/************************************************************************/ /* */ /* ***** ***** */ /* ***** ***** */ /* ***** ***** */ /* ***** ***** */ /* *************** *************** */ /* ***************** ***************** */ /* *************** *************** */ /* ***** ***** TheNetNode */ /* ***** ***** Portable */ /* ***** ***** Network */ /* ***** ***** Software */ /* */ /* File src/l7utils.c (maintained by: ???) */ /* */ /* This file is part of "TheNetNode" - Software Package */ /* */ /* Copyright (C) 1998 - 2008 NORD>downca); if (index != -1) { np = netp->nodetab+index; putalt(np->alias, mbp); } } putid(calofs(uplink, uid), mbp); } else { putalt(alias, mbp); putid(myid, mbp); } putchr('\r', mbp); if (msg != conmsg) prompt(mbp); seteom(mbp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void puttfu(const char *name) { MBHEAD *mbp; #ifdef SPEECH putstr(speech_message(279), (mbp = putals(name))); #else putstr(" table full\r", (mbp = putals(name))); #endif prompt(mbp); seteom(mbp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putmsg(const char *string) { MBHEAD *mbp; mbp = putals(string); if (userpo->convflag == 0) prompt(mbp); seteom(mbp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ MBHEAD *putals(const char *string) { MBHEAD *mbp; mbp = getmbp(); putalt(alias, mbp); putid(myid, mbp); putstr("> ", mbp); putstr(string, mbp); return(mbp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ MBHEAD *getmbp(void) { MBHEAD *mbp; mbp = (MBHEAD *) allocb(ALLOC_MBHEAD); mbp->l2link = g_ulink(userpo->uid); mbp->type = g_utyp(userpo->uid); return(mbp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putuse(LINKTYP seite, UID uid, MBHEAD *mbp) { CIRBLK *cp; LNKBLK *lp; HOSTUS *hp; #ifdef L1TCPIP TCPIP *tc; #endif /* L1TCPIP */ #ifndef USER_AUSGABE int index; NODE *np; #endif /* USER_AUSGABE */ if (seite == CQ_LINK) { putstr("CQ(", mbp); switch (g_utyp(uid)) { case L4_USER: putid(((CIRBLK *)g_ulink(uid))->upcall, mbp); break; case L2_USER: putid(((LNKBLK *)g_ulink(uid))->dstid, mbp); break; #ifdef L1TCPIP case TCP_USER: putid(((TCPIP *)g_ulink(uid))->Upcall, mbp); break; #endif /* L1TCPIP */ default: putid(((HOSTUS *)g_ulink(uid))->call, mbp); break; } putstr(")\r", mbp); return; } switch (g_utyp(uid)) { case L4_USER: cp = g_ulink(uid); #ifdef USER_AUSGABE if (seite == UPLINK) { putstr("Uplink(", mbp); putid(cp->upcall, mbp); putchr(')', mbp); putspa(18,mbp); putstr("N: ",mbp); putid(cp->downca, mbp); } else { putstr("(", mbp); putid(cp->upcall, mbp); putspa(52,mbp); putstr(" <> ", mbp); putid(cp->downca, mbp); putchr(')', mbp); putspa(65,mbp); } #else /* USER_AUSGABE */ putstr("Circuit(", mbp); index = find_node_this_ssid(cp->downca); if (index != -1) { np = netp->nodetab+index; putalt(np->alias, mbp); } putid(cp->downca, mbp); putchr(' ', mbp); putid(cp->upcall, mbp); putchr(')', mbp); #endif /* USER_AUSGABE */ break; case L2_USER: lp = g_ulink(uid); #ifdef USER_AUSGABE if (seite == UPLINK) { putstr("Uplink(", mbp); putid(lp->dstid, mbp); putchr(')', mbp); putspa(18,mbp); putprintf(mbp,"P%-2u ",lp->liport); putprintf(mbp,"%-10s ",portpar[lp->liport].name); } else { putspa(40,mbp); putstr("(", mbp); putid(lp->srcid, mbp); putspa(52,mbp); putstr(" <> ", mbp); putid(lp->dstid, mbp); putchr(')', mbp); putspa(65,mbp); putprintf(mbp,"P%-2u ",lp->liport); putprintf(mbp,"%-10s",portpar[lp->liport].name); #else /* USER_AUSGABE */ if (seite == UPLINK) { putstr("Uplink(", mbp); putid(lp->dstid, mbp); putchr(')', mbp); } else { putstr("Downlink(", mbp); putid(lp->srcid, mbp); putchr(' ', mbp); putid(lp->dstid, mbp); putchr(')', mbp); #endif /* USER_AUSGABE */ } break; #ifdef L1TCPIP case TCP_USER: tc = g_ulink(uid); if (seite == UPLINK) { putstr("Uplink(", mbp); putid(tc->Upcall, mbp); putchr(')', mbp); putspa(18,mbp); putprintf(mbp,"P%-2u ",tc->port); putprintf(mbp,"%-15s ",tc->ip); } else { putspa(40,mbp); putstr("(", mbp); putprintf(mbp,"%s",tc->ip); putchr(')', mbp); putspa(65,mbp); putprintf(mbp,"P%-2u ",tc->port); putprintf(mbp,"%-10s",portpar[tc->port].name); } break; #endif /* L1TCPIP */ default: hp = g_ulink(uid); putstr("Host(", mbp); if (cmpid(hostid, myid)) { putalt(alias, mbp); putid(myid, mbp); } else { if (seite == UPLINK) putid(hp->call, mbp); else { putid(hp->call, mbp); putchr(' ', mbp); putid(hostid, mbp); } } putchr(')', mbp); break; } } static BOOLEAN issecret(WORD channel) { CHANNEL *ch; for (ch = channels; ch; ch = ch->next) if (ch->chan == channel) break; if (ch->flags & (M_CHAN_S|M_CHAN_I)) return(TRUE); return(FALSE); } /************************************************************************/ /* putcvsu */ /* Da die Verbindungen des Conversmodus so verdreht aufgebaut werden, */ /* hier nun eine entsprechend verdrehte Ausgaberoutine DL1XAO */ /*----------------------------------------------------------------------*/ void putcvsu(USRBLK *u, MBHEAD *mbp) { UID uid = u->uid; CONNECTION *cp = u->convers; if (u->convflag == 2) { /* ausgehender Convershost */ #ifdef USER_AUSGABE putstr("Uplink", mbp); putstr("(", mbp); putid(myid, mbp); putchr(')', mbp); putspa(18,mbp); putstr("Convers", mbp); #else putstr("Convers(", mbp); putid(myid, mbp); /* SSID egal? ja! */ putchr(')', mbp); #endif /* USER_AUSGABE */ if (cp->type == CT_HOST) putstr(" Host", mbp); putspa(38, mbp); putstr(u->status == US_CHST ? "<..> " /* im Aufbau? */ : "<--> ", mbp); putuse(DOWNLINK, uid, mbp); viaput(DOWNLINK, uid, mbp); } else { /* User und eingehende CVSHOST */ putuse(UPLINK, uid, mbp); putspa(38, mbp); #ifdef USER_AUSGABE putstr("<--> (", mbp); putid(calofs(UPLINK, uid), mbp); putspa(53,mbp); putstr("<> Convers)", mbp); #else putstr("<--> Convers(", mbp); putid(calofs(UPLINK, uid), mbp); putchr(')', mbp); #endif /* USER_AUSGABE */ if ( cp->type == CT_USER && (issecret(cp->channel) == FALSE || userpo->sysflg)) { #ifdef USER_AUSGABE putspa(65,mbp); #endif /*USER_AUSGABE */ #ifndef L1IRC putstr("Ch", mbp); putlong((LONG)cp->channel, 0, mbp); #else if (cp->channel == EOF) putstr("IRC", mbp); else { putstr("Ch", mbp); putlong((LONG)cp->channel, 0, mbp); } #endif /* L1IRC */ } if (cp->type == CT_HOST) putstr(" Host", mbp); viaput(UPLINK, uid, mbp); } } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putdil(const char *liste, MBHEAD *mbp) { BOOLEAN mark = TRUE; if (*liste) { putstr(" via", mbp); while (*liste) { putchr(' ', mbp); putid(liste, mbp); if (mark) if ((liste[L2IDLEN - 1] & L2CH) != 0) if (!liste[L2IDLEN] || !(liste[L2ILEN - 1] & L2CH)) { putchr('*', mbp); mark = FALSE; } liste += L2IDLEN; } } } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putid(const char *call, MBHEAD *mbp) { char ssid; char c; WORD i; for (i = 0; i < L2IDLEN-1; ++i) { c = *call++; if (c > ' ') putchr(c, mbp); else { if (c < ' ') { putchr('^', mbp); #ifdef __WIN32__ putchr((char)(c + '@'), mbp); #else putchr((c + '@'), mbp); #endif /* WIN32 */ } } } ssid = (*call >> 1) & 0x0f; if (ssid != 0) { putchr('-', mbp); putnum(ssid, mbp); } } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putalt(char *ident, MBHEAD *mbp) { if (*ident != ' ') { putcal(ident, mbp); putchr(':', mbp); } } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putcal(char *call, MBHEAD *mbp) { char *cp; WORD i; for (i = 0, cp = call; i < L2CALEN; ++cp, ++i) { if (*cp == ' ') break; putchr(*cp, mbp); } } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void puttim(time_t *time, MBHEAD *mbp) { struct tm *p; p = localtime(time); putprintf(mbp,"%02d.%02d.%02d %02d:%02d:%02d", p->tm_mday, p->tm_mon+1, p->tm_year % 100, p->tm_hour, p->tm_min, p->tm_sec); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putnum(int zahl, MBHEAD *mbp) { char buf[10]; sprintf(buf, "%d", zahl); putstr(buf, mbp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putlong(ULONG zahl, BOOLEAN justify, MBHEAD *mbp) { char buf[20]; sprintf(buf,justify ? " %10lu" : " %lu",zahl); putstr(buf, mbp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putstr(const char *string, MBHEAD *mbp) { while (*string) putchr(*string++, mbp); } /**************************************************************************/ /* printf fuer mbp-Fuellen DL1XAO */ /*------------------------------------------------------------------------*/ #define VSPRINTFBUFFER 256 void putprintf(MBHEAD *mbp, const char *format, ...) { va_list arg_ptr; char str[VSPRINTFBUFFER]; int n = 0; va_start(arg_ptr, format); n = vsnprintf(str, VSPRINTFBUFFER, format, arg_ptr); va_end(arg_ptr); if (n > -1 && n < VSPRINTFBUFFER) putstr(str, mbp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ void putspa(WORD stop, MBHEAD *mbp) { WORD i; i = mbp->l4time + stop - mbp->mbpc; while (i-- > 0) putchr(' ', mbp); } /**************************************************************************/ /* VIA-Pfad extrahieren und pruefen */ /* */ /* YES = Check ohne Fehler */ /* NO = Check mit Fehler, Pfad zu kurz */ /* ERRORS = Check mit Fehler, Calls konnten nicht extrahiert werden */ /*------------------------------------------------------------------------*/ TRILLIAN getdig(WORD *laenge, char **inbuf, BOOLEAN pflag, char *outbuf) { char *lispoi; WORD i; char *p; WORD n; *outbuf = NUL; skipsp(laenge, inbuf); /* Laengenpruefung */ if ((n = *laenge) < 4) return (NO); /* zu kurz */ p = *inbuf; /* optionales "VIA" im Pfad ueberspringen */ if (!strnicmp((char*)p, "VIA", 3)) { p += 3; n -= 3; } skipsp(&n, &p); /* solange wir gueltige Calls finden */ for (i = 0, lispoi = outbuf; n > 0 && i < L2VNUM; ++i, lispoi += L2IDLEN) if (getcal(&n, &p, pflag, lispoi) != YES) break; *lispoi = NUL; /* mindestens ein gueltiges Call gefunden */ if (i > 0) { *laenge = n; *inbuf = p; return(YES); } return(ERRORS); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ TRILLIAN getcal(WORD *laenge, char **inbuf, BOOLEAN pflag, char *outbuf) { char call[L2IDLEN]; char binsid = 0; char *bufpoi; char zeichen; WORD i; char *p = *inbuf; WORD n = *laenge; cpyid(call,nullid); skipsp(&n, &p); bufpoi = call; i = 0; while (n > 0) { if (((zeichen = (char) toupper(*p)) == ' ' ) || (zeichen == ',')) break; if (zeichen < ' ') return(ERRORS); if (zeichen == '-') { if (n <= 0) return(ERRORS); ++p; --n; if (n <= 0) return(ERRORS); zeichen = *p; if ((zeichen < '0') || (zeichen > '9')) return(ERRORS); ++p; --n; binsid = (zeichen - '0'); if (n > 0) { zeichen = *p; if ((zeichen >= '0') && (zeichen <= '9')) { binsid *= 10; binsid += (zeichen - '0'); if (binsid > 15) return(ERRORS); ++p; --n; } } call[L2IDLEN-1] = (binsid << 1) | 0x60; break; } else { if (i++ == L2IDLEN-1) return(ERRORS); *bufpoi++ = zeichen; ++p; --n; } } while (n > 0) { zeichen = *p; if ((zeichen != ' ') && (zeichen != ',')) break; ++p; --n; if (zeichen == ',') break; } /* haben wir nur eine SID bekommen, dann ergaenzen wir mit unserem Call */ if ((call[0] == ' ') && (binsid <= 15) && (binsid > 0)) { cpyid(call, myid); call[L2IDLEN-1] = (binsid << 1) | 0x60; i = 1; } if (i == 0) return(NO); if (pflag && (fvalca(call) == ERRORS)) return(ERRORS); cpyid(outbuf, call); *laenge = n; *inbuf = p; return(YES); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ BOOLEAN getport(WORD *laenge, char **inbuf, WORD *port) { WORD i; WORD tmp_port; char *save_inbuf = *inbuf; WORD save_laenge = *laenge; char pn[12]; char *inbp; char ch; skipsp(laenge, (char **) inbuf); if (*laenge <= 0) return(FALSE); inbp = *inbuf; for (i = 0; i < min(*laenge, 11); i++) { ch = *inbp++; if (ch == ' ') break; pn[i] = ch; } pn[i] = NUL; for (i = 0; i < L2PNUM; i++) { /* erst Portnamen vergleichen */ if (stricmp(portpar[i].name, pn) == 0) { nextspace(laenge, inbuf); return(portenabled(*port = i)); } } if (isdigit(**inbuf)) { /* sonst Portnummer pruefen */ tmp_port = nxtnum(laenge, inbuf); if ( (tmp_port >= 0) && (tmp_port < L2PNUM)) { /* Port gueltig? */ return(portenabled(*port = tmp_port)); } } *inbuf = save_inbuf; /* Position restaurieren */ *laenge = save_laenge; return(FALSE); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ TRILLIAN getide(WORD *laenge, char *(*inbuf), char *outbuf) { char ident[L2CALEN]; char c; WORD i; WORD n = *laenge; char *p = *inbuf; memcpy(ident, nulide, L2CALEN); for (i = 0; (i < L2CALEN) && (n > 0); ++i) { --n; c = *p++; if (c != ' ') { if (c != '*') { ident[i] = c; continue; } if (i != 0 || c != '*') return(ERRORS); } break; } if ((i == L2CALEN) && (n > 0) && (*p != ' ')) return(ERRORS); if (valcal(ident) == YES) return(ERRORS); memcpy(outbuf, ident, L2CALEN); if (ident[0] != ' ') /* Ident korrekt gelesen */ { *laenge = n; *inbuf = p; return(YES); } return(NO); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ UWORD nxtnum(WORD *laenge, char **buffer) { UWORD temp; skipsp(laenge, buffer); temp = 0; while (*laenge > 0 && **buffer >= '0' && **buffer <= '9') { --*laenge; temp *= 10; temp += (*(*buffer)++ - '0'); } return(temp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ LONG nxtlong(WORD *laenge, char **buffer) { LONG temp; skipsp(laenge, buffer); temp = 0; while (*laenge > 0 && **buffer >= '0' && **buffer <= '9') { --*laenge; temp *= 10; temp += (*(*buffer)++ - '0'); } return(temp); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ TRILLIAN fvalca(char *call) { if (*call == ' ' ) return(NO); return(valcal(call)); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ TRILLIAN valcal(char *call) { char *numpos = 0; char *actual; char zeichen; WORD zahl = 0; WORD i = 0; for (actual = call; i < L2IDLEN-1; ++i, ++actual) { if ((zeichen = *actual) == ' ') break; if (!((zeichen >= 'A') && (zeichen <= 'Z'))) { if ((zeichen >= '0') && (zeichen <= '9')) { zahl += 1; numpos = actual; } else return(ERRORS); } } #ifndef CALLCHECK if ( ((actual - call) < 4) || zahl == 0 || zahl > 2 || (numpos == call) || (numpos == (actual - 1)) || ((numpos - call) >= 3)) return(ERRORS); #else /* Hat Rufzeichen weniger als 4 Zeichen, */ if (i < 4) /* ist es ungueltig. */ return(ERRORS); #endif /* CALLCHECK */ return(YES); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ BOOLEAN ismemr(void) { if (nmbfre < 300 && !userpo->sysflg) return(FALSE); return(TRUE); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ char *calofs(LINKTYP uplink, UID uid) { void *link; if (uid == NO_UID) return(myid); link = g_ulink(uid); switch (g_utyp(uid)) { case L2_USER : return(((LNKBLK *)link)->dstid); case L4_USER : return( ((uplink == UPLINK) || (uplink == CQ_LINK)) ? ((CIRBLK *)link)->upcall : ((CIRBLK *)link)->downca); #ifdef L1TCPIP case TCP_USER : return(((TCPIP *)link)->Upcall); #endif /* L1TCPIP */ } if (tnnb_aktiv) return(myid); if (uplink == DOWNLINK) return(hostid); return(hstusr->call); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ BOOLEAN getlin(MBHEAD *mbp) { char huge *nextch; WORD getcou; WORD found; WORD laenge; WORD mlaenge = 81; if (userpo->status == US_WBIN || userpo->status == US_RBIN) return(TRUE); if (userpo->convers) { if (userpo->convers->type == CT_UNKNOWN) return(TRUE); mlaenge = 2047; } nextch = mbp->mbbp; getcou = mbp->mbgc; found = FALSE; laenge = 0; while (mbp->mbgc < mbp->mbpc) { if ( ((getchr(mbp)) == CR) || (++laenge == mlaenge)) { found = TRUE; break; } } mbp->mbbp = nextch; mbp->mbgc = getcou; return(found); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ BOOLEAN issyso(void) { return(userpo->sysflg != 0); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ BOOLEAN skipsp(WORD *cnt, char **cpp) { while ((*cnt > 0) && **cpp == ' ') { ++*cpp; --*cnt; } return((*cnt > 0) ? TRUE : FALSE); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ WORD getparam(WORD *cnt, char **cpp, WORD min, WORD max, WORD def) { int par; if ((*cnt) > 1) { (*cpp)++; (*cnt)--; if (toupper(*(*cpp)) == 'O') { /* BOOLEAN */ if (toupper((*cpp)[1]) == 'N') par = 1; else par = 0; nextspace(cnt, cpp); return(par); } par = (nxtnum(cnt, cpp)); if (par > max) par = max; if (par < min) par = min; return(par); } return(def); } /**************************************************************************/ /* */ /*------------------------------------------------------------------------*/ BOOLEAN nextspace(WORD *cnt, char **cpp) { while ((*cnt > 0) && **cpp != ' ') { ++*cpp; --*cnt; } return((*cnt > 0) ? TRUE : FALSE); } /* Ermittelt das Filedatum von AKTUELL.TXT und stellt es zur Verfuegung */ static char *aktuell(void) { char file[128]; struct ffblk fb; static char akt[10] = "?"; #ifdef MC68302 struct tm *ftime; #endif strcpy(file, textcmdpath); #ifdef MC68302 strcat(file, "aktuell.txc"); #else strcat(file, "aktuell.txt"); #endif if (xfindfirst(file, &fb, 0) == 0) { #ifdef MC68302 ftime = localtime(&fb.ff_ftime); sprintf(akt, "%02d.%02d.%02d", ftime->tm_mday, (ftime->tm_mon)+1, (ftime->tm_year)%100); #else sprintf(akt,"%02d.%02d.%02d", fb.ff_fdate & 0x1f, (fb.ff_fdate >> 5) & 0xf, ((fb.ff_fdate >> 9) + 80) % 100); #endif } return(akt); } /*------------------------------------------------------------------------*/ /* Prompt generieren und an Message-Buffer anhaengen */ /*------------------------------------------------------------------------*/ /* Prompt aufbauen, im Convers-Modus gibt es keinen Prompt, sondern */ /* stattdessen einen String '***\r', der das Ende der Ausgabe des */ /* Digis anzeigt. */ void prompt(MBHEAD *mbp) { if (userpo->convers == NULLCONNECTION) prompt2str(mbp, promptstr); else putstr("***\r", mbp); } /* String nach '%' durchsucht und gegebenenfalls ergaenzt. */ /* '%a' wird durch den Digipeater-Ident ersetzt, */ /* '%A' wird durch das Datum des aktuell.txt ersetzt, */ /* '%c' durch das Call des Users, */ /* '%C' durch das User-Call mit SSID, */ /* '%d' durch das Call des Digipeaters, */ /* '%D' durch das Call des Digipeaters mit SSID, */ /* '%f' durch den Inhalt der angegebenen Datei */ /* '%l' durch die Anzahl aktiver L2-Links */ /* '%p' durch die Portnummer */ /* '%P' durch den Pseudo-Name des Ports */ /* '%r' durch Carriage-Return */ /* '%s' durch Datum */ /* '%t' durch die aktuelle Uhrzeit (HH:MM). */ /* '%u' durch die Anzahl der User auf dem aktuellen Port */ /* '%%' durch % */ /* '%0' unterdrueckt die Aussendung eines Prompts. */ void prompt2str(MBHEAD *mbp, char *str) { char *cp; char buf[128]; struct tm *lt; LNKBLK *link; /* L2-Link des Users */ FILE *fp; char *c; char filename[128]; #ifdef MAKRO_USER UWORD user_anzahl = 0; /* die echte Useranzahl im Knoten */ UWORD interlinks = 0; /* alle Interlinks im knoten */ UWORD _nmblks = 0; /* Sicherungskopie fuer das echte nmblks */ #endif #ifdef L1TCPIP TCPIP *tpoi; #endif /* L1TCPIP */ while (*str) { for (cp = str; *cp && *cp != '%'; ++cp) ; if (*cp == '%') { *cp = NUL; putstr(str, mbp); *cp++ = '%'; switch (*cp) { case 'a': putalt(alias, mbp); break; case 'A': putstr(aktuell(), mbp); break; case 'c': putcal(calofs(UPLINK, userpo->uid), mbp); break; case 'C': putid(calofs(UPLINK, userpo->uid), mbp); break; case 'd': putcal(myid, mbp); break; case 'D': putid(myid, mbp); break; case 'f': cp++; strcpy(filename, cp); /* Dateiname extrahieren */ if ((c = strchr(filename, ' ')) != NULL) *c = '\0'; if ((fp = xfopen(filename, "rt")) != NULL) { while (fgets(buf, 126, fp) != NULL) { if ((c = strchr(buf, '\n')) != NULL) *c = CR; putprintf(mbp, buf); } fclose(fp); cp += strlen(filename) - 1; /* Ein Zeichen vor dem Ende */ if (*(cp + 1) == ' ') cp++; /* Sonst Probs bei Text am Strinende */ } break; case 'l': putprintf(mbp, "%01u", nmblks); /* Anzahl L2-Links */ break; case 'p': /* Portnummer */ switch(g_utyp(userpo->uid)) { case L2_USER : link = g_ulink(userpo->uid); /* Userlink ermitteln */ putprintf(mbp, "%u", link->liport); /* -> Portnummer */ break; #ifdef L1TCPIP case TCP_USER : tpoi = g_ulink(userpo->uid); /* Userlink ermitteln */ putprintf(mbp, "%u", tpoi->port); /* -> Portnummer */ break; #endif /* L1TCPIP */ default : /* Host-Console */ putstr("C", mbp); /* -> "C" */ break; } break; case 'P': /* Portname */ switch(g_utyp(userpo->uid)) { case L2_USER : link = g_ulink(userpo->uid); /* Userlink ermitteln */ /* Portname ausgeben, wenn User nicht von Console kommt */ putprintf(mbp, "%s", portpar[link->liport].name); break; #ifdef L1TCPIP case TCP_USER : tpoi = g_ulink(userpo->uid); /* Userlink ermitteln */ /* Portname ausgeben, wenn User nicht von Console kommt */ putprintf(mbp, "%s", portpar[tpoi->port].name); break; #endif /* L1TCPIP */ default : /* Host-Console */ putstr("Console", mbp); /* -> "Console" */ break; } break; case 'r': putchr(CR, mbp); break; case 's': lt = localtime(&sys_time); putprintf(mbp, "%02u.%02u.%02u", lt->tm_mday, lt->tm_mon+1, lt->tm_year%100); break; case 't': sprintf(buf,"%16.16s",ctime(&sys_time)); putstr(&buf[11], mbp); break; #ifdef MAKRO_USER case 'u': interlinks = Interlinks_zaehlen(); /* wir zaehlen erstmal alle Interlinks im Knoten */ _nmblks = nmblks; /* Sicherungskopie vom Original nmblks */ putprintf(mbp, "%u", user_anzahl = (_nmblks - interlinks) + nmbcir #ifdef L1TCPIP + nmbtcp #endif /* L1TCPIP */ ); /* L2-Links - Interlinks + L4-User = echte Useranzahl */ break; #else case 'u': /* Useranzahl auf aktuellem L2-Port */ if (mbp->type == L2_USER) { lnk = g_ulink(userpo->uid); /* Userlink ermitteln */ /* Anzahl ausgeben, wenn User nicht von Console kommt */ putprintf(mbp, "%u", portpar[lnk->liport].nmbstn); } else /* fuer Host-Console und L4 nicht */ putstr("N/A", mbp); /* verfuegbar */ break; #endif #ifdef MAKRO_NOLOGINSTR case 'v': putprintf(mbp,"%s",loginstr); #endif case '0': break; case '%': putchr('%', mbp); break; } str = ++cp; } else { putstr(str, mbp); str = cp; } } } /************************************************************************/ /* */ /*----------------------------------------------------------------------*/ void putide(char *ID, MBHEAD *mbp) { int i; for (i = 5; (i >= 0) && (ID[i] == ' '); i--) putchr(' ', mbp); for (i = 0; (i < L2CALEN) && (ID[i] != ' '); i++) putchr(ID[i],mbp); } /************************************************************************/ /* */ /*----------------------------------------------------------------------*/ void invmsg(void) { #ifdef SPEECH putmsg(speech_message(277)); #else putmsg("Invalid command. Try HELP.\r"); #endif } /************************************************************************/ /* Beacons */ /*----------------------------------------------------------------------*/ void dump_beacn(MBHEAD *mbp) { BEACON *beapoi; int port; putstr(";\r; Stat/Text-Broadcast\r;\r", mbp); for (port = 0, beapoi = beacon; port < L2PNUM; ++port, ++beapoi) { if (*beapoi->text) putprintf(mbp, "BEACON %d = %s\r", port, beapoi->text); putprintf(mbp, "BEACON %d %d %d ", port, beapoi->interval, beapoi->telemetrie); putid(beapoi->beades, mbp); putdil(beapoi->beadil, mbp); putchr('\r', mbp); } } /************************************************************************/ /* Convers-Links */ /*----------------------------------------------------------------------*/ void dump_convc(MBHEAD *mbp) { int pl; char *c; PERMLINK *p; putstr(";\r; Convers Interlinks\r;\r", mbp); #ifdef CONVERS_HOSTNAME putprintf(mbp,"CONV HOSTNAME %s\r",myhostname); #endif for (pl = 0; pl < MAXCVSHOST; pl++) { p = permarray[pl]; if (p ) { putstr("CONV C ", mbp); #ifdef L1IPCONV putprintf(mbp,"%s ", p->cname); if (p->TcpLink) putprintf(mbp,"%s ", p->HostName); else #endif /* L1IPCONV */ putid(p->call, mbp); if (p->port != 255) { putchr(' ', mbp); putnum(p->port, mbp); if (*(c = p->via)) { while (*c) { putchr(' ', mbp); putid(c, mbp); c += L2IDLEN; } } } putchr('\r', mbp); } } } /************************************************************************/ /* Links */ /*----------------------------------------------------------------------*/ void dump_links(MBHEAD *mbp) { char *c; L2LINK *p; PEER *pp; int i; int max_peers = netp->max_peers; #ifdef ALIASSAVEMOD char alias[L2IDLEN]; #endif /* ALIASSAVEMOD */ putstr(";\r; Links\r;\r", mbp); for (i = 0, pp = netp->peertab; i < max_peers; i++, pp++) if (pp->used) { p = pp->l2link; if (p->port != L2PNUM) /* Sonderbehandlung Hostmode-Link */ { #ifdef AUTOROUTING /* Link ist eine Auto-Route, */ if (p->ppAuto == AUTO_ROUTE) /* zum naechsten Eintrag. */ continue; #endif /* AUTOROUTING */ putstr("LINK + ", mbp); putprintf(mbp, "%2.2s ",typtbl + pp->soll_typ * 2); #ifdef PROXYFUNC if (pp->proxy == TRUE) putstr("P ", mbp); #endif /* PROXYFUNC */ putnum(p->port, mbp); putchr(' ', mbp); #ifdef ALIASSAVEMOD /* Ist der Alias komplett in Grossbuchstaben, wird der Linkeintrag */ /* beim naechsten mal NICHT eingelesen!!! Darum muessen wir den */ /* in kleinbuchstaben umwandeln. */ cpyid(alias, p->alias); /* Ein Alias kann max. 6 Zeichen haben. */ alias[L2CALEN] = 0; /* Alias in kleinbuchstaben umwandeln und in den Buffer schreiben. */ putcal(strlwr(alias), mbp); #else putcal(p->alias, mbp); #endif /* ALIASSAVEMOD */ putchr(' ', mbp); putid (p->call, mbp); putchr(' ', mbp); if (*(c = p->digil )) { while (*c) { putchr(' ', mbp); putid(c, mbp); c += L2IDLEN; } } #ifdef LINKSMODINFO putchr(' ', mbp); putstr("INFO=",mbp); putprintf(mbp,"%s",p->info, mbp); #endif /* LINKSMODINFO */ } else { putstr("ESC I ", mbp); putid(p->call, mbp); putchr(' ', mbp); putcal(p->alias, mbp); #ifdef PROXYFUNC if (pp->proxy == TRUE) putstr(" P", mbp); #endif } putchr('\r',mbp); } } /************************************************************************/ /* Parameter */ /*----------------------------------------------------------------------*/ void dump_parms(MBHEAD *mbp) { UWORD num; PARAM *p; putstr(";\r; Parameters\r;\r", mbp); for (p = partab, num = 1; num <= partablen; p++, num++) if (p->paradr && strncmp(p->parstr, "unu", 3)) putprintf(mbp, "PAR %s %u\r", p->parstr, *(p->paradr)); } /************************************************************************/ /* Ports */ /*----------------------------------------------------------------------*/ void dump_ports(MBHEAD *mbp) { int port; PORTINFO *pp; L1MODETAB *mtp; char mode[16], *cp; putstr(";\r; Port Configuration (Level 1)\r;\r", mbp); for (port = 0, pp = portpar; port < L2PNUM; port++, pp++) { putprintf(mbp, "PORT %d NAME=%s ", port, pp->name); l1hwcfg(port, mbp); cp = mode; for (mtp = l1modetab; mtp->ch; mtp++) if (pp->l1mode & mtp->mode) *cp++ = mtp->ch; *cp = NUL; putprintf(mbp, " MODE=%u00%s TXD=%u MAX=%u%s ", pp->speed, mode, pp->txdelay, pp->maxframe, automaxframe(port) ? "a" : ""); #ifdef SETTAILTIME putprintf(mbp, "TAIL=%u ", pp->tailtime); #endif #ifdef DAMASLAVE if (pp->l2mode & MODE_ds) strcpy(mode, "s"); else #endif sprintf(mode, "%2u", pp->l2mode & MODE_a ? pp->dch + 1 : 0); putprintf(mbp, "DAMA=%s CTEXT=%u SYSOP=%u MH=%u", mode, pp->l2mode & MODE_x ? 1 : 0, pp->l2mode & MODE_s ? 1 : 0, pp->l2mode & MODE_h ? 1 : 0); #ifdef USERMAXCON putprintf(mbp, " MAXCON=%u", pp->maxcon); #endif #ifdef EAX25 putprintf(mbp, " EAXMAXF=%u EAXMODE=%u", pp->maxframe_eax, pp->eax_behaviour); #endif #ifdef EXPERTPARAMETER putprintf(mbp, " PERS=%u%c SLOT=%u%c IRTT=%u%c T2=%u%c RETRY=%u%c", pp->persistance, (pp->l2autoparam & MODE_apers) ? 'a' : ' ', pp->slottime, (pp->l2autoparam & MODE_aslot) ? 'a' : ' ', pp->IRTT, (pp->l2autoparam & MODE_aIRTT) ? 'a' : ' ', pp->T2, (pp->l2autoparam & MODE_aT2) ? 'a' : ' ', pp->retry, (pp->l2autoparam & MODE_aretry) ? 'a' : ' '); #endif #ifdef PORT_MANUELL putprintf(mbp, "\rPORT %d", port); putprintf(mbp, " PACLEN=%u", pp->paclen); putprintf(mbp, " T3=%u", pp->T3); #endif /* PORT_MANUELL */ #ifdef IPOLL_FRAME putprintf(mbp, " IPACLEN=%u IRETRY=%u", pp->ipoll_paclen,pp->ipoll_retry); #endif /* IPOLL_FRAME */ #ifdef PORT_L2_CONNECT_TIME putprintf(mbp, " L2TIME=%u", pp->l2_connect_time); #endif #ifdef PORT_L2_CONNECT_RETRY putprintf(mbp, " L2RETRY=%u", pp->l2_connect_retry); #endif #ifdef AUTOROUTING /* Fixed/Auto-Route eintragen. */ putprintf(mbp, " L4AUTO=%u", pp->poAuto); #endif /* AUTOROUTING */ putchr('\r', mbp); } } /************************************************************************/ /* SUSPEND */ /*----------------------------------------------------------------------*/ void dump_suspd(MBHEAD *mbp) { SUSPEND *suspoi; int i; putstr(";\r; Suspended Users\r;\r", mbp); for (suspoi = sustab, i = 0; i < MAXSUSPEND; suspoi++, i++) if (suspoi->call[0]) { putprintf(mbp, "SUSPEND + %d ", suspoi->port); putcal(suspoi->call, mbp); if (suspoi->port == 255) { putchr(' ', mbp); putnum(suspoi->okcount, mbp); } putchr('\r', mbp); } } /************************************************************************/ /* ip */ /*----------------------------------------------------------------------*/ #ifdef IPROUTE void dump_ipr(MBHEAD *mbp) { IP_ROUTE *ipr; ARP_TAB *arp; const char *dgmode_tab[] = {"", "DG", "VC"}; putstr(";\r;IP-Config\r;\rIPA ", mbp); show_ip_addr(my_ip_addr, mbp); /* My IP-Adress */ putprintf(mbp, "/%d\r", my_ip_bits); for (ipr = (IP_ROUTE *)IP_Routes.head; /* IP-Routen */ ipr != (IP_ROUTE *)&IP_Routes; ipr = (IP_ROUTE *)ipr->nextip) { putstr("IPR ", mbp); show_ip_addr(ipr->dest, mbp); /* Adresse anzeigen */ putprintf(mbp, "/%d + %s", ipr->bits, /* Bitmaske zeigen */ ipr->flags & RTDYNAMIC ? "D " : " "); switch (ipr->port) { case NETROM_PORT: putstr("NET/ROM ", mbp); break; #ifdef KERNELIF case KERNEL_PORT: putstr("KERNEL ", mbp); break; #endif default : putprintf(mbp, "%s ", portpar[ipr->port].name); } if (ipr->gateway != 0) show_ip_addr(ipr->gateway, mbp); /* Gateway */ putchr(' ', mbp); if (ipr->metric != 0) /* if metric set, */ putnum(ipr->metric, mbp); /* show metric */ putchr('\r', mbp); } for (arp = (ARP_TAB *)Arp_tab.head; /* ARP */ arp != (ARP_TAB *)&Arp_tab; arp = (ARP_TAB *)arp->nextar) { if (arp->timer == 0) { /* nur feste Eintraege */ putstr("ARP ", mbp); show_ip_addr(arp->dest, mbp); putprintf(mbp, " + %c ", arp->publish_flag ? 'P' : ' '); switch (arp->port) { case NETROM_PORT: putstr("NET/ROM ", mbp); break; #ifdef KERNELIF case KERNEL_PORT: putstr("KERNEL ", mbp); break; #endif default : putprintf(mbp, "%s ", portpar[arp->port].name); } putprintf(mbp, "%s ", dgmode_tab[(int)arp->dgmode]); putid(arp->callsign, mbp); putchr(' ', mbp ); putdil(arp->digi, mbp); putchr('\r', mbp ); } } } #endif #ifdef ALIASCMD /************************************************************************/ /* print aliasses */ /*----------------------------------------------------------------------*/ void dump_alias(MBHEAD *mbp) { CMDALIAS *ap; putstr(";\r; Commando-Aliasses\r;\r", mbp); for (ap = aliaslist; ap != NULL; ap = ap->next) putprintf(mbp, "ALIAS %s %s\r", ap->alias, ap->cmd); } #endif /************************************************************************/ /* Versch. noch eintragen */ /*----------------------------------------------------------------------*/ void dump_divrs(MBHEAD *mbp) { #ifdef PACSAT WORD x; /* PACSAT-BROADCAST */ putstr(";\r; Pacsat Broadcast\r;\r", mbp); for (x = 0; x < L2PNUM; x++) { if (pacsat_enabled[x]) { putprintf(mbp, "PACSAT + %u\r", x); } } putstr("PACSAT C ", mbp); if (!cmpid(pacsatid, nullid)) putid(pacsatid,mbp); else putchr('-', mbp); putprintf(mbp, "\rPACSAT P 1 %u\r",pacsat_timer); putprintf(mbp, "PACSAT P 2 %u\r",pacsat_frames); putprintf(mbp, "PACSAT P 3 %u\r",pacsat_free); #endif /* versch. */ putstr(";\r; Mailbox and Cluster\r;", mbp); if (boxid[0]) { putstr("\rMAILBOX ", mbp); putid(boxid, mbp); } if (dxcid[0]) { putstr("\rDXCLUSTER ", mbp); putid(dxcid, mbp); } #ifdef HOSTMYCALL if (hostuserid[0]) { putstr("\rMYHOST ", mbp); putid(hostuserid, mbp); } #endif /* HOSTMYCALL */ #ifdef SYSOPPASSWD if (paswrd[0]) { putstr("\rSYSPASS ", mbp); putprintf(mbp,"%s",paswrd); } #endif /* SYSOPPASSWD */ putstr("\r;\r; MHeard, Prompt\r;\r", mbp); putprintf(mbp, "MH = %d\r", l2heard.max); putprintf(mbp, "L3MH = %d\r", l3heard.max); putprintf(mbp, "PROMPT =%s\r", promptstr); #ifndef __LINUX__ /* steht bei Linux in tnn.ini */ if (tkcom > -1) { /* Tokenring-Speed */ putstr(";\r; Tokenspeed\r;\r", mbp); putprintf(mbp, "#T %u00",tkbaud); } #endif } void save_parms(void) { MBHEAD *mbp; FILE *fp; UBYTE ch; char call[20]; #ifdef SAVEPARAMFIX char konfigfile[128]; strcpy(konfigfile,cfgfile); strcat(konfigfile,".TNB"); if ((fp = xfopen(konfigfile, "wt+")) == NULL) return; #else /* SAVEPARAMFIX */ if ((fp = xfopen("PARMS.TNB", "wt+")) == NULL) return; #endif /* SAVEPARAMFIX */ #ifdef ST setvbuf(fp, NULL, _IOFBF, 4096L); /* speedup */ #endif mbp = (MBHEAD *) allocb(ALLOC_MBHEAD); /* Versionskennung und Datum speichern */ putprintf(mbp, "; ----------------------------------------------\r" ";\r" "; THIS FILE MAY BE OVERWRITTEN - DO NOT CHANGE!!\r" "; (use %s.TNB)\r;\r", cfgfile); putprintf(mbp, "; ----------------------------------------------\r" "; TheNetNode AutoConfiguration Batch File\r" ";\r" "; Created: "); puttim(&sys_time, mbp); call2str(call,myid); putprintf(mbp, "\r; Version: %s;\r" "; Node Ident : %s\r" "; Node MyCall: %s\r;\r", version, alias, call); #ifdef ATTACH dump_attach(mbp); #endif /* die ganzen Parameter ausgeben, nach DL1XAO */ dump_ports(mbp); dump_beacn(mbp); dump_convc(mbp); dump_links(mbp); dump_parms(mbp); #ifdef THENETMOD dump_l4parms(mbp); /* L4-Parameter speichern. */ /* L4QUALI */ dump_routes(mbp); /* Qualitaet einer Route (nur THENET) speichern. */ #endif /* THENETMOD */ dump_suspd(mbp); #ifdef ALIASCMD dump_alias(mbp); #endif #ifdef IPROUTE dump_ipr(mbp); #endif #ifdef KERNELIF dump_kernel(mbp); #endif #ifdef AX25IP dump_ax25ip(mbp); #endif #ifdef SPEECH dump_speech(mbp); #endif #ifdef L1TCPIP DumpTCP(mbp); #endif /* L1TCPIP */ dump_divrs(mbp); rwndmb(mbp); while (mbp->mbgc < mbp->mbpc) { ch = getchr(mbp); if (ch == CR) fprintf(fp, "\n"); else fputc(ch, fp); } dealmb(mbp); fclose(fp); } /************************************************************************/ /* Ein Ereignis protokollieren, jeder Sysop, der einen Trace mit dem */ /* notwendigen Level eingestellt hat, bekommt die Meldung zugeschickt. */ /*----------------------------------------------------------------------*/ void notify(int level, const char *format, ...) { #if MAX_TRACE_LEVEL > 0 #define NOTIFYVSNPFBUFF 1024 va_list arg_ptr; char str[NOTIFYVSNPFBUFF]; USRBLK *sav_userpo; MBHEAD *mbp; struct tm *p; int n; p = localtime(&sys_time); va_start(arg_ptr, format); n = vsnprintf(str, NOTIFYVSNPFBUFF, format, arg_ptr); va_end(arg_ptr); if (n == -1 || n > NOTIFYVSNPFBUFF) return; sav_userpo = userpo; for (userpo = (USRBLK *) usccpl.head; userpo != (USRBLK *) &usccpl; userpo = (USRBLK *) userpo->unext) { if (userpo->status == US_CCP && userpo->auditlevel >= level) { mbp = getmbp(); putprintf(mbp, "(%u) %02d.%02d.%02d %02d:%02d:%02d ", level, p->tm_mday, p->tm_mon+1, p->tm_year % 100, p->tm_hour, p->tm_min, p->tm_sec); putstr(str, mbp); putchr('\r', mbp); if (!send_msg(FALSE,mbp)) dealmb((MBHEAD *)ulink((LEHEAD *)mbp)); /* der Link ist voll */ break; } } userpo = sav_userpo; #endif } /************************************************************************/ /* Feststellen, ob ein User einen Downlink auf einem Port machen darf. */ /*----------------------------------------------------------------------*/ BOOLEAN is_down_suspended(char *user_call, int user_port) { LNKBLK *link; SUSPEND *suspended; WORD user_links; WORD i, j; /* Suspended-Liste nach dem User-Rufzeichen durchsuchen */ for (suspended = sustab, i = 0; i < MAXSUSPEND; suspended++, i++) if (strnicmp(user_call, suspended->call, L2CALEN) == 0) break; if (i == MAXSUSPEND) /* User nicht in der Liste */ return(FALSE); /* er darf.. */ if (user_port == suspended->port) /* User gesperrt auf diesem Port */ return(TRUE); /* also abwerfen.. */ if (suspended->port == 254) /* darf ueberhauptnicht */ return(TRUE); if (suspended->port != 255) /* Falls 255 dann zaehlen... */ return(FALSE); /* Anzahl der Links dieses Users zum Knoten ermitteln */ for (link = lnktbl, j = 0, user_links = 0; j < LINKNMBR; j++, link++) if (cmpcal(link->dstid, user_call) && link->state != L2SDSCED ) user_links++; return(user_links > suspended->okcount); } /************************************************************************/ /*--- Test, ob User gesperrt ist ---*/ /* */ /* Parameter im Aufruf: */ /* *u_block: Pointer auf User Kontrollblock */ /* */ /* Rueckgabe: */ /* TRUE: User ist gesperrt */ /* FALSE: User hat noch mindestens einen Kanal frei */ /* */ /* Es wird auf PORT und OKCOUNT geprueft. OKCOUNT ist die Maximalzahl */ /* der zulaessigen Links, unabhaengig vom Port. PORT ist immer gesperrt.*/ /* Um einen User nur fuer einen Port zu sperren ist also OKCOUNT auf */ /* 255 zu setzen und PORT auf den Sperrport. Um einen USER auf eine */ /* Maximalzahl von Links zu begrenzen, ist PORT auf 255 zu setzen und */ /* OKCOUNT auf die gewuenschte Zahl an Links. */ /* Der Port 254 entspricht einem L4-User */ /*----------------------------------------------------------------------*/ BOOLEAN is_suspended(USRBLK *u_block) { LNKBLK *link; SUSPEND *suspended; char *user_call; UBYTE user_port; WORD user_links; WORD i, j; #ifdef L1TCPIP TCPIP *tc; #endif /* L1TCPIP */ switch (g_utyp(u_block->uid)) { case HOST_USER: return(FALSE); /* User am Host-Terminal */ /* User im Level-2 Uplink */ case L2_USER: link = g_ulink(u_block->uid); user_call = link->dstid; #ifdef __WIN32__ user_port = (unsigned char)link->liport; #else user_port = link->liport; #endif /* WIN32 */ break; /* User kommt per Circuit */ case L4_USER: user_call = ((CIRBLK *)g_ulink(u_block->uid))->upcall; user_port = 254; break; #ifdef L1TCPIP case TCP_USER: tc = g_ulink(u_block->uid); user_call = tc->Upcall; user_port = (unsigned char)tc->port; break; #endif /* L1TCPIP */ /* damit der Compiler auch bei Optimierungen zufrieden ist ... */ default: user_call = 0; user_port = 254; break; } /* Suspended-Liste nach dem User-Rufzeichen durchsuchen */ for (suspended = sustab, i = 0; i < MAXSUSPEND; ++suspended, ++i) if (cmpcal(user_call, suspended->call)) break; if (i == MAXSUSPEND) /* User nicht in der Liste */ return(FALSE); /* er darf.. */ if (user_port == suspended->port) /* User gesperrt auf diesem Port */ return(TRUE); /* also abwerfen.. */ /* Anzahl der Links dieses Users zum Knoten ermitteln */ for (link = lnktbl, j = 0, user_links = 0; j < LINKNMBR; ++j, ++link) if (cmpcal(link->dstid, user_call) && link->state != L2SDSCED ) ++user_links; if (user_links > suspended->okcount) /* Anzahl der Links ueberschritten */ return(TRUE); /* also abwerfen.. */ return(FALSE); /* User darf.. */ } #ifdef PORT_SUSPEND BOOLEAN is_port_suspended(USRBLK *u_block) { LNKBLK *link; char *user_call = NUL; char *p; UWORD user_port = FALSE; PEER *pp; int max_peers = netp->max_peers; int i; switch (g_utyp(u_block->uid)) { case HOST_USER: return(FALSE); /* Host ist nie gesperrt !!! */ case L2_USER: link = g_ulink(u_block->uid); /* In den Linkblock wird ein Zeiger auf das Rufzeichen abgelegt, das in */ /* Wirklichkeit der Ansprechpartner dieses Linkes ist. Es ist das Erste */ /* Rufzeichen im via-Feld ohne H-Bit oder das Ziel-Rufzeichen selbst. */ for (p = link->viaidl; *p; p += L2IDLEN) if ((p[L2IDLEN - 1] & L2CH) == 0) break; link->realid = *p ? p : link->dstid; user_call = link->realid; user_port = link->liport; break; case L4_USER: return(FALSE); /* damit der Compiler auch bei Optimierungen zufrieden ist ... */ default: break; } for (i = 0, pp = netp->peertab; i < max_peers; i++, pp++) if (pp->used) { if ((cmpcal(user_call,pp->l2link->call) || (cmpcal(user_call,pp->l2link->digil) == TRUE))) if ((user_port == pp->l2link->port) == TRUE) return (FALSE); } return(TRUE); } #endif /************************************************************************/ /*--- CRC-Tabelle berechnen ---*/ /* */ /*----------------------------------------------------------------------*/ void init_crctab(void) { UWORD n; UWORD m; UWORD r; UWORD mask; static UWORD bitrmdrs[] = { 0x9188, 0x48C4, 0x2462, 0x1231, 0x8108, 0x4084, 0x2042, 0x1021}; for (n = 0; n < 256; ++n) { for (mask = 0x0080, r = 0, m = 0; m < 8; ++m, mask >>= 1) if (n & mask) r = bitrmdrs[m] ^ r; crctab[n] = r; } } /*----------------------------------------------------------------------*/ static char *search_file(char *dir_name, char *text_name) { /* */ /* Das erste Wort in *clipoi als Filenamen annehmen. Dabei sind */ /* Abkuerzungen erlaubt. Nach einem passenden File im Directory dir_name*/ /* suchen und den Namen bei Bedarf ergaenzen. */ /* */ /* Rueckgabe: char * auf den Filenamen ohne Extention, wenn gefunden */ /* NULL : kein passendes File gefunden */ /* */ /* 18/02/95 DL9HCJ Extention nicht zurueckgeben, damit mehr Platz in der*/ /* Eingabezeile ist. */ /* */ /*----------------------------------------------------------------------*/ char *cli_save; WORD cli_cnt; struct ffblk file_block; WORD i; cli_save = clipoi; cli_cnt = clicnt; strcpy(text_name, dir_name); i = 0; while (isalnum(*clipoi) && (i < 8) && (clicnt > 0)) { strncat(text_name, (char *) clipoi++, 1); clicnt--; i++; } if (i == 0) return(NULL); if (i < 8) strcat(text_name, "*"); /*****************************************************************************/ /*** Da es beim MC68302-Betriebssystem keine Verzeichnisse gibt, unter- ***/ /*** scheiden wir anhand der Dateiendung um was es sich hier handelt... ***/ #ifdef MC68302 if (dir_name == userexepath) strcat(text_name, ".APU"); else if (dir_name == sysopexepath) strcat(text_name, ".APS"); else strcat(text_name, ".TXC"); #endif #if defined(__GO32__) || defined(__WIN32__) if (dir_name == textcmdpath) strcat(text_name, ".TXT"); else strcat(text_name, ".EXE"); #endif #ifdef ST if (dir_name == textcmdpath) strcat(text_name, ".TXT"); else strcat(text_name, ".TTP"); #endif if (xfindfirst(text_name, &file_block, 0) == 0) { strcpy(text_name, dir_name); strcat(text_name, file_block.ff_name); return(text_name); } clipoi = cli_save; clicnt = cli_cnt; return(NULL); } /*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/ BOOLEAN read_txt(void) { /* */ /* Das erste Wort *clipoi als Filenamen annehmen. Dabei sind */ /* Abkuerzungen erlaubt. Nach einem passenden File im Directory "TEXT" */ /* suchen und den Namen bei Bedarf ergaenzen. Das File lesen und an den */ /* User userpo schicken. */ /* */ /* Rueckgabe: */ /* TRUE: Fehler, File nicht gefunden. */ /* FALSE: kein Fehler. */ /* */ /*----------------------------------------------------------------------*/ char file_path[128]; if (search_file(textcmdpath, file_path) != NULL) { ccpread(file_path); return(FALSE); } return(TRUE); } /*----------------------------------------------------------------------*/ BOOLEAN do_file(char *directory) { /* */ /* Sucht in Directory directory nach einem zu *clipoi passenden File */ /* und fuehrt es bei Erfolg aus. Der Rest von clilin wird als Argument */ /* uebergeben. */ /* Wenn die auszufuehrende Kommandozeile nicht zu lang ist, dann wird */ /* die Ausgabe auf ein File umgeleitet und an den User ueber ccpread */ /* geschickt. */ /* Als zusaetzliches Argument wird das User Call+SSID uebergeben */ /* */ /* Rueckgabe: TRUE : Fehler, kein File gefunden */ /* FALSE: kein Fehler aufgetreten */ /* */ /*----------------------------------------------------------------------*/ /* Puffergroesse je nach OS */ #if !defined(__LINUX__) && !defined(__WIN32__) #define MAXCMDLINE 512 /* so wie bisher */ #else #define MAXCMDLINE MAXPATH /* Linux (mehr hat keinen Sinn, siehe unten) */ #endif char command_line[MAXCMDLINE]; char call[10]; char *tmpfile; #ifdef __GO32__ int i; #endif if (search_file(directory, command_line) != NULL) { if (clicnt > 0) { /* Vorerst case abfangen -> nur Sonderzeichen */ /* zusaetzlich noch das, was spaeter noch maximal angehaengt */ /* werden kann (Call, Umleitung und temp. Datei) */ if ( 2*(clicnt-1) + strlen(command_line) + 21 <= MAXCMDLINE) strncat(command_line, (char *) clipoi, clicnt); else { putmsg("Commandline too long..\r"); return(FALSE); } } #ifdef __LINUX__ security_check(command_line); #else command_line[strcspn(command_line,"<>|")] = NUL; #endif strcat(command_line, " "); tmpfile = tempnam(textpath, "do"); if (tmpfile == NULL) return(FALSE); call2str(call, usrcal); strcat(command_line, call); /* Call anhaengen */ #ifndef MC68302 strcat(command_line, " > "); /* Ausgabe umleiten */ #else strcat(command_line, " "); #endif strcat(command_line, tmpfile); /* Zieldatei */ #ifdef __LINUX__ if (strlen(command_line) > 127) /* max. Laenge der Kommando- */ #else if (strlen(command_line) > MAXPATH) /* max. Laenge der Kommando- */ #endif { /* Zeile ist 127 bei DOSE */ #ifdef SPEECH putmsg(speech_message(278)); #else putmsg("Commandline too long..\r"); #endif free(tmpfile); } else { xchdir(textpath); system(command_line); /* Ausgaben ins Temporaerfile */ #ifdef __GO32__ for (i = 0; i < MAXCOMS; i++) clear_rs232(i); /* DOS schaltet IRQs ab??? */ #endif xchdir(NULL); #ifdef MAKRO_FILE /* Markiere, userpo->fp NICHT updaten. */ userpo->read_ok = TRUE; #endif userpo->fname = tmpfile; ccpread(tmpfile); } return(FALSE); /* Kommandoauswertung beenden */ } return(TRUE); } /*----------------------------------------------------------------------*/ BOOLEAN extern_command(void) { /* */ /* Sucht in Directory "USEREXE" nach einem *clipoi passenden File */ /* und fuehrt es bei Erfolg aus. Der Rest von clilin wird als Argument */ /* uebergeben. Die Ausgabe wird auf EXTCMD.TMP umgeleitet und den User */ /* ueber ccpread geschickt. */ /* Als zusaetzliches Argument wird das User Call uebergeben */ /* Falls der User Sysop Status hat, auch in "SYSEXE" nachsehen */ /* */ /* Rueckgabe: TRUE : Fehler, kein File gefunden */ /* FALSE: kein Fehler aufgetreten */ /* */ /*----------------------------------------------------------------------*/ if (!do_file(userexepath)) return(FALSE); if (issyso()) return(do_file(sysopexepath)); return(TRUE); } /*----------------------------------------------------------------------*/ TRILLIAN intern_command(COMAND *tabelle) { /* */ /* Das erste Wort in clilin als Befehl annehmen und nach einem */ /* passenden Befehl suchen und ihn bei Erfolg ausfuehren. */ /* */ /* Rueckgabe: ERRORS: Befehl mit Sonderzeichen */ /* YES : Fehler, nichts gefunden */ /* NO : kein Fehler, Befehl wurde ausgefuehrt. */ /* */ /*----------------------------------------------------------------------*/ COMAND *cmdpoi; const char *cmdnam; char *command_line_save; WORD command_length_save; command_line_save = clipoi; command_length_save = clicnt; for (cmdpoi = tabelle; cmdpoi->cmdstr != 0; ++cmdpoi) { clipoi = command_line_save; clicnt = command_length_save; cmdnam = cmdpoi->cmdstr; while ((clicnt != 0) && (*clipoi != ' ')) { if ((char) toupper(*clipoi) != *cmdnam) break; ++clipoi; --clicnt; ++cmdnam; } if (clicnt == 0 || *clipoi == ' ') break; } if (cmdpoi->cmdfun != NULL) { skipsp(&clicnt, &clipoi); (*cmdpoi->cmdfun)(cmdpoi->cmdpar); return(NO); } clipoi = command_line_save; clicnt = command_length_save; while ((clicnt != 0) && (*clipoi != ' ')) { if (!isalnum(*clipoi)) return(ERRORS); ++clipoi; --clicnt; } clipoi = command_line_save; clicnt = command_length_save; return(YES); } /************************************************************************/ /* Unbekanntes Kommando, Anzahl Fehler zaehlen */ /*----------------------------------------------------------------------*/ void inv_cmd(void) { invmsg(); if (g_ulink(userpo->uid) != hstubl) if (++userpo->errcnt >= 5) disusr(userpo->uid); } /************************************************************************/ /* Binaerfile einladen, Pruefsumme berechnen. */ /*----------------------------------------------------------------------*/ void program_load(MBHEAD *mhdp) { MBHEAD *mbp; #ifndef AUTOBINAERFIX char c; #else UBYTE c; #endif /* AUTOBINAERFIX */ while (mhdp->mbgc < mhdp->mbpc) { c = getchr(mhdp) & 0xFF; fputc(c, loadfp); checksum += c; crc = crctab[crc >> 8] ^ ((crc << 8) | (UWORD)c); bytecnt--; if (bytecnt == 0L) { userpo->status = US_CCP; fclose(loadfp); mbp = getmbp(); #ifndef MC68302 if (xrename(loadtmp, loadname) == 0) #endif strcpy(loadtmp, loadname); #ifndef AUTOBINAERFIX putprintf(mbp,"%s ok. Checksum: %ld CRC: %u\r", loadtmp, checksum, crc); #else putprintf(mbp,"%s ok.\rChecksum: %ld CRC: %u\r", loadtmp, checksum, crc); #endif /* AUTOBINAERFIX */ prompt(mbp); seteom(mbp); checksum = 0L; crc = 0; loadname[0] = loadtmp[0] = NUL; } } } /*----------------------------------------------------------------------*/ /* Binaerfileuebertragung nach dem THP-AUTOBIN-Format starten. */ /*----------------------------------------------------------------------*/ void start_autobin(void) { MBHEAD *mbp; if (strnicmp(clilin, "#BIN#", 5) == 0) { clipoi = clilin + 5; clicnt -= 5; if ((bytecnt = nxtlong(&clicnt,&clipoi)) != 0L) { userpo->status = US_RBIN; xremove(loadname); mbp = getmbp(); putstr("#OK#\r", mbp); seteom(mbp); return; } } fclose(loadfp); loadname[0] = loadtmp[0] = NUL; userpo->status = US_CCP; } /*----------------------------------------------------------------------*/ /* Text-Eingabe starten. Der Text wird zunaechst in die Datei TMP.TXT */ /* geschrieben. Wird ein '.' als erstes Zeichen einer Zeile empfangen, */ /* wird TMP.TXT umbenannt in den vom Sysop angegebenen Dateinamen. */ /* Da nur ein temporaeres File TMP.TXT zur gleichen Zeit vorhanden */ /* sein kann, darf bei mehreren eingelogten Sysops immer nur einer */ /* Dateien editieren. */ /*----------------------------------------------------------------------*/ void load_text(void) { MBHEAD *mbp; *clipoi = NUL; clipoi = clilin; if (*clipoi == '.' || *clipoi == 0x1A) { userpo->status = US_CCP; fclose(loadfp); mbp = getmbp(); #ifndef MC68302 #ifdef __WIN32__ remove(loadname); #endif if (xrename(loadtmp, loadname) == 0) #endif strcpy(loadtmp, loadname); putprintf(mbp, "%s ok!\r", loadtmp); prompt(mbp); seteom(mbp); loadname[0] = loadtmp[0] = NUL; } else { fputs(clilin, loadfp); fputc('\n', loadfp); } } /************************************************************************/ /* Vom User eingegebene Zeichen mit aktuellem Passwort vergleichen und */ /* bei korrekter Eingabe SYSOP-Flag setzen. In jedem Fall den Versuch */ /* in die Datei SYSOP-PRO aufnehmen. */ /*----------------------------------------------------------------------*/ void get_password(void) { WORD i; char file[128]; FILE *fp; char pwd[6]; /* ala BayBox DL1XAO */ memcpy(pwd, userpo->paswrd, 5); pwd[5] = NUL; i = FALSE; if (strlen((char *)clipoi) > 80) /* maximal 80 Zeichen */ *(clipoi + 80) = NUL; if (clicnt >= 5 && strstr((char *)clipoi, pwd) != NULL) { userpo->errcnt = 0; i = TRUE; #ifndef USER_PASSWORD userpo->sysflg = 1; #else if (userpo->status == US_WPWD) userpo->sysflg = 1; userpo->pwdtyp = PW_USER; #endif } else if (++userpo->errcnt >= 5) { disusr(userpo->uid); return; } /* Wenn SYSOP-Protokoll gefuehrt werden soll, Rufzeichen, Datum, */ /* Zeit und ob SYSOP-Befehl erfolgreich in eine Datei mit Namen */ /* SYSOP.PRO schreiben. Diese Datei kann spaeter vom SYSOP */ /* ausgelesen und ausgewertet werden. */ #ifndef USER_PASSWORD if (syspro_flag == TRUE) #else if (syspro_flag == TRUE && userpo->status == US_WPWD) #endif { strcpy(file, confpath); strcat(file, "SYSOP.PRO"); if ((fp = xfopen(file,"at")) != NULL) { fprintf(fp, "%24.24s %6.6s: %s\n", ctime(&sys_time), calofs(UPLINK, userpo->uid), i ? "accepted" : "rejected"); fclose(fp); } } userpo->status = US_CCP; } /* * CTEXT mit mehr Moeglichkeiten (wie prompt) */ void out_ctext(char *name, MBHEAD *mbp) { FILE *fp; char line[128]; char *c; if ((fp = xfopen(name, "rt")) != NULL) { while (fgets(line, 126, fp) != NULL) { if ((c = strchr(line, '\n')) != NULL) *c = CR; prompt2str(mbp, line); } fclose(fp); } } /* * Einstiegsport des User feststellen fuer LOOP-Warning */ int userport(USRBLK *u) { CIRBLK *cirp; LNKBLK *lnkp; #ifdef L1TCPIP TCPIP *tpoi; #endif /* L1TCPIP */ PEER *pp; /* Einstiegsport des Users feststellen (fuer LOOP-Warning) */ switch (g_utyp(u->uid)) { case L4_USER: /* User ist Circuit */ cirp = (CIRBLK *) g_ulink(u->uid); if (find_best_qual(find_node_this_ssid(cirp->l3node), &pp, DG) > 0) return(pp->l2link->port); break; case L2_USER: /* User ist L2-Link */ lnkp = (LNKBLK *) g_ulink(u->uid); return(lnkp->liport); #ifdef L1TCPIP case TCP_USER: /* User ist TCPIP */ tpoi = (TCPIP *) g_ulink(u->uid); return(tpoi->port); #endif /* L1TCPIP */ } return(L2PNUM); /* Defaultport */ } /* * Manche Befehle erhalten die Anwort erst ein bischen spaeter (PING, * DEST, NRR usw), deshalb mit besonderer Vorsicht ausgeben. */ void send_async_response(USRBLK *ublk, const char *title, const char *text) { MBHEAD *mbp; USRBLK *up; LHEAD mbhd; /* Antwort generieren und an den User senden */ for (up = (USRBLK *) usccpl.head; (USRBLK *) &usccpl != up; up = (USRBLK *) up->unext) { if (up == ublk) /* das ist der gesuchte User, darf er die Antwort bekommen? */ if ((up->status == US_CCP || up->status == US_TALK)) { (mbp = (MBHEAD *)allocb(ALLOC_MBHEAD))->l2fflg = L2CPID; /* tnx DB2OS */ putchr('\r', mbp); putalt(alias, mbp); putid(myid, mbp); putprintf(mbp, "> %s%s\r", title, text); rwndmb(mbp); inithd(&mbhd); relink((LEHEAD *)mbp, (LEHEAD *)mbhd.tail); if (!itousr(up->uid, NO_UID, FALSE, mbp)) dealmb(mbp); } } } /************************************************************************/ /* Parameternummer aus Namen ermitteln */ /*----------------------------------------------------------------------*/ static UWORD getparnum(PARAM *partab, int len) { size_t l; UWORD num; PARAM *p; for (p = partab, num = 1; num <= len; p++, num++) if (p->paradr) { l = strlen(p->parstr); if (!strnicmp(p->parstr, clipoi, l)) { clipoi += l; clicnt -= (WORD)l; return(num); } } return(0); } /* Interpreter fuer einfache Parametertabellen. */ void ccp_par(const char *name, PARAM *partab, int len) { int i; UWORD parnum; MBHEAD *mbp; PARAM *parpoi; UWORD nummer; UWORD wert; nummer = 0; if (issyso()) { if (!isdigit(*clipoi)) nummer = getparnum(partab, len); else nummer = nxtnum(&clicnt, &clipoi); } if (nummer != 0 && nummer <= len) { parpoi = partab + nummer-1; if ( clicnt != 0 && ((wert = nxtnum(&clicnt, &clipoi)) >= parpoi->minimal) && (wert <= parpoi->maximal) ) *(parpoi->paradr) = wert; mbp = putals(name); putprintf(mbp, "%u: %s = %u (%u...%u)\r", nummer, parpoi->parstr, *(parpoi->paradr), parpoi->minimal, parpoi->maximal); } else { mbp = putals(name); mbp->l4time = mbp->mbpc; for (i = 0, parnum = 1, parpoi = partab; parnum <= len; ++i, ++parnum, ++parpoi) { if (i >= 3) { putchr('\r', mbp); mbp->l4time = mbp->mbpc; i = 0; } else #ifdef __WIN32__ putspa((char)(25 * i), mbp); #else putspa(25 * i, mbp); #endif /* WIN32 */ putprintf(mbp, "%02u:%-12s %5u", parnum, parpoi->parstr, *(parpoi->paradr)); } putchr('\r', mbp); } prompt(mbp); seteom(mbp); } /* Rufzeichen eintragen/Austragen. */ void ccp_call(char *id) { if (!issyso()) invmsg(); if (*clipoi == '-') /* Call austragen? */ { id[0] = NUL; putmsg("ok\r"); } else if (getcal(&clicnt, &clipoi, TRUE, id) != YES) { /* ein Call ? */ #ifdef SPEECH putmsg(speech_message(167)); #else putmsg("Invalid call\r"); #endif } else { MBHEAD *mbp = getmbp(); prompt(mbp); seteom(mbp); } } /* Fuer den L4 feststellen, wie gross fragmentierte Frames sein duerfen */ int ptc_p_max(void *link, UBYTE typ) { UID p_uid; p_uid = (ptctab + g_uid(link, typ))->p_uid; if (p_uid == NO_UID) return(256); if (g_utyp(p_uid) == L4_USER) return(236); return(256); } #ifdef MAKRO_USER /* Wir zaehlen alle Interlinks und */ /* Convers-Host's die aktiv sind. */ static UWORD Interlinks_zaehlen(void) { PEER *pp; PERMLINK *p; int i; int max_peers = netp->max_peers; UWORD interlinks = 0; /* Interlinks zaehlen ausser */ /* LOCAL ,LOCAL_N, LOCAL_V. */ for (i = 0, pp = netp->peertab; i < max_peers; i++, pp++) { /* Nur benutzte eintraege. */ if (pp->used) { /* Rufzeichen? */ if (pp->l2link->call) { /* Pruefe ob das Rufzeichen ein LOCAL ist. */ if (pp->typ >= LOCAL) continue; /* Ist der PEER aktiv? */ if (pp->nbrl2l == NULL) /* Nein! */ continue; /* Kein LOCAL/N/V und aktiv.*/ interlinks++; } /* kein Rufzeichen gefunden. */ } /* freier eintrag. */ } /* Zaehlen der Convers-Host's. */ for (i = 0; i < MAXCVSHOST; i++) { p = permarray[i]; /* Nur eingetragene Host's zaehlen. */ if (p != NULL) { /* Ist der Host aktiv? */ if (p->connection) /* Dann wird gezaehlt. */ interlinks++; /* Host ist nicht aktiv. */ continue; } /* Kein Host gefunden. */ /* Weiter suchen. */ break; } /* Gesamtanzahl der Interlinks und Convers-Host's. */ return(interlinks); } #endif #ifdef CONNECTTIME /*************************************************************************/ /* */ /* Connect-Zeit in Flexnet-Stil ausgeben. */ /* 1 CB0RIE CB1GLA IXF 0 0 0 13 136 138 96 13h,21m - */ /* ======= */ /*************************************************************************/ char *ConnectTime(unsigned long contime) { static char runtime[8 + 1]; char *time = runtime; register int zeit; unsigned long sec, min, std; zeit = contime; sec = zeit % 60L; zeit /= 60L; min = zeit % 60L; zeit /= 60L; std = zeit % 24L; zeit /= 24L; if (zeit > 0) sprintf(time, "%2dd,%2luh",zeit, std); /* Tage, Stunden. */ else if (std > 0) sprintf(time, "%2luh,%2lum",std, min); /* Stunden, Minuten. */ else if (min > 0) sprintf(time, "%2lum,%2lus", min, sec); /* Minuten, Sekunden. */ else { if (sec > 0) sprintf(time, " %2lus", sec); /* Ausgabe in Sekunden. */ else sprintf(time, " "); } return(time); } #endif /* CONNECTTIME */ /* Ende src/l7utils.c */