Annotation of sbbs/sbbs3/qwknodes.c, revision 1.1

1.1     ! root        1: /* QWKNODES.C */
        !             2: 
        !             3: /* Synchronet QWKnet node list or route.dat file generator */
        !             4: 
        !             5: /* $Id: qwknodes.c,v 1.3 2000/11/04 12:03:51 rswindell Exp $ */
        !             6: 
        !             7: /****************************************************************************
        !             8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !            10:  *                                                                                                                                                     *
        !            11:  * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            12:  *                                                                                                                                                     *
        !            13:  * This program is free software; you can redistribute it and/or                       *
        !            14:  * modify it under the terms of the GNU General Public License                         *
        !            15:  * as published by the Free Software Foundation; either version 2                      *
        !            16:  * of the License, or (at your option) any later version.                                      *
        !            17:  * See the GNU General Public License for more details: gpl.txt or                     *
        !            18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
        !            19:  *                                                                                                                                                     *
        !            20:  * Anonymous FTP access to the most recent released source is available at     *
        !            21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            22:  *                                                                                                                                                     *
        !            23:  * Anonymous CVS access to the development source and modification history     *
        !            24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            26:  *     (just hit return, no password is necessary)                                                     *
        !            27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            28:  *                                                                                                                                                     *
        !            29:  * For Synchronet coding style and modification guidelines, see                                *
        !            30:  * http://www.synchro.net/source.html                                                                          *
        !            31:  *                                                                                                                                                     *
        !            32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            33:  * format) via e-mail to [email protected]                                                                      *
        !            34:  *                                                                                                                                                     *
        !            35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            36:  ****************************************************************************/
        !            37: 
        !            38: #include "sbbs.h"
        !            39: #include "crc32.h"
        !            40: 
        !            41: unsigned _stklen=10000;
        !            42: smb_t          smb;
        !            43: scfg_t         cfg;
        !            44: 
        !            45: /****************************************************************************/
        !            46: /* Updates 16-bit "rcrc" with character 'ch'                                */
        !            47: /****************************************************************************/
        !            48: void ucrc16(uchar ch, ushort *rcrc) {
        !            49:        ushort i, cy;
        !            50:     uchar nch=ch;
        !            51:  
        !            52: for (i=0; i<8; i++) {
        !            53:     cy=*rcrc & 0x8000;
        !            54:     *rcrc<<=1;
        !            55:     if (nch & 0x80) *rcrc |= 1;
        !            56:     nch<<=1;
        !            57:     if (cy) *rcrc ^= 0x1021; }
        !            58: }
        !            59: 
        !            60: /****************************************************************************/
        !            61: /* Returns 16-crc of string (not counting terminating NULL)                            */
        !            62: /****************************************************************************/
        !            63: ushort crc16(char *str)
        !            64: {
        !            65:        int     i=0;
        !            66:        ushort  crc=0;
        !            67: 
        !            68: ucrc16(0,&crc);
        !            69: while(str[i])
        !            70:        ucrc16(str[i++],&crc);
        !            71: ucrc16(0,&crc);
        !            72: ucrc16(0,&crc);
        !            73: return(crc);
        !            74: }
        !            75: 
        !            76: /****************************************************************************/
        !            77: /* Returns 32-crc of string (not counting terminating NULL)                            */
        !            78: /****************************************************************************/
        !            79: ulong _crc32(char *str)
        !            80: {
        !            81:        int i=0;
        !            82:        ulong crc=0xffffffffUL;
        !            83: 
        !            84:        while(str[i])
        !            85:                crc=ucrc32(str[i++],crc);
        !            86:        crc=~crc;
        !            87:        return(crc);
        !            88: }
        !            89: 
        !            90: #if 0
        !            91: /****************************************************************************/
        !            92: /* Converts unix time format (long - time_t) into a char str MM/DD/YY          */
        !            93: /****************************************************************************/
        !            94: char *unixtodstr(time_t unix, char *str)
        !            95: {
        !            96:        struct date date;
        !            97:        struct time curtime;
        !            98: 
        !            99: if(!unix)
        !           100:        strcpy(str,"00/00/00");
        !           101: else {
        !           102:        unixtodos(unix,&date,&curtime);
        !           103:        if((unsigned)date.da_mon>12) {    /* DOS leap year bug */
        !           104:                date.da_mon=1;
        !           105:                date.da_year++; }
        !           106:        if((unsigned)date.da_day>31)
        !           107:                date.da_day=1;
        !           108:        if(sys_misc&SM_EURODATE)
        !           109:                sprintf(str,"%02u/%02u/%02u",date.da_day,date.da_mon
        !           110:                        ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900);
        !           111:        else
        !           112:                sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day
        !           113:                        ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); }
        !           114: return(str);
        !           115: }
        !           116: #else
        !           117: /****************************************************************************/
        !           118: /* Converts unix time format (long - time_t) into a char str MM/DD/YY          */
        !           119: /****************************************************************************/
        !           120: char * unixtodstr(time_t unix, char *str)
        !           121: {
        !           122:        struct tm* tm;
        !           123: 
        !           124: if(!unix)
        !           125:        strcpy(str,"00/00/00");
        !           126: else {
        !           127:        tm=gmtime(&unix);
        !           128:        if(tm==NULL) {
        !           129:                strcpy(str,"00/00/00");
        !           130:                return(str);
        !           131:        }
        !           132:        if(tm->tm_mon>11) {       /* DOS leap year bug */
        !           133:                tm->tm_mon=0;
        !           134:                tm->tm_year++; }
        !           135:        if(tm->tm_mday>31)
        !           136:                tm->tm_mday=1;
        !           137:        if(cfg.sys_misc&SM_EURODATE)
        !           138:                sprintf(str,"%02u/%02u/%02u",tm->tm_mday,tm->tm_mon+1
        !           139:                        ,TM_YEAR(tm->tm_year));
        !           140:        else
        !           141:                sprintf(str,"%02u/%02u/%02u",tm->tm_mon+1,tm->tm_mday
        !           142:                        ,TM_YEAR(tm->tm_year)); }
        !           143: return(str);
        !           144: }
        !           145: #endif
        !           146: 
        !           147: /****************************************************************************/
        !           148: /* Puts a backslash on path strings                                                                            */
        !           149: /****************************************************************************/
        !           150: void backslash(char *str)
        !           151: {
        !           152:     int i;
        !           153: 
        !           154: i=strlen(str);
        !           155: if(i && str[i-1]!='\\') {
        !           156:     str[i]='\\'; str[i+1]=0; }
        !           157: }
        !           158: /****************************************************************************/
        !           159: /* Network open function. Opens all files DENYALL and retries LOOP_NOPEN    */
        !           160: /* number of times if the attempted file is already open or denying access     */
        !           161: /* for some other reason.      All files are opened in BINARY mode.                    */
        !           162: /****************************************************************************/
        !           163: int nopen(char *str, int access)
        !           164: {
        !           165:        int file,share,count=0;
        !           166: 
        !           167: if(access==O_RDONLY) share=SH_DENYWR;
        !           168:        else share=SH_DENYRW;
        !           169: while(((file=sopen(str,O_BINARY|access,share,S_IWRITE))==-1)
        !           170:        && errno==EACCES && count++<LOOP_NOPEN);
        !           171: if(file==-1 && errno==EACCES)
        !           172:        lputs("\7\r\nNOPEN: ACCESS DENIED\r\n\7");
        !           173: return(file);
        !           174: }
        !           175: /****************************************************************************/
        !           176: /* This function performs an nopen, but returns a file stream with a buffer */
        !           177: /* allocated.                                                                                                                          */
        !           178: /****************************************************************************/
        !           179: FILE *fnopen(int *file, char *str, int access)
        !           180: {
        !           181:        char mode[128];
        !           182:        FILE *stream;
        !           183: 
        !           184: if(((*file)=nopen(str,access))==-1)
        !           185:        return(NULL);
        !           186: 
        !           187: if(access&O_APPEND) {
        !           188:        if(access&O_RDONLY)
        !           189:                strcpy(mode,"a+");
        !           190:        else
        !           191:                strcpy(mode,"a"); }
        !           192: else {
        !           193:        if(access&O_WRONLY)
        !           194:                strcpy(mode,"r+");
        !           195:        else
        !           196:                strcpy(mode,"r"); }
        !           197: stream=fdopen((*file),mode);
        !           198: if(stream==NULL) {
        !           199:        close(*file);
        !           200:        return(NULL); }
        !           201: setvbuf(stream,NULL,_IOFBF,16*1024);
        !           202: return(stream);
        !           203: }
        !           204: 
        !           205: /****************************************************************************/
        !           206: /* Truncates white-space chars off end of 'str' and terminates at first tab */
        !           207: /****************************************************************************/
        !           208: void truncsp(char *str)
        !           209: {
        !           210:        uchar c;
        !           211: 
        !           212: c=strlen(str);
        !           213: while(c && (uchar)str[c-1]<=SP) c--;
        !           214: str[c]=0;
        !           215: }
        !           216: 
        !           217: void stripctrla(uchar *str)
        !           218: {
        !           219:        uchar out[256];
        !           220:        int i,j;
        !           221: 
        !           222: for(i=j=0;str[i];i++) {
        !           223:        if(str[i]==1)
        !           224:                i++;
        !           225:        else
        !           226:                out[j++]=str[i]; }
        !           227: out[j]=0;
        !           228: strcpy(str,out);
        !           229: }
        !           230: 
        !           231: 
        !           232: long lputs(char FAR16 *str)
        !           233: {
        !           234:     char tmp[256];
        !           235:     int i,j,k;
        !           236: 
        !           237: j=strlen(str);
        !           238: for(i=k=0;i<j;i++)      /* remove CRs */
        !           239:     if(str[i]==CR && str[i+1]==LF)
        !           240:         continue;
        !           241:     else
        !           242:         tmp[k++]=str[i];
        !           243: tmp[k]=0;
        !           244: return(fputs(tmp,stderr));
        !           245: }
        !           246: /****************************************************************************/
        !           247: /* Performs printf() through local assembly routines                        */
        !           248: /* Called from everywhere                                                   */
        !           249: /****************************************************************************/
        !           250: int lprintf(char *fmat, ...)
        !           251: {
        !           252:        va_list argptr;
        !           253:        char sbuf[256];
        !           254:        int chcount;
        !           255: 
        !           256: va_start(argptr,fmat);
        !           257: chcount=vsprintf(sbuf,fmat,argptr);
        !           258: va_end(argptr);
        !           259: lputs(sbuf);
        !           260: return(chcount);
        !           261: }
        !           262: void bail(int code)
        !           263: {
        !           264: exit(code);
        !           265: }
        !           266: 
        !           267: 
        !           268: char *loadmsgtail(smbmsg_t msg)
        !           269: {
        !           270:        char    *buf=NULL;
        !           271:        ushort  xlat;
        !           272:        int     i;
        !           273:        long    l=0,length;
        !           274: 
        !           275: for(i=0;i<msg.hdr.total_dfields;i++) {
        !           276:        if(msg.dfield[i].type!=TEXT_TAIL)
        !           277:                continue;
        !           278:        fseek(smb.sdt_fp,msg.hdr.offset+msg.dfield[i].offset
        !           279:                ,SEEK_SET);
        !           280:        fread(&xlat,2,1,smb.sdt_fp);
        !           281:        if(xlat!=XLAT_NONE)             /* no translations supported */
        !           282:                continue;
        !           283:        length=msg.dfield[i].length-2;
        !           284:        if((buf=REALLOC(buf,l+msg.dfield[i].length+1))==NULL)
        !           285:                return(buf);
        !           286:        l+=fread(buf+l,1,length,smb.sdt_fp);
        !           287:        buf[l]=0; }
        !           288: return(buf);
        !           289: }
        !           290: 
        !           291: 
        !           292: void gettag(smbmsg_t msg, char *tag)
        !           293: {
        !           294:        char *buf,*p;
        !           295: 
        !           296: tag[0]=0;
        !           297: buf=loadmsgtail(msg);
        !           298: if(buf==NULL)
        !           299:        return;
        !           300: truncsp(buf);
        !           301: stripctrla(buf);
        !           302: p=strrchr(buf,LF);
        !           303: if(!p) p=buf;
        !           304: else p++;
        !           305: if(!strnicmp(p," � Synchronet � ",16))
        !           306:        p+=16;
        !           307: if(!strnicmp(p," * Synchronet * ",16))
        !           308:     p+=16;
        !           309: while(*p && *p<=SP) p++;
        !           310: strcpy(tag,p);
        !           311: FREE(buf);
        !           312: }
        !           313: 
        !           314: 
        !           315: #define FEED   (1<<0)
        !           316: #define LOCAL  (1<<1)
        !           317: #define APPEND (1<<2)
        !           318: #define TAGS   (1<<3)
        !           319: 
        !           320: #define ROUTE  (1<<1)
        !           321: #define NODES  (1<<2)
        !           322: #define USERS  (1<<3)
        !           323: 
        !           324: char *usage="\nusage: qwknodes [/opts] cmds"
        !           325:                        "\n"
        !           326:                        "\n cmds: r  =  create route.dat"
        !           327:                        "\n       u  =  create users.dat"
        !           328:                        "\n       n  =  create nodes.dat
        !           329:                        "\n"
        !           330:                        "\n opts: f  =  format addresses for nodes that feed from this system"
        !           331:                        "\n       a  =  append existing output files"
        !           332:                        "\n       t  =  include tag lines in nodes.dat
        !           333:                        "\n       l  =  include local users in users.dat
        !           334:                        "\n       m# =  maximum message age set to # days"
        !           335:                        "\n";
        !           336: 
        !           337: void main(int argc, char **argv)
        !           338: {
        !           339:        char                    str[256],tmp[128],tag[256],addr[256],*p;
        !           340:        int                     i,j,mode=0,cmd=0,o_mode,max_age=0;
        !           341:        ushort                  smm,sbl;
        !           342:        ulong                   *crc=NULL,curcrc,total_crcs=0,l;
        !           343:        FILE                    *route,*users,*nodes;
        !           344:        time_t                  now;
        !           345:        read_cfg_text_t txt;
        !           346:        smbmsg_t                msg;
        !           347: 
        !           348: txt.openerr="\7\r\nError opening %s for read.\r\n";
        !           349: txt.reading="\r\nReading %s...";
        !           350: txt.readit="\rRead %s       ";
        !           351: txt.allocerr="\7\r\nError allocating %u bytes of memory\r\n";
        !           352: txt.error="\7\r\nERROR: Offset %lu in %s\r\n\r\n";
        !           353: 
        !           354: fprintf(stderr,"\nSynchronet QWKnet Node/Route/User List  v1.20  "
        !           355:        "Copyright 2000 Rob Swindell\n");
        !           356: 
        !           357: 
        !           358: for(i=1;i<argc;i++)
        !           359:        for(j=0;argv[i][j];j++)
        !           360:                switch(toupper(argv[i][j])) {
        !           361:                        case '/':
        !           362:                        case '-':
        !           363:                                while(argv[i][++j])
        !           364:                                        switch(toupper(argv[i][j])) {
        !           365:                                                case 'F':
        !           366:                                                        mode|=FEED;
        !           367:                                                        break;
        !           368:                                                case 'L':
        !           369:                                                        mode|=LOCAL;
        !           370:                                                        break;
        !           371:                                                case 'A':
        !           372:                                                        mode|=APPEND;
        !           373:                                                        break;
        !           374:                                                case 'T':
        !           375:                                                        mode|=TAGS;
        !           376:                                                        break;
        !           377:                                                case 'M':
        !           378:                                                        j++;
        !           379:                                                        max_age=atoi(argv[i]+j);
        !           380:                                                        while(isdigit(argv[i][j+1])) j++;
        !           381:                                                        break;
        !           382:                                                default:
        !           383:                                                        printf(usage);
        !           384:                                                        exit(1); }
        !           385:                                j--;
        !           386:                                break;
        !           387:                        case 'R':
        !           388:                                cmd|=ROUTE;
        !           389:                                break;
        !           390:                        case 'U':
        !           391:                                cmd|=USERS;
        !           392:                                break;
        !           393:                        case 'N':
        !           394:                                cmd|=NODES;
        !           395:                                break;
        !           396:                        default:
        !           397:                                printf(usage);
        !           398:                                exit(1); }
        !           399: 
        !           400: if(!cmd) {
        !           401:        printf(usage);
        !           402:        exit(1); }
        !           403: 
        !           404: if(mode&APPEND)
        !           405:        o_mode=O_WRONLY|O_CREAT|O_APPEND;
        !           406: else
        !           407:        o_mode=O_WRONLY|O_CREAT|O_TRUNC;
        !           408: 
        !           409: if(cmd&NODES)
        !           410:        if((nodes=fnopen(&i,"nodes.dat",o_mode))==NULL) {
        !           411:                printf("\7\nError opening nodes.dat\n");
        !           412:                exit(1); }
        !           413: 
        !           414: if(cmd&USERS)
        !           415:        if((users=fnopen(&i,"users.dat",o_mode))==NULL) {
        !           416:                printf("\7\nError opening users.dat\n");
        !           417:         exit(1); }
        !           418: 
        !           419: if(cmd&ROUTE)
        !           420:        if((route=fnopen(&i,"route.dat",o_mode))==NULL) {
        !           421:                printf("\7\nError opening route.dat\n");
        !           422:         exit(1); }
        !           423: 
        !           424: if(!node_dir[0]) {
        !           425:        p=getenv("SBBSNODE");
        !           426:        if(p==NULL) {
        !           427:                printf("\7\nSBBSNODE environment variable not set.\n");
        !           428:                exit(1); }
        !           429:        strcpy(node_dir,p); }
        !           430: 
        !           431: if(node_dir[strlen(node_dir)-1]!='\\')
        !           432:        strcat(node_dir,"\\");
        !           433: 
        !           434: read_node_cfg(&cfg,txt);
        !           435: if(ctrl_dir[0]=='.') {   /* Relative path */
        !           436:        strcpy(str,ctrl_dir);
        !           437:        sprintf(ctrl_dir,"%s%s",node_dir,str);
        !           438:        if(_fullpath(str,ctrl_dir,40))
        !           439:                strcpy(ctrl_dir,str); }
        !           440: backslash(ctrl_dir);
        !           441: 
        !           442: read_main_cfg(&cfg,txt);
        !           443: if(data_dir[0]=='.') {   /* Relative path */
        !           444:        strcpy(str,data_dir);
        !           445:        sprintf(data_dir,"%s%s",node_dir,str);
        !           446:        if(_fullpath(str,data_dir,40))
        !           447:                strcpy(data_dir,str); }
        !           448: backslash(data_dir);
        !           449: read_msgs_cfg(txt);
        !           450: 
        !           451: now=time(NULL);
        !           452: smm=crc16("smm");
        !           453: sbl=crc16("sbl");
        !           454: fprintf(stderr,"\n\n");
        !           455: for(i=0;i<total_subs;i++) {
        !           456:        if(!(sub[i]->misc&SUB_QNET))
        !           457:                continue;
        !           458:        fprintf(stderr,"%-*s  %s\n"
        !           459:                ,LEN_GSNAME,grp[sub[i]->grp]->sname,sub[i]->lname);
        !           460:        sprintf(smb.file,"%s%s",sub[i]->data_dir,sub[i]->code);
        !           461:        smb.retry_time=30;
        !           462:        if((j=smb_open(&smb))!=0) {
        !           463:                printf("smb_open returned %d\n",j);
        !           464:                continue; }
        !           465:        if((j=smb_locksmbhdr(&smb))!=0) {
        !           466:                printf("smb_locksmbhdr returned %d\n",j);
        !           467:                smb_close(&smb);
        !           468:                continue; }
        !           469:        if((j=smb_getstatus(&smb))!=0) {
        !           470:                printf("smb_getstatus returned %d\n",j);
        !           471:                smb_close(&smb);
        !           472:                continue; }
        !           473:        smb_unlocksmbhdr(&smb);
        !           474:        msg.offset=smb.status.total_msgs;
        !           475:        if(!msg.offset) {
        !           476:                smb_close(&smb);
        !           477:                printf("Empty.\n");
        !           478:                continue; }
        !           479:        while(!kbhit() && !ferror(smb.sid_fp) && msg.offset) {
        !           480:                msg.offset--;
        !           481:                fseek(smb.sid_fp,msg.offset*sizeof(idxrec_t),SEEK_SET);
        !           482:                if(!fread(&msg.idx,1,sizeof(idxrec_t),smb.sid_fp))
        !           483:                        break;
        !           484:                fprintf(stderr,"%-5lu\r",msg.offset+1);
        !           485:                if(msg.idx.to==smm || msg.idx.to==sbl)
        !           486:                        continue;
        !           487:                if(max_age && now-msg.idx.time>((ulong)max_age*24UL*60UL*60UL))
        !           488:                        continue;
        !           489:                if((j=smb_lockmsghdr(&smb,&msg))!=0) {
        !           490:                        printf("smb_lockmsghdr returned %d\n",j);
        !           491:                        break; }
        !           492:                if((j=smb_getmsghdr(&smb,&msg))!=0) {
        !           493:                        printf("smb_getmsghdr returned %d\n",j);
        !           494:             break; }
        !           495:                smb_unlockmsghdr(&smb,&msg);
        !           496:                if((mode&LOCAL && msg.from_net.type==NET_NONE)
        !           497:                        || msg.from_net.type==NET_QWK) {
        !           498:                        if(msg.from_net.type!=NET_QWK)
        !           499:                                msg.from_net.addr="";
        !           500:                        if(cmd&USERS) {
        !           501:                                sprintf(str,"%s%s",msg.from_net.addr,msg.from);
        !           502:                                curcrc=crc32(str); }
        !           503:                        else
        !           504:                                curcrc=crc32(msg.from_net.addr);
        !           505:                        for(l=0;l<total_crcs;l++)
        !           506:                                if(curcrc==crc[l])
        !           507:                                        break;
        !           508:                        if(l==total_crcs) {
        !           509:                                total_crcs++;
        !           510:                                if((crc=(ulong *)REALLOC(crc
        !           511:                                        ,sizeof(ulong)*total_crcs))==NULL) {
        !           512:                                        printf("Error allocating %lu bytes\n"
        !           513:                                                ,sizeof(ulong)*total_crcs);
        !           514:                                        break; }
        !           515:                                crc[l]=curcrc;
        !           516:                                if(cmd&ROUTE && msg.from_net.type==NET_QWK) {
        !           517:                                        strcpy(addr,msg.from_net.addr);
        !           518:                                        if(mode&FEED) {
        !           519:                                                p=strrchr(addr,'/');
        !           520:                                                if(!p)
        !           521:                                                        p=addr;
        !           522:                                                else
        !           523:                                                        *(p++)=0;
        !           524:                                                sprintf(str,"%s %s:%s%c%s"
        !           525:                                                        ,unixtodstr(msg.hdr.when_written.time,tmp)
        !           526:                                                        ,p,sys_id,p==addr ? 0 : '/'
        !           527:                                                        ,addr);
        !           528:                                                fprintf(route,"%s\r\n",str); }
        !           529:                                        else {
        !           530:                                                p=strrchr(addr,'/');
        !           531:                                                if(p) {
        !           532:                                                        *(p++)=0;
        !           533:                                                fprintf(route,"%s %s:%.*s\r\n"
        !           534:                                                        ,unixtodstr(msg.hdr.when_written.time,str)
        !           535:                                                        ,p
        !           536:                                                        ,(uint)(p-addr)
        !           537:                                                        ,addr); } } }
        !           538:                                if(cmd&USERS) {
        !           539:                                        if(msg.from_net.type!=NET_QWK)
        !           540:                                                strcpy(str,sys_id);
        !           541:                                        else if(mode&FEED)
        !           542:                                                sprintf(str,"%s/%s",sys_id,msg.from_net.addr);
        !           543:                                        else
        !           544:                                                strcpy(str,msg.from_net.addr);
        !           545:                                        p=strrchr(str,'/');
        !           546:                     if(p)
        !           547:                                                fprintf(users,"%-25.25s  %-8.8s  %s  (%s)\r\n"
        !           548:                                                        ,msg.from,p+1
        !           549:                                                        ,unixtodstr(msg.hdr.when_written.time,tmp)
        !           550:                                                        ,str);
        !           551:                                        else
        !           552:                                                fprintf(users,"%-25.25s  %-8.8s  %s\r\n"
        !           553:                                                        ,msg.from,str
        !           554:                                                        ,unixtodstr(msg.hdr.when_written.time,tmp)); }
        !           555:                                if(cmd&NODES && msg.from_net.type==NET_QWK) {
        !           556:                                        if(mode&TAGS)
        !           557:                                                gettag(msg,tag);
        !           558:                                        if(mode&FEED)
        !           559:                                                sprintf(str,"%s/%s",sys_id,msg.from_net.addr);
        !           560:                                        else
        !           561:                                                strcpy(str,msg.from_net.addr);
        !           562:                                        p=strrchr(str,'/');
        !           563:                                        if(p) {
        !           564:                                                if(mode&TAGS)
        !           565:                                                        fprintf(nodes,"%-8.8s  %s\r\n"
        !           566:                                                                ,p+1
        !           567:                                                                ,tag);
        !           568:                                                else
        !           569:                                                        fprintf(nodes,"%-8.8s  %s  (%s)\r\n"
        !           570:                                                                ,p+1
        !           571:                                                                ,unixtodstr(msg.hdr.when_written.time,tmp)
        !           572:                                                                ,str); }
        !           573:                                        else
        !           574:                                                fprintf(nodes,"%-8.8s  %s\r\n"
        !           575:                                                        ,str
        !           576:                                                        ,mode&TAGS
        !           577:                                                        ? tag
        !           578:                                                        : unixtodstr(msg.hdr.when_written.time,tmp)); }
        !           579:                                } }
        !           580:                smb_freemsgmem(&msg); }
        !           581: 
        !           582:        smb_close(&smb);
        !           583:        if(kbhit()) {
        !           584:                getch();
        !           585:                fprintf(stderr,"Key pressed.\n");
        !           586:                break; } }
        !           587: fprintf(stderr,"Done.\n");
        !           588: }
        !           589: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.