home *** CD-ROM | disk | FTP | other *** search
/ Hacker Chronicles 2 / HACKER2.BIN / 550.TNL7B.C < prev    next >
Text File  |  1988-05-14  |  22KB  |  578 lines

  1. /*****************************************************************************/
  2. /*                                              */
  3. /*                                         */
  4. /*    *****              *****                      */
  5. /*     *****            *****                         */
  6. /*       *****          *****                         */
  7. /*         *****        *****                         */
  8. /*  ***************      ***************                     */
  9. /*  *****************    *****************                     */
  10. /*  ***************      ***************                     */
  11. /*         *****        *****       TheNet                    */
  12. /*       *****          *****       Portable. Compatible.         */
  13. /*     *****            *****       Public Domain             */
  14. /*    *****              *****    NORD><LINK                  */
  15. /*                                         */
  16. /* This software is public domain ONLY for non commercial use                */
  17. /*                                                                           */
  18. /*                                         */
  19. /*****************************************************************************/
  20.  
  21. /* Level 7B, Befehlsinterpreter, Befehle                     */
  22. /* Version 1.01                                   */
  23. /* Hans Georg Giese, DF2AU, Hinter dem Berge 5, 3300 Braunschweig         */
  24. /* 08-MAY-88                                     */
  25.  
  26. # include "tndef.h"        /* Definition von Konstanten             */
  27. # include "tntyp.h"        /* Definition der Typen                 */
  28. # include "tnl7be.h"        /* externe Definitionen                 */
  29.  
  30. /*---------------------------------------------------------------------------*/
  31. VOID    ccpcon()        /* CONNECT Befehl                 */
  32.   {
  33.   char       call[7];        /* User Call                     */
  34.   char       digil[57];        /* Downlink Digiliste                 */
  35.   char       node[6];        /* Ziel Node                     */
  36.   char       *cpoisa;        /* Temp fuer clipoi                 */
  37.   unsigned ccntsa;        /* Temp fuer clicnt                 */
  38.   unsigned iscall;        /* Ergebniss der Suche nach Call         */
  39.   unsigned isnode;        /* Ergebniss der Suche nach Node         */
  40.   unsigned cnt;            /* Scratch Zaehler                 */
  41.   usrtyp   *usrpoi;        /* aktueller User beim Suchen             */
  42.   l2ltyp   *frelnk;        /* freier lnkpoi Platz                 */
  43.   l2ltyp   *p_cblk;        /* Partner lnkpoi Block                 */
  44.   
  45.   if (!ismemr()) return;    /* noch Platz?                      */
  46.  
  47.   if (clicnt != 0)        /* ohne Parameter -> Host connecten         */
  48.    {
  49.     cpoisa = clipoi;        /* Parameter des Aufrufs retten             */
  50.     ccntsa = clicnt;
  51.     isnode = getide(node);    /* Node angegeben?                 */
  52.     clipoi = cpoisa;        /* Aufrufparameter zurueck             */
  53.     clicnt = ccntsa;
  54.  
  55.     if (
  56.        (((iscall = ((getcal(&clicnt, &clipoi, VCpar, call) == 1) &&
  57.                     (getdig(&clicnt, &clipoi, 0, digil) != -1))
  58.                     ) == 1)
  59.         && (digil[0] == 0)
  60.         && (seades(call) == 1))
  61.         || ((isnode == 1) && (isidnt(node) == 1)))
  62.        {
  63.  
  64. /*=== Node soll connected werden ============================================*/
  65.         for (cnt = 0, cirpoi = cirtab; cnt < NUMCIR; ++cnt, ++cirpoi)
  66.          {                /* freien Platz in CIRTAB suchen     */
  67.           if (cirpoi->state3 == 0) break;
  68.          }
  69.         if (cnt != NUMCIR)        /* Erfolg dabei?             */
  70.          {
  71.           userpo->cblk_p = (l2ltyp *) cirpoi;    /* in User Block eintragen   */
  72.           userpo->typ_p = 4;        /* und Usertyp eintragen         */
  73.           userpo->status = 2;        /* Staus: connect requested         */
  74.           cpyid(cirpoi->downca, despoi->nodcal);
  75.           cpyid(cirpoi->upcall, usrcal);/* User Call merken             */
  76.           cirpoi->l3node = despoi;    /* CIRTAB Eintrag mit Userdaten         */
  77.           newcir();            /* Circuit aufbauen             */
  78.          }
  79.         else puttfu("Circuit");        /* kein Platz: melden             */
  80.         return;
  81.        }
  82.  
  83. /*=== User soll connected werden ============================================*/
  84.     if (iscall == 1)            /* gueltiges Call?             */
  85.      {
  86.                     /* Antwort auf CQ-Ruf?             */
  87.       for (usrpoi = (usrtyp *) usccpl.lnext;
  88.            (usrtyp *) &usccpl != usrpoi;
  89.             usrpoi = usrpoi->unext)
  90.        {                /* Userliste absuchen             */
  91.         if ((usrpoi->status == 2)    /* Status muss stimmen             */
  92.           &&(usrpoi->typ_p == 2)    /* gesuchter Partner muss stimmen    */
  93.           &&((p_cblk = usrpoi->cblk_p)->state == 0)) /* und noch kein L2     */
  94.          {
  95.          if (cmpid(p_cblk->srcid, call) == 1) /* und eigenes Call         */
  96.           {
  97.            disusr(p_cblk, 2);        /* dann aus CCP entfernen         */
  98.            for (ptcrdp = ptcrdl; ptcrdp->luserl != 0; ptcrdp += 2)
  99.             ;                /* freier Eintrag links             */
  100.            makcon(usrpoi);        /* Verbindung herstellen         */
  101.            ++ptcrdp;            /* auf rechte Seite             */
  102.            frelnk = (l2ltyp *) userpo;
  103.            userpo = usrpoi;
  104.            makcon(usrpoi = (usrtyp *) frelnk);    /* zweite Seite              */
  105.            kilusr();            /* Partner loeschen             */
  106.            userpo = usrpoi;
  107.            kilusr();            /* eigenen Eintrag loeschen         */
  108.            return;
  109.           }
  110.          }
  111.        }
  112.                                         /* Connect in L2 absetzen         */
  113.       invsid();                /* SSID aendern                 */
  114.       for (p_cblk = 0, cnt = 0, lnkpoi = lnktbl; /* freien Eintrag finden    */
  115.            cnt < MAXL2L; ++cnt, ++lnkpoi)
  116.        {
  117.         if (lnkpoi->state != 0)        /* Eintrag leer?             */
  118.          {
  119.           if ((cmpid(lnkpoi->srcid, usrcal) == 1)
  120.             && (cmpid(lnkpoi->dstid, call) == 1))
  121.            {
  122.             msgfrm('D', lnkpoi, 2, dmmsg); /* nicht gleiche Partner 2-mal    */
  123.             return;
  124.            }
  125.          }
  126.         else                /* leerer Eintrag gefunden:         */
  127.          {
  128.           if ((! p_cblk) && (lnkpoi->srcid[0] == 0))
  129.            p_cblk = lnkpoi;        /* den ersten merken             */
  130.          }
  131.         }
  132.       if (p_cblk != 0) {        /* freier Platz da?             */
  133.         lnkpoi = p_cblk;        /* merken                 */
  134.         setl2b();            /* L2 Block initialisieren         */
  135.         cpyid(lnkpoi->dstid, call);    /* Partner Call                 */
  136.         cpyidl(lnkpoi->viaid, digil);    /* Digipeater                 */
  137.         lnkpoi->liport = 0;        /* Port ist HDLC             */
  138.         newlnk();            /* an Level2 melden             */
  139.         }
  140.       else {                /* alles voll                 */
  141.         puttfu("Link");            /* melden                 */
  142.         }
  143.     }
  144.     else invcal();
  145.     return;
  146.     }
  147.  
  148. /*=== Host soll connected werden ============================================*/
  149.   for (cnt = 0, hstusr = hstubl;    /* alle Hostkanaele absuchen         */
  150.        cnt < MAXHST;
  151.        ++cnt, ++hstusr) {
  152.     if (! hstusr->conflg)        /* dieser Kanal belegt?             */
  153.       break;
  154.     }
  155.   if (cnt != MAXHST) {            /* freien Kanal gefunden?         */
  156.     userpo->cblk_p = (l2ltyp *) hstusr;        /* Host als Partner eintragen*/
  157.     userpo->typ_p = 0;            /* Usertyp ist Host             */
  158.     userpo->status = 2;            /* neuer Status: connect requested   */
  159.     cpyid(hstusr->call, usrcal);    /* Usercall in Hostblock eintragen   */
  160.     hstreq();                /* Request an Hostinterface leiten   */
  161.     return;
  162.     }
  163.   else puttfu("Host");            /* kein Kanal frei             */
  164. }
  165.  
  166. /*---------------------------------------------------------------------------*/
  167. ccpcq()                /* CQ-Ruf starten                 */
  168.   {
  169.   unsigned cnt;                /* Scartch Zaehler             */
  170.   mhtyp    *mbhd;            /* Buffer fuer Meldung             */
  171.  
  172.   if (ismemr() == 1)            /* Platz genug?                 */
  173.    {
  174.     for (cnt = 0, lnkpoi = lnktbl; cnt < MAXL2L; ++cnt, ++lnkpoi)
  175.      {                    /* freien Platz in L2-Liste suchen   */
  176.       if ((lnkpoi->state == 0) && (lnkpoi->srcid[0] == 0))
  177.         break;
  178.      }
  179.     if (cnt < MAXL2L)
  180.      {
  181.       invsid();                /* SSID umdrehen             */
  182.       setl2b();                /* L2 Kontrollblock initialisieren   */
  183.       if (cqen == 1)            /* CQ-Ruf zulaessig?             */
  184.        {
  185.         (mbhd = (mhtyp *) allocb())->pid = 0xf0;    /* PID setzen                 */
  186.         while (clicnt != 0)        /* Rest der Zeile ist Meldung         */
  187.          {
  188.           putchr(*clipoi++, mbhd);    /* umkopieren                 */
  189.           --clicnt;
  190.          }
  191.         putchr(0x0d, mbhd);        /* Zeilenende anhaengen             */
  192.         rwndmb(mbhd);            /* Pointer auf Null             */
  193.         sdui(cqdil, cqdest, usrcal, 0, mbhd); /* senden                 */
  194.         dealmb(mbhd);            /* Buffer wieder freigeben         */
  195.        }
  196.      }
  197.     else                /* Tabelle ist voll             */
  198.       puttfu("Link");            /* melden                 */
  199.    }
  200.   }
  201.  
  202. /*---------------------------------------------------------------------------*/
  203. VOID    ccpide()        /* Befehl INFO                     */
  204.   {
  205. mhtyp     *bufpoi;                /* Buffer fuer Meldung         */
  206. unsigned chaptr;
  207.  
  208.   if (issyso() == TRUE)                /* Sysop setzt Zusatz?         */
  209.    {
  210.     chaptr = 0;
  211.     while (clicnt-- != 0)
  212.      {
  213.       infmsg[chaptr++] = *clipoi++;
  214.      }
  215.     infmsg[chaptr] = 0;
  216.    }
  217.  
  218.   bufpoi = putals(DEFINF);            /* Info mit Header         */
  219.   putchr('\015', bufpoi);
  220.   putstr(infmsg, bufpoi);            /* Zusatzinfo             */
  221.   seteom(bufpoi);                /* Endekennung dran         */
  222.   }
  223.  
  224. /*---------------------------------------------------------------------------*/
  225. VOID    ccpnod()        /* NODES Befehl                     */
  226.   {
  227.   char       newcal[7];        /* neues Call                     */
  228.   char       niden[6];        /* neuer Ident                     */
  229.   char     *cpoisa;        /* temp fuer clipoi                 */
  230.   BOOLEAN  alles;        /* versteckte Nodes auch zeigen             */
  231.   unsigned nobc;        /* neuer Abwesenheitszaehler             */
  232.   unsigned wegcnt;        /* Zaehler fuer Wege in Ausgabe             */
  233.   unsigned aender;        /* Aenderungsmode: + oder -             */
  234.   unsigned iscall;        /* Ergebniss des Tests auf gueltiges Call    */
  235.   unsigned isnode;        /* Ergebniss des Tests auf gueltigen Node    */
  236.   unsigned ccntsa;        /* temp fuer clicnt                 */
  237.   BOOLEAN  neupar;        /* neue Parameter in der Zeile             */
  238.   unsigned cnt;            /* Scratch Zaehler                 */
  239.   unsigned leer;        /* Leerzeichen bis zum naechsten Node         */
  240.   mhtyp       *bufpoi;        /* Buffer fuer Meldung an User             */
  241.   wegtyp   *actweg;        /* aktueller Weg der Ausgabe             */
  242.   nbrtyp   *nabar;        /* Nachbar fuer aktuellen Node             */
  243.  
  244.   alles = FALSE;        /* default: keine versteckten Nodes         */
  245.   if (clicnt != 0)        /* mit Argument aufgerufen?                */
  246.    {
  247.     cpoisa = clipoi;        /* Befehlszeile retten                    */
  248.     ccntsa = clicnt;
  249.     isnode = getide(niden);    /* Test auf Node Namen                 */
  250.     clipoi = cpoisa;        /* Befehlszeile zurueck                 */
  251.     clicnt = ccntsa;
  252.     iscall = getcal(&clicnt, &clipoi, VCpar, newcal); /* Test auf Call         */
  253.     clipoi = cpoisa;        /* Befehlszeile zurueck                 */
  254.     clicnt = ccntsa;
  255.  
  256.     while (clicnt != 0)
  257.      {
  258.       if (*clipoi == ' ') break;
  259.       ++clipoi;            /* Call bzw Ident ueberlesen             */
  260.       --clicnt;
  261.      }
  262.  
  263.     if ((iscall == 1)        /* alle Nodes oder was spezielles gefragt?   */
  264.       || (isnode != -1))
  265.      {
  266.       neupar = FALSE;            /* default: keine neuen Parameter    */
  267.       if ((issyso() == 1)        /* nur Sysop darf aendern         */
  268.         && (iscall == 1))        /* wenn er ein Call angibt         */
  269.        {
  270.         --clicnt;            /* Aenderungsmode uebergehen         */
  271.         if (((aender = *clipoi++) == '+') /* nur + oder - erlaubt         */
  272.           || (aender == '-'))
  273.          {
  274.  
  275. /*=== Node Parameter aendern ================================================*/
  276.           if ((skipsp(&clicnt, &clipoi) == 1) /* Parameter holen         */
  277.             && ((isnode = getide(niden)) != -1)) /* Ident             */
  278.            {
  279.             if (getqua() == 1)        /* Qualitaet holen             */
  280.              {
  281.               if ((skipsp(&clicnt, &clipoi) == 1)
  282.               && ((nobc = nxtnum(&clicnt, &clipoi)) <= 255))
  283.                {
  284.                 if (getpar() == 1) neupar = TRUE; /* Port, Digis, Nachbar    */
  285.                }
  286.              }
  287.            }
  288.          }
  289.        }
  290.       else if (isnode == 0) alles = 1; /* Sternchen eingegeben             */
  291.  
  292.       if (neupar == TRUE) {        /* neue Werte spezifiziert         */
  293.         if (chgnod(aender, nobc, nquali, nport, ndigi, ncall, niden, newcal)
  294.             == 0) {
  295.           puttfu("Routing");        /* hat nicht geklappt, Ende         */
  296.           return;
  297.           }
  298.         }
  299.       if (((iscall == TRUE) && (seades(newcal) == 1)) /* gueltiges Call         */
  300.        || ((isnode == TRUE) && (isidnt(niden) == 1))) { /* Node?         */
  301.         putnod(bufpoi = putals("Routes to: ")); /* gueltig:             */
  302.  
  303.         for (wegcnt = 0; wegcnt < despoi->wege; ++wegcnt)
  304.          {                /* alle Wege zeigen             */
  305.           nabar = (actweg = &despoi->weg[wegcnt])->nachba;
  306.           putstr((((despoi->actrou != 0) && (despoi->wegnr == wegcnt)) ?
  307.             "\015> " : "\015  "), bufpoi); /* aktiven Weg markieren         */
  308.           putnum((actweg->qualit) &0xff, bufpoi);
  309.           putchr(' ', bufpoi);
  310.           putnum((actweg->obscnt) &0xff, bufpoi);
  311.           putnbr(nabar, bufpoi);    /* Nachbarn Zeigen             */
  312.          }
  313.  
  314.         seteom(bufpoi);            /* Ende anhaengen             */
  315.         return;
  316.         }
  317.       }
  318.     }
  319.  
  320. /*=== Nodes anzeigen ========================================================*/
  321.   bufpoi = putals("Nodes:");        /* Kopfzeile holt Buffer         */
  322.   cnt = 0;                /* Nummer des Eintrages             */
  323.   for (despoi = (nodtyp *) destil.lnext;        /* gesamte Liste             */
  324.        (nodtyp *) &destil != despoi;
  325.        despoi = (nodtyp *) despoi->nodlnk.lnext) {
  326.     if (despoi->nodcal[0] != 0) {    /* Eintrag definiert?             */
  327.       if ((despoi->nodide[0] != '#')
  328.         || (alles == TRUE)) {        /* auch versteckte Nodes zeigen?     */
  329.         if ((cnt++ & 0x03) == 0)    /* 4 Nodes in eine Zeile         */
  330.           putchr('\015', bufpoi);
  331.         bufpoi->l4time = bufpoi->putcnt;
  332.         putnod(bufpoi);            /* Node ausgeben             */
  333.         putspa(19, bufpoi);        /* Abstand zum Nachbarn             */
  334.     } } }
  335.   seteom(bufpoi);            /* Endekennung anhaengen         */
  336.   }
  337.  
  338. /*---------------------------------------------------------------------------*/
  339. VOID    ccppar()        /* PARMS Befehl                     */
  340.   {
  341.   unsigned laenge;        /* Laenge der Zeile bisher             */
  342.   unsigned newval;        /* neuer Wert des Parameters             */
  343.   unsigned parnum;        /* Nummer des aktuellen Parameters         */
  344.   mhtyp       *bufpoi;        /* Message Buffer                 */
  345.   partyp   *parpoi;        /* Pointer auf aktuellen Parameter         */
  346.  
  347.   bufpoi = putals("");                /* Kopfzeile             */
  348.   for (laenge = 0, parnum = 0, parpoi = partab;
  349.        parnum < (sizeof(partab) / sizeof(struct param));
  350.        ++parnum, ++parpoi)            /* alle Parameter         */
  351.    {
  352.     if (issyso() == TRUE)            /* Sysop am anderen Ende?    */
  353.      {
  354.       if (*clipoi != '*')            /* Wert aendern?         */
  355.        {
  356.         newval = nxtnum(&clicnt, &clipoi);    /* neuen Wert holen         */
  357.         if ((newval >= parpoi->minimal) && (newval <= parpoi->maximal))
  358.          *(parpoi->paradr) = newval;
  359.        
  360.         else clicnt = 0;            /* Fehler: Rest vergessen    */
  361.        }
  362.       else                    /* Parameter bleibt:         */
  363.        {
  364.         --clicnt;                /* das Sternchen verbrauchen */
  365.         ++clipoi;
  366.        }
  367.      }
  368.     if ((bufpoi->putcnt - laenge) > 72)
  369.      {
  370.       putchr('\15', bufpoi);            /* neue Zeile             */
  371.       laenge = bufpoi->putcnt;
  372.      }
  373.     else putchr(' ', bufpoi);
  374.  
  375.     putnum(*(parpoi->paradr), bufpoi);        /* Wert ausgeben         */
  376.    }
  377.   seteom(bufpoi);        /* Endekennung anhaengen             */
  378.   }
  379.  
  380. /*---------------------------------------------------------------------------*/
  381. VOID    ccprou()        /* ROUTES Befehl                 */
  382.   {
  383.   unsigned mode;
  384.   mhtyp    *mbhd;
  385.   nbrtyp   *neigb;
  386.  
  387.   neigb = NULL;                    /* default: kein Nachbar     */
  388.   if (clicnt != 0)                /* aendern oder zeigen?         */
  389.    {
  390.     if (getpar() == TRUE)            /* Nachbardaten holen         */
  391.      {
  392.       neigb = (nbrtyp *) getnei(ndigi, ncall, nport);    /* existiert Nachbar?*/
  393.       if (issyso() == TRUE)            /* nur SYSOP darf aendern    */
  394.        {
  395.         --clicnt;
  396.         mode = *clipoi++;            /* Modus holen, merken         */
  397.         if (getqua() == TRUE)            /* Qualitaet muss passen     */
  398.          {
  399.           if (mode == '+')            /* blockieren?             */
  400.            {
  401.             if (!neigb)                /* Nachbar existiert nicht?  */
  402.               neigb = (nbrtyp *) updnbr(ndigi, ncall, nport); /* erzeugen    */
  403.  
  404.             neigb->pathqu = nquali;        /* neue Daten setzen         */
  405.             neigb->locked = TRUE;        /* blockieren             */
  406.            }
  407.           else
  408.            {
  409.             if (mode == '-')            /* freigeben?             */
  410.              {
  411.               if (neigb != NULL)        /* nur wenn Nachbar existiert*/
  412.                {
  413.                 neigb->pathqu = nquali;        /* neue Daten setzen         */
  414.                 neigb->locked = FALSE;        /* nicht blockieren         */
  415.                 if (neigb->nbrrou == 0)        /* wenn keine Wege aktiv     */
  416.                  {
  417.                   dealoc(unlink(neigb));    /* Eintrag loeschen         */
  418.                   neigb = NULL;
  419.                  }
  420.                }
  421.              }
  422.            }
  423.          }
  424.        }
  425.      }
  426.    }
  427.   mbhd = putals("Routes:");            /* neue Daten zeigen         */
  428.   if (!neigb)                    /* kein Nachbar angegeben    */
  429.    {
  430.     for (neigb = (nbrtyp *) neigbl.lnext;
  431.         (nbrtyp *) &neigbl != neigb;
  432.          neigb = (nbrtyp *) neigb->nbrlnk.lnext)
  433.      {                        /* alle Wege zeigen         */
  434.       putrou(neigb, mbhd);
  435.      }
  436.    }
  437.   else
  438.     putrou(neigb, mbhd);            /* sonst Wege des Nachbarn   */
  439.  
  440.   seteom(mbhd);                    /* Ende Kennung anhaengen    */
  441.   }
  442.  
  443. /*---------------------------------------------------------------------------*/
  444. VOID    ccpres()        /* RESET Befehl                     */
  445.  {
  446.   if (userpo->sysflg == TRUE)            /* darf nur der Sysop         */
  447.    {
  448.     magicn = 0;                    /* immer Kaltstart         */
  449.     reset();
  450.    }
  451.  }
  452.  
  453. /*---------------------------------------------------------------------------*/
  454. VOID    ccplow()        /* LOW Befehl                     */
  455.  {
  456.   if (issyso() == TRUE)                /* darf nur der Sysop         */
  457.    {
  458.     switch (nxtnum(&clicnt, &clipoi))
  459.      {
  460.       case 0:
  461.         CONled(FALSE);
  462.         break;
  463.  
  464.       case 1:
  465.         STAled(FALSE);
  466.         break;
  467.  
  468.      }
  469.    }
  470.  }
  471.  
  472. /*---------------------------------------------------------------------------*/
  473. VOID    ccphig()        /* HIGH Befehl                     */
  474.  {
  475.   if (issyso() == TRUE)                /* darf nur der Sysop         */
  476.    {
  477.     switch (nxtnum(&clicnt, &clipoi))
  478.      {
  479.       case 0:
  480.         CONled(TRUE);
  481.         break;
  482.  
  483.       case 1:
  484.         STAled(TRUE);
  485.         break;
  486.  
  487.      }
  488.    }
  489.  }
  490.  
  491. /*---------------------------------------------------------------------------*/
  492. VOID    ccpsys()        /* SYSOP Befehl                     */
  493.   {
  494.   unsigned num;            /* Zufallszahl fuer Zeichenauswahl         */
  495.   unsigned cnt;            /* Scratch Zaehler                 */
  496.   unsigned chk;            /* Check Zaehler                 */
  497.   mhtyp       *bufpoi;        /* Buffer fuer Passwort-Zahlen             */
  498.  
  499.   if (paswle != 0)                /* ohne Passwort kein Sysop  */
  500.    {
  501.     bufpoi = putals("");            /* Buffer besorgen         */
  502.     for (cnt = 0; cnt < 5; ++cnt)        /* 5 Zahlen ausgeben         */
  503.      {
  504.       do
  505.        {
  506.         do;
  507.         while (((num = random()) >= paswle)    /* Zufallszahl holen         */
  508.           || (paswrd[num] == ' '));        /* gueltiges Zeichen?         */
  509.         for (chk = 0; chk < cnt; ++chk)        /* keine Zahl doppelt         */
  510.          {
  511.           if ((userpo->paswrd[chk] & 0xff) == num) break;
  512.          }
  513.        }
  514.       while (cnt != chk);
  515.       userpo->paswrd[cnt] = num; /* neue Zahl merken                 */
  516.       putchr(' ', bufpoi);
  517.       putnum(num +1, bufpoi);    /* dem User mitteilen                 */
  518.      }
  519.     seteom(bufpoi);        /* Ende Kennung anhaengen             */
  520.     userpo->status = 3;        /* neuer Status: Passwort soll kommen         */
  521.    }
  522.   }
  523.  
  524. /*---------------------------------------------------------------------------*/
  525. VOID    ccpuse()        /* USERS Befehl                     */
  526.   {
  527.   unsigned cnt;            /* Scratch Zaehler                 */
  528.   mhtyp       *bufpoi;        /* MBHD fuer Meldungen                 */
  529.   usrtyp   *userp;        /* Userkontrollblock fuer CCP User         */
  530.   l2ltyp   *ucblk;        /* L2 User Kontrollblock             */
  531.  
  532.   bufpoi = putals(signon);            /* Kopf                 */
  533.   putnum(nmbfre, bufpoi);            /* freie Buffer             */
  534.   putchr(')', bufpoi);
  535.  
  536.                         /* erst die User mit Partner */
  537.   for (cnt = 0, ptcrdp = ptcrdl;        /* Patchcord Liste absuchen  */
  538.       cnt < ((NUMPAT +1) /2);
  539.       ++cnt, ptcrdp += 2)            /* nur "linke" Eintraege     */
  540.    {
  541.     if (ptcrdp->luserl != NULL)                /* Eintrag belegt?   */
  542.      {
  543.       putchr('\015', bufpoi);
  544.       bufpoi->l4time = bufpoi->putcnt;        /* Zeichen im Buffer merken  */
  545.       putuse('L', ptcrdp->luserl, ptcrdp->lusert, bufpoi); /* linke Seite    */
  546.       putspa(35, bufpoi);            /* Leerzeichen als Trennung  */
  547.       putstr("  <-->  ", bufpoi);        /* Verbindung steht         */
  548.       putuse('R', (ptcrdp +1)->luserl, (ptcrdp +1)->lusert, bufpoi);
  549.                         /* rechte Seite             */
  550.      }
  551.    }
  552.   for (userp = (usrtyp *) usccpl.lnext;        /* nun die User am CCP         */
  553.        (usrtyp *) &usccpl != userp;        /* bis zum Ende der Liste    */
  554.        userp = userp->unext)
  555.    {
  556.     putchr('\15', bufpoi);            /* neue Zeile je User         */
  557.     bufpoi->l4time = bufpoi->putcnt;        /* Zeichen im Buffer merken  */
  558.     putuse('L', userp->cblk_u, userp->typ_u, bufpoi); /* immer links         */
  559.     if (userp->status == 2)            /* Connect laeuft?         */
  560.      {
  561.       putspa(35, bufpoi);            /* Trennung             */
  562.       putstr("  <..>  ", bufpoi);        /* Verbindung wartet         */
  563.       if ((userp->typ_p == 2)            /* wird L2 Verbindung?         */
  564.         &&((ucblk = userp->cblk_p)->state == 0)) /* Status: connect laeuft   */
  565.        {
  566.         putstr("CQ(", bufpoi);            /* Partner ist "CQ"         */
  567.         putid(ucblk->srcid, bufpoi);
  568.         putchr(')', bufpoi);
  569.        }
  570.       else                    /* andere L2 Verbindung         */
  571.         putuse('R', userp->cblk_p, userp->typ_p, bufpoi);
  572.      }
  573.    }
  574.   seteom(bufpoi);                /* Ende der Meldung setzen   */
  575.   }
  576.  
  577. /*--- Ende Level7B ----------------------------------------------------------*/
  578.