Annotation of sbbs/sbbs3/tmp_xfer.cpp, revision 1.1

1.1     ! root        1: /* tmp_xfer.cpp */
        !             2: 
        !             3: /* Synchronet temp directory file transfer routines */
        !             4: 
        !             5: /* $Id: tmp_xfer.cpp,v 1.8 2000/12/11 23:21:12 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: 
        !            40: /*****************************************************************************/
        !            41: /* Temp directory section. Files must be extracted here and both temp_uler   */
        !            42: /* and temp_uler fields should be filled before entrance.                    */
        !            43: /*****************************************************************************/
        !            44: void sbbs_t::temp_xfer()
        !            45: {
        !            46:     char       str[256],tmp2[256],done=0,ch;
        !            47:        char    tmp[512];
        !            48:     uint       i,dirnum=cfg.total_dirs,j,files;
        !            49:     ulong      bytes;
        !            50:        ulong   space;
        !            51:     time_t     start,end,t;
        !            52:     file_t     f;
        !            53:        glob_t  g;
        !            54:        struct  tm * tm;
        !            55: 
        !            56:        if(!usrlibs)
        !            57:                return;
        !            58:        if(useron.rest&FLAG('D')) {
        !            59:                bputs(text[R_Download]);
        !            60:                return; }
        !            61:        /*************************************/
        !            62:        /* Create TEMP directory information */
        !            63:        /*************************************/
        !            64:        if((cfg.dir[dirnum]=(dir_t *)MALLOC(sizeof(dir_t)))==0) {
        !            65:                errormsg(WHERE,ERR_ALLOC,"temp_dir",sizeof(dir_t));
        !            66:                return; }
        !            67:        memset(cfg.dir[dirnum],0,sizeof(dir_t));
        !            68:        cfg.dir[dirnum]->lname="Temporary";
        !            69:        cfg.dir[dirnum]->sname="Temp";
        !            70:        strcpy(cfg.dir[dirnum]->code,"TEMP");
        !            71:        cfg.dir[dirnum]->path=cfg.temp_dir;
        !            72:        cfg.dir[dirnum]->maxfiles=MAX_FILES;
        !            73:        cfg.dir[dirnum]->data_dir=cfg.dir[0]->data_dir;
        !            74:        cfg.dir[dirnum]->op_ar=(uchar *)nulstr;
        !            75:        temp_dirnum=curdirnum=usrdir[curlib][curdir[curlib]];
        !            76:        cfg.total_dirs++;
        !            77: 
        !            78:        /****************************/
        !            79:        /* Fill filedat information */
        !            80:        /****************************/
        !            81:        memset(&f,0,sizeof(f));
        !            82:        sprintf(f.name,"temp_%3.3d.%s",cfg.node_num,useron.tmpext);
        !            83:        strcpy(f.desc,"Temp File");
        !            84:        f.dir=dirnum;
        !            85: 
        !            86:        if(useron.misc&(RIP|WIP) && !(useron.misc&EXPERT))
        !            87:                menu("tempxfer");
        !            88:        lncntr=0;
        !            89:        while(online && !done) {
        !            90:                if(!(useron.misc&(EXPERT|RIP|WIP))) {
        !            91:                        sys_status&=~SS_ABORT;
        !            92:                        if(lncntr) {
        !            93:                                SYNC;
        !            94:                                CRLF;
        !            95:                                if(lncntr)          /* CRLF or SYNC can cause pause */
        !            96:                                        pause(); }
        !            97:                        menu("tempxfer"); }
        !            98:                ASYNC;
        !            99:                bputs(text[TempDirPrompt]);
        !           100:                strcpy(f.uler,temp_uler);
        !           101:                ch=(char)getkeys("ADEFNILQRVX?\r",0);
        !           102:                if(ch>SP)
        !           103:                        logch(ch,0);
        !           104:                switch(ch) {
        !           105:                        case 'A':   /* add to temp file */
        !           106:                                /* free disk space */
        !           107:                                space=getfreediskspace(cfg.temp_dir);
        !           108:                                if(space<(ulong)cfg.min_dspace*1024L) {
        !           109:                                        bputs(text[LowDiskSpace]);
        !           110:                                        sprintf(str,"Diskspace is low: %s (%lu bytes)"
        !           111:                                                ,cfg.temp_dir,space);
        !           112:                                        errorlog(str);
        !           113:                                        if(!dir_op(dirnum))
        !           114:                                                break; }
        !           115:                                bprintf(text[DiskNBytesFree],ultoac(space,tmp));
        !           116:                                if(!getfilespec(str))
        !           117:                                        break;
        !           118:                                if(!checkfname(str))
        !           119:                                        break;
        !           120:                                sprintf(tmp2,"Added %s to %s",str,f.name);
        !           121:                                logline(nulstr,tmp2);
        !           122:                                sprintf(tmp2,"%s%s",cfg.temp_dir,str);
        !           123:                                sprintf(str,"%s%s",cfg.temp_dir,f.name);
        !           124:                                external(cmdstr(temp_cmd(),str,tmp2,NULL),EX_CC|EX_OUTL|EX_OUTR);
        !           125:                                break;
        !           126:                        case 'D':   /* download from temp dir */
        !           127:                                sprintf(str,"%s%s",cfg.temp_dir,f.name);
        !           128:                                if(!fexist(str)) {
        !           129:                                        bprintf(text[TempFileNotCreatedYet],f.name);
        !           130:                                        break; }
        !           131:                                f.size=f.cdt=flength(str);
        !           132:                                f.opencount=0;
        !           133:                                if(temp_cdt)    /* if file was not free */
        !           134:                                        f.cdt=f.size;
        !           135:                                else
        !           136:                                        f.cdt=0;
        !           137:                                if(!(useron.exempt&FLAG('D'))
        !           138:                                        && f.cdt>useron.cdt+useron.freecdt) {
        !           139:                                        bprintf(text[YouOnlyHaveNCredits]
        !           140:                                                ,ultoac(useron.cdt+useron.freecdt,tmp));
        !           141:                                        break; }    /* f.cdt must equal size here */
        !           142:                                if(!(useron.exempt&FLAG('T')) && !dir_op(dirnum)
        !           143:                                        && !(cfg.dir[temp_dirnum]->misc&DIR_TFREE) && cur_cps
        !           144:                                        && f.size/(ulong)cur_cps>timeleft) {
        !           145:                                        bputs(text[NotEnoughTimeToDl]);
        !           146:                                        break; }
        !           147:                                if(!chk_ar(cfg.dir[temp_dirnum]->dl_ar,&useron)) {
        !           148:                                        bputs(text[CantDownloadFromDir]);
        !           149:                                        break; }
        !           150:                                addfiledat(&cfg,&f);
        !           151:                                menu("dlprot");
        !           152:                                SYNC;
        !           153:                                mnemonics(text[ProtocolOrQuit]);
        !           154:                                strcpy(tmp2,"Q");
        !           155:                                for(i=0;i<cfg.total_prots;i++)
        !           156:                                        if(cfg.prot[i]->dlcmd[0] && chk_ar(cfg.prot[i]->ar,&useron)) {
        !           157:                                                sprintf(tmp,"%c",cfg.prot[i]->mnemonic);
        !           158:                                                strcat(tmp2,tmp); }
        !           159:                                ungetkey(useron.prot);
        !           160:                                ch=(char)getkeys(tmp2,0);
        !           161:                                for(i=0;i<cfg.total_prots;i++)
        !           162:                                        if(cfg.prot[i]->dlcmd[0] && cfg.prot[i]->mnemonic==ch
        !           163:                                                && chk_ar(cfg.prot[i]->ar,&useron))
        !           164:                                                break;
        !           165:                                if(i<cfg.total_prots) {
        !           166:                                        getnodedat(cfg.node_num,&thisnode,1);
        !           167:                                        action=NODE_DLNG;
        !           168:                                        t=now;
        !           169:                                        if(cur_cps) 
        !           170:                                                t+=(f.size/(ulong)cur_cps);
        !           171:                                        tm=gmtime(&t);
        !           172:                                        if(tm==NULL)
        !           173:                                                break;
        !           174:                                        thisnode.aux=(tm->tm_hour*60)+tm->tm_min;
        !           175: 
        !           176:                                        putnodedat(cfg.node_num,&thisnode); /* calculate ETA */
        !           177:                                        start=time(NULL);
        !           178:                                        j=protocol(cmdstr(cfg.prot[i]->dlcmd,str,nulstr,NULL),0);
        !           179:                                        end=time(NULL);
        !           180:                                        if(cfg.dir[temp_dirnum]->misc&DIR_TFREE)
        !           181:                                                starttime+=end-start;
        !           182:                                        if(cfg.prot[i]->misc&PROT_DSZLOG) {
        !           183:                                                if(checkprotlog(&f))
        !           184:                                                        downloadfile(&f);
        !           185:                                                else
        !           186:                                                        notdownloaded(f.size,start,end); }
        !           187:                                        else {
        !           188:                                                if(!j)
        !           189:                                                        downloadfile(&f);
        !           190:                                                else {
        !           191:                                                        bprintf(text[FileNotSent],f.name);
        !           192:                                                        notdownloaded(f.size,start,end); } }
        !           193:                                        autohangup(); }
        !           194:                                removefiledat(&cfg,&f);
        !           195:                                break;
        !           196:                        case 'E':
        !           197:                                extract(usrdir[curlib][curdir[curlib]]);
        !           198:                                sys_status&=~SS_ABORT;
        !           199:                                break;
        !           200:                        case 'F':   /* Create a file list */
        !           201:                                delfiles(cfg.temp_dir,ALLFILES);
        !           202:                                create_filelist("FILELIST.TXT",0);
        !           203:                                if(!(sys_status&SS_ABORT))
        !           204:                                        logline(nulstr,"Created list of all files");
        !           205:                                CRLF;
        !           206:                                sys_status&=~SS_ABORT;
        !           207:                                break;
        !           208:                        case 'I':   /* information on what's here */
        !           209:                                bprintf(text[TempFileInfo],f.uler,temp_file);
        !           210:                                break;
        !           211:                        case 'L':   /* list files in dir */
        !           212:                                if(!getfilespec(str))
        !           213:                                        break;
        !           214:                                if(!checkfname(str))
        !           215:                                        break;
        !           216:                                bytes=files=0L;
        !           217:                                CRLF;
        !           218:                                sprintf(tmp2,"%s%s",cfg.temp_dir,str);
        !           219:                                glob(tmp2,0,NULL,&g);
        !           220:                                for(i=0;i<g.gl_pathc && !msgabort();i++) {
        !           221:                                        if(isdir(g.gl_pathv[i]))
        !           222:                                                continue;
        !           223:                                        bprintf("%s %15s\r\n",padfname(getfname(g.gl_pathv[i]),str)
        !           224:                                                ,ultoac(flength(g.gl_pathv[i]),tmp));
        !           225:                                        files++;
        !           226:                                        bytes+=flength(g.gl_pathv[i]);
        !           227:                                }
        !           228:                                globfree(&g);
        !           229:                                if(!files)
        !           230:                                        bputs(text[EmptyDir]);
        !           231:                                else if(files>1)
        !           232:                                        bprintf(text[TempDirTotal],ultoac(bytes,tmp),files);
        !           233:                                break;
        !           234:                        case 'N':   /* Create a list of new files */
        !           235:                                delfiles(cfg.temp_dir,ALLFILES);
        !           236:                                create_filelist("NEWFILES.TXT",FL_ULTIME);
        !           237:                                if(!(sys_status&SS_ABORT))
        !           238:                                        logline(nulstr,"Created list of new files");
        !           239:                                CRLF;
        !           240:                                sys_status&=~SS_ABORT;
        !           241:                                break;
        !           242:                        case 'R':   /* Remove files from dir */
        !           243:                                if(!getfilespec(str))
        !           244:                                        break;
        !           245:                                // padfname(str,tmp);  Removed 04/14/96
        !           246:                                bprintf(text[NFilesRemoved],delfiles(cfg.temp_dir,tmp));
        !           247:                                break;
        !           248:                        case 'V':   /* view files in dir */
        !           249:                                bputs(text[FileSpec]);
        !           250:                                if(!getstr(str,12,K_UPPER) || !checkfname(str))
        !           251:                                        break;
        !           252:                                viewfiles(dirnum,str);
        !           253:                                break;
        !           254:                        case CR:
        !           255:                        case 'Q':   /* quit */
        !           256:                                done=1;
        !           257:                                break;
        !           258:                        case 'X':   /* extract from archive in temp dir */
        !           259:                                extract(dirnum);
        !           260:                                sys_status&=~SS_ABORT;
        !           261:                                break;
        !           262:                        case '?':   /* menu */
        !           263:                                if(useron.misc&(EXPERT|RIP|WIP))
        !           264:                                        menu("tempxfer");
        !           265:                                break; }
        !           266:                if(sys_status&SS_ABORT)
        !           267:                        break; }
        !           268:        FREE(cfg.dir[dirnum]);
        !           269:        cfg.total_dirs--;
        !           270: }
        !           271: 
        !           272: /*****************************************************************************/
        !           273: /* Handles extraction from a normal transfer file to the temp directory      */
        !           274: /*****************************************************************************/
        !           275: void sbbs_t::extract(uint dirnum)
        !           276: {
        !           277:     char       fname[13],str[256],excmd[256],path[256],done
        !           278:                                ,tmp[256],intmp=0;
        !           279:     uint       i,j;
        !           280:        ulong   space;
        !           281:     file_t     f;
        !           282:        DIR*    dir;
        !           283:        DIRENT* dirent;
        !           284: 
        !           285:        temp_dirnum=curdirnum=dirnum;
        !           286:        if(!strcmp(cfg.dir[dirnum]->code,"TEMP"))
        !           287:                intmp=1;
        !           288: 
        !           289:        /* get free disk space */
        !           290:        space=getfreediskspace(cfg.temp_dir);
        !           291:        if(space<(ulong)cfg.min_dspace*1024L) {
        !           292:                bputs(text[LowDiskSpace]);
        !           293:                sprintf(str,"Diskspace is low: %s (%lu bytes)",cfg.temp_dir,space);
        !           294:                errorlog(str);
        !           295:                if(!dir_op(dirnum))
        !           296:                        return; }
        !           297:        else if(!intmp) {   /* not in temp dir */
        !           298:                CRLF; }
        !           299:        bprintf(text[DiskNBytesFree],ultoac(space,tmp));
        !           300: 
        !           301:        if(!intmp) {    /* not extracting FROM temp directory */
        !           302:                sprintf(str,"%s%s",cfg.temp_dir,ALLFILES);
        !           303:                if(fexist(str)) {
        !           304:                        bputs(text[RemovingTempFiles]);
        !           305:                        dir=opendir(cfg.temp_dir);
        !           306:                        while((dirent=readdir(dir))!=NULL) {
        !           307:                                sprintf(str,"%s%s",cfg.temp_dir,dirent->d_name);
        !           308:                        if(!isdir(str))
        !           309:                                        remove(str);
        !           310:                        }
        !           311:                        closedir(dir);
        !           312:                        CRLF; 
        !           313:                } 
        !           314:        }
        !           315:        bputs(text[ExtractFrom]);
        !           316:        if(!getstr(fname,12,K_UPPER) || !checkfname(fname) || strchr(fname,'*')
        !           317:                || strchr(fname,'?'))
        !           318:                return;
        !           319:        padfname(fname,f.name);
        !           320:        strcpy(str,f.name);
        !           321:        truncsp(str);
        !           322:        for(i=0;i<cfg.total_fextrs;i++)
        !           323:                if(!strcmp(str+9,cfg.fextr[i]->ext) && chk_ar(cfg.fextr[i]->ar,&useron)) {
        !           324:                        strcpy(excmd,cfg.fextr[i]->cmd);
        !           325:                        break; }
        !           326:        if(i==cfg.total_fextrs) {
        !           327:                bputs(text[UnextractableFile]);
        !           328:                return; }
        !           329:        if(!intmp && !findfile(&cfg,dirnum,f.name)) {    /* not temp dir */
        !           330:                bputs(text[SearchingAllDirs]);
        !           331:                for(i=0;i<usrdirs[curlib] && !msgabort();i++) {
        !           332:                        if(i==dirnum) continue;
        !           333:                        if(findfile(&cfg,usrdir[curlib][i],f.name))
        !           334:                                break; }
        !           335:                if(i==usrdirs[curlib]) { /* not found in cur lib */
        !           336:                        bputs(text[SearchingAllLibs]);
        !           337:                        for(i=0;i<usrlibs;i++) {
        !           338:                                if(i==curlib) continue;
        !           339:                                for(j=0;j<usrdirs[i] && !msgabort();j++)
        !           340:                                        if(findfile(&cfg,usrdir[i][j],f.name))
        !           341:                                                break;
        !           342:                                if(j<usrdirs[i])
        !           343:                                        break; }
        !           344:                        if(i==usrlibs) {
        !           345:                                bputs(text[FileNotFound]);  /* not in database */
        !           346:                                return; }
        !           347:                        dirnum=usrdir[i][j]; }
        !           348:                else
        !           349:                        dirnum=usrdir[curlib][i]; }
        !           350:        if(sys_status&SS_ABORT)
        !           351:                return;
        !           352:        sprintf(path,"%s%s",cfg.dir[dirnum]->path,fname);
        !           353:        if(!intmp) {    /* not temp dir, so get temp_file info */
        !           354:                f.datoffset=f.dateuled=f.datedled=0L;
        !           355:                f.dir=dirnum;
        !           356:                getfileixb(&cfg,&f);
        !           357:                if(!f.datoffset && !f.dateuled && !f.datedled)  /* error reading ixb */
        !           358:                        return;
        !           359:                f.size=0;
        !           360:                getfiledat(&cfg,&f);
        !           361:                fileinfo(&f);
        !           362:                if(f.altpath>0 && f.altpath<=cfg.altpaths)
        !           363:                        sprintf(path,"%s%s",cfg.altpath[f.altpath-1],fname);
        !           364:                temp_dirnum=dirnum;
        !           365:                if(cfg.dir[f.dir]->misc&DIR_FREE)
        !           366:                        temp_cdt=0L;
        !           367:                else
        !           368:                        temp_cdt=f.cdt;
        !           369:                strcpy(temp_uler,f.uler);
        !           370:                strcpy(temp_file,f.name); }     /* padded filename */
        !           371:        if(!fexist(path)) {
        !           372:                bputs(text[FileNotThere]);  /* not on disk */
        !           373:                return; }
        !           374:        done=0;
        !           375:        while(online && !done) {
        !           376:                mnemonics(text[ExtractFilesPrompt]);
        !           377:                switch(getkeys("EVQ",0)) {
        !           378:                        case 'E':
        !           379:                                if(!getfilespec(str))
        !           380:                                        break;
        !           381:                                if(!checkfname(str))
        !           382:                                        break;
        !           383:                                if((i=external(cmdstr(excmd,path,str,NULL)
        !           384:                                        ,EX_INR|EX_OUTL|EX_OUTR|EX_CC))!=0) {
        !           385:                                        errormsg(WHERE,ERR_EXEC,cmdstr(excmd,path,str,NULL),i);
        !           386:                                        return; }
        !           387:                                sprintf(tmp,"Extracted %s from %s",str,path);
        !           388:                                logline(nulstr,tmp);
        !           389:                                CRLF;
        !           390:                                break;
        !           391:                        case 'V':
        !           392:                                viewfiles(dirnum,fname);
        !           393:                                break;
        !           394:                        default:
        !           395:                                done=1;
        !           396:                                break; } }
        !           397: }
        !           398: 
        !           399: /****************************************************************************/
        !           400: /* Creates a text file named NEWFILES.DAT in the temp directory that        */
        !           401: /* all new files since p-date. Returns number of files in list.             */
        !           402: /****************************************************************************/
        !           403: ulong sbbs_t::create_filelist(char *name, long mode)
        !           404: {
        !           405:     char       str[256];
        !           406:        int             file;
        !           407:        uint    i,j,d;
        !           408:        ulong   l,k;
        !           409: 
        !           410:        bprintf(text[CreatingFileList],name);
        !           411:        sprintf(str,"%s%s",cfg.temp_dir,name);
        !           412:        if((file=nopen(str,O_CREAT|O_WRONLY|O_APPEND))==-1) {
        !           413:                errormsg(WHERE,ERR_OPEN,str,O_CREAT|O_WRONLY|O_APPEND);
        !           414:                return(0); }
        !           415:        k=0;
        !           416:        if(mode&FL_ULTIME) {
        !           417:                sprintf(str,"New files since: %s\r\n",timestr(&ns_time));
        !           418:                write(file,str,strlen(str)); }
        !           419:        for(i=d=0;i<usrlibs;i++) {
        !           420:                for(j=0;j<usrdirs[i];j++,d++) {
        !           421:                        outchar('.');
        !           422:                        if(d && !(d%5))
        !           423:                                bputs("\b\b\b\b\b     \b\b\b\b\b");
        !           424:                        if(mode&FL_ULTIME /* New-scan */
        !           425:                                && (cfg.lib[usrlib[i]]->offline_dir==usrdir[i][j]
        !           426:                                || cfg.dir[usrdir[i][j]]->misc&DIR_NOSCAN))
        !           427:                                continue;
        !           428:                        l=listfiles(usrdir[i][j],nulstr,file,mode);
        !           429:                        if((long)l==-1)
        !           430:                                break;
        !           431:                        k+=l; }
        !           432:                if(j<usrdirs[i])
        !           433:                        break; }
        !           434:        if(k>1) {
        !           435:                sprintf(str,"\r\n%d Files Listed.\r\n",k);
        !           436:                write(file,str,strlen(str)); }
        !           437:        close(file);
        !           438:        if(k)
        !           439:                bprintf(text[CreatedFileList],name);
        !           440:        else {
        !           441:                bputs(text[NoFiles]);
        !           442:                sprintf(str,"%s%s",cfg.temp_dir,name);
        !           443:                remove(str); }
        !           444:        strcpy(temp_file,name);
        !           445:        strcpy(temp_uler,"File List");
        !           446:        return(k);
        !           447: }
        !           448: 
        !           449: /****************************************************************************/
        !           450: /* This function returns the command line for the temp file extension for      */
        !           451: /* current user online.                                                                                                        */
        !           452: /****************************************************************************/
        !           453: char * sbbs_t::temp_cmd(void)
        !           454: {
        !           455:        int i;
        !           456: 
        !           457:        if(!cfg.total_fcomps) {
        !           458:                errormsg(WHERE,ERR_CHK,"compressable file types",0);
        !           459:                return(nulstr); }
        !           460:        for(i=0;i<cfg.total_fcomps;i++)
        !           461:                if(!stricmp(useron.tmpext,cfg.fcomp[i]->ext)
        !           462:                        && chk_ar(cfg.fcomp[i]->ar,&useron))
        !           463:                        return(cfg.fcomp[i]->cmd);
        !           464:        return(cfg.fcomp[0]->cmd);
        !           465: }

unix.superglobalmegacorp.com

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