Annotation of sbbs/sbbs3/qwknodes.c, revision 1.1.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.