Annotation of sbbs/sbbs2/sbl/sbl.c, revision 1.1

1.1     ! root        1: /* SBL.C */
        !             2: 
        !             3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
        !             4: 
        !             5: /****************************/
        !             6: /* Synchronet BBS List Door */
        !             7: /****************************/
        !             8: 
        !             9: /****************************************************************************/
        !            10: /* This source code is completely Public Domain and can be modified and        */
        !            11: /* distributed freely (as long as changes are documented).                  */
        !            12: /* It is meant as an example to programmers of how to use the XSDK                     */
        !            13: /****************************************************************************/
        !            14: 
        !            15: /***********
        !            16:  * History *
        !            17:  ***********
        !            18: 
        !            19: ******************
        !            20: * RELEASE: v1.00 *
        !            21: ******************
        !            22: 
        !            23: 07/03/93 03:16am
        !            24: Fixed bug with "Auto-deleting" already deleted entries. This would cause a
        !            25: long list of "Auto-deletion" messages once a day.
        !            26: 
        !            27: 07/03/93 03:30am
        !            28: The name of the user who last updated the entry is now stored and displayed.
        !            29: 
        !            30: 07/03/93 03:45am
        !            31: Adding/Updating entries is now much easier and user friendly.
        !            32: 
        !            33: 07/03/93 04:00am
        !            34: Added support for user "verification" of BBS entries.
        !            35: 
        !            36: 07/03/93 04:10am
        !            37: Users may now update or remove entries using partial system names.
        !            38: 
        !            39: 07/03/93 04:30am
        !            40: Sysops may now un-delete purged entries with the '*' key.
        !            41: 
        !            42: ******************
        !            43: * RELEASE: v1.10 *
        !            44: ******************
        !            45: 
        !            46: 10/18/93 06:04pm
        !            47: Fixed bug that would cause entries to be purged almost immediately.
        !            48: 
        !            49: 10/18/93 07:01pm
        !            50: (F)ind text now searches user names who last updated and verified.
        !            51: 
        !            52: 10/19/93 01:34am
        !            53: Added option for users to change the format of BBS listings.
        !            54: 
        !            55: ******************
        !            56: * RELEASE: v1.20 *
        !            57: ******************
        !            58: 
        !            59: 10/20/93 04:44pm
        !            60: Fixed cosmetic problem with opening menu (for users, not sysop).
        !            61: 
        !            62: ******************
        !            63: * RELEASE: v1.21 *
        !            64: ******************
        !            65: 
        !            66: 11/29/93 09:40pm
        !            67: More cosmetic changes. Added "Saving..." message.
        !            68: 
        !            69: ******************
        !            70: * RELEASE: v1.22 *
        !            71: ******************
        !            72: 
        !            73: 02/02/94
        !            74: Added warning for pending auto-deletion of BBS entries.
        !            75: 
        !            76: 02/02/94
        !            77: Added option for turning screen pause off/on.
        !            78: 
        !            79: 02/03/94
        !            80: Added option in SBL.CFG for sysop/co-sysop notification of changes made to
        !            81: BBS list by users.
        !            82: 
        !            83: 02/03/94
        !            84: Converted all file operations from handles to streams for buffered i/o (speed).
        !            85: 
        !            86: 02/09/94
        !            87: Added options for generating a sort index and displaying sorted list based on
        !            88: various criteria.
        !            89: 
        !            90: 02/09/94
        !            91: Added nodesync() calls to display any messages waiting for this user/node.
        !            92: 
        !            93: 02/10/94
        !            94: Added search for duplicate names when adding new BBS entries.
        !            95: 
        !            96: 02/10/94
        !            97: Notification notice of actual auto-deletion sent to author of BBS entry upon
        !            98: auto-deletion.
        !            99: 
        !           100: ******************
        !           101: * RELEASE: v1.30 *
        !           102: ******************
        !           103: 
        !           104: 03/14/94
        !           105: Added /M switch to force daily maintenance.
        !           106: 
        !           107: 03/22/94
        !           108: Fixed occasional double pause after listings.
        !           109: 
        !           110: 03/22/94
        !           111: Added total entries found to find text listings.
        !           112: 
        !           113: 03/22/94
        !           114: If a user verifies an entry, the user who created the entry is notified.
        !           115: 
        !           116: 03/29/94
        !           117: Sysop can define/change the "owner" of an entry when adding or updating.
        !           118: 
        !           119: 04/18/94
        !           120: Fixed bug in the sort-by-string functions that caused lock-ups when sorting
        !           121: more than 312 entries.
        !           122: 
        !           123: 04/18/94
        !           124: Lowered memory requirements for all sort functions.
        !           125: 
        !           126: ******************
        !           127: * RELEASE: v1.31 *
        !           128: ******************
        !           129: 
        !           130: 08/23/94
        !           131: BBS entries now know whether they were created by a user or by SMB2SBL (via
        !           132: message base).
        !           133: 
        !           134: 08/23/94
        !           135: Fixed problem with hitting Ctrl-C locally during regular (not extended)
        !           136: listing. Returning to main menu would not clear screen or have correct colors.
        !           137: 'aborted' variable is now reset in main() loop.
        !           138: 
        !           139: ******************
        !           140: * RELEASE: v1.32 *
        !           141: ******************
        !           142: 
        !           143: 08/30/94
        !           144: Fixed stack overflow that would cause periodic lock-ups on some systems.
        !           145: 
        !           146: ******************
        !           147: * RELEASE: v1.33 *
        !           148: ******************
        !           149: 
        !           150: 09/08/94
        !           151: When deleting an entry, the name of the BBS deleted wasn't being printed.
        !           152: 
        !           153: 02/01/95
        !           154: Import utility made mistake of ignoring READ messages to SBL. This has been
        !           155: fixed.
        !           156: 
        !           157: */
        !           158: 
        !           159: #include "xsdk.h"
        !           160: #include "sbldefs.h"
        !           161: 
        !           162: unsigned _stklen=16000;                  /* Set stack size in code, not header */
        !           163: 
        !           164: typedef struct {
        !           165: 
        !           166:        char    str[32];
        !           167:        short   offset;
        !           168: 
        !           169:        } sortstr_t;
        !           170: 
        !           171: typedef struct {
        !           172: 
        !           173:        long    i;
        !           174:        short   offset;
        !           175: 
        !           176:        } sortint_t;
        !           177: 
        !           178: char *nulstr="";
        !           179: char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
        !           180: char *mon[]={"Jan","Feb","Mar","Apr","May","Jun"
        !           181:             ,"Jul","Aug","Sep","Oct","Nov","Dec"};
        !           182: char tmp[256];
        !           183: char list_fmt[128];
        !           184: uint del_days,add_ml,update_ml,remove_ml,verify_ml,sbl_pause=1,notify_user;
        !           185: struct date date;
        !           186: struct time curtime;
        !           187: time_t now;
        !           188: 
        !           189: /****************************************************************************/
        !           190: /* Generates a 24 character ASCII string that represents the time_t pointer */
        !           191: /* Used as a replacement for ctime()                                                                           */
        !           192: /****************************************************************************/
        !           193: char *timestr(time_t *intime)
        !           194: {
        !           195:        static char str[256];
        !           196:     char mer[3],hour;
        !           197:     struct tm *gm;
        !           198: 
        !           199: gm=localtime(intime);
        !           200: if(gm->tm_hour>=12) {
        !           201:     if(gm->tm_hour==12)
        !           202:         hour=12;
        !           203:     else
        !           204:         hour=gm->tm_hour-12;
        !           205:     strcpy(mer,"pm"); }
        !           206: else {
        !           207:     if(gm->tm_hour==0)
        !           208:         hour=12;
        !           209:     else
        !           210:         hour=gm->tm_hour;
        !           211:     strcpy(mer,"am"); }
        !           212: sprintf(str,"%s %s %02d %4d %02d:%02d %s"
        !           213:     ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year
        !           214:     ,hour,gm->tm_min,mer);
        !           215: return(str);
        !           216: }
        !           217: 
        !           218: 
        !           219: /****************************************************************************/
        !           220: /* Converts unix time format (long - time_t) into a char str MM/DD/YY          */
        !           221: /****************************************************************************/
        !           222: char *unixtodstr(time_t unix, char *str)
        !           223: {
        !           224: 
        !           225: if(!unix)
        !           226:        strcpy(str,"00/00/00");
        !           227: else {
        !           228:        unixtodos(unix,&date,&curtime);
        !           229:        if((unsigned)date.da_mon>12) {    /* DOS leap year bug */
        !           230:                date.da_mon=1;
        !           231:                date.da_year++; }
        !           232:        if((unsigned)date.da_day>31)
        !           233:                date.da_day=1;
        !           234:        sprintf(str,"%02u/%02u/%02u",date.da_mon,date.da_day
        !           235:                ,date.da_year>=2000 ? date.da_year-2000 : date.da_year-1900); }
        !           236: return(str);
        !           237: }
        !           238: 
        !           239: 
        !           240: /****************************************************************************/
        !           241: /* Converts a date string in format MM/DD/YY into unix time format                     */
        !           242: /****************************************************************************/
        !           243: time_t dstrtounix(char *str)
        !           244: {
        !           245: 
        !           246: if(!strcmp(str,"00/00/00"))
        !           247:        return(NULL);
        !           248: curtime.ti_hour=curtime.ti_min=curtime.ti_sec=0;
        !           249: if(str[6]<7)
        !           250:        date.da_year=2000+((str[6]&0xf)*10)+(str[7]&0xf);
        !           251: else
        !           252:        date.da_year=1900+((str[6]&0xf)*10)+(str[7]&0xf);
        !           253: date.da_mon=((str[0]&0xf)*10)+(str[1]&0xf);
        !           254: date.da_day=((str[3]&0xf)*10)+(str[4]&0xf);
        !           255: return(dostounix(&date,&curtime));
        !           256: }
        !           257: 
        !           258: void dots(int show)
        !           259: {
        !           260:        static int i;
        !           261: 
        !           262: if(!show) {  /* reset */
        !           263:        i=0;
        !           264:        return; }
        !           265: if(++i>5) {
        !           266:        bputs("\b\b\b\b\b     \b\b\b\b\b");
        !           267:        i=0;
        !           268:        return; }
        !           269: outchar('.');
        !           270: }
        !           271: 
        !           272: 
        !           273: /* Displays short information about BBS. Returns 0 if aborted. */
        !           274: 
        !           275: char short_bbs_info(bbs_t bbs)
        !           276: {
        !           277:        int i,j;
        !           278: 
        !           279: for(i=0;i<bbs.total_numbers && i<MAX_NUMBERS;i++) {
        !           280:        for(j=0;list_fmt[j];j++) {
        !           281:                if(j) bputs(" ");
        !           282:                switch(toupper(list_fmt[j])) {
        !           283:                        case 'N':
        !           284:                                bprintf("\1h\1m%-25.25s",i ? nulstr : bbs.name);
        !           285:                                break;
        !           286:                        case 'S':
        !           287:                                bprintf("\1h\1c%-15.15s",i ? nulstr : bbs.software);
        !           288:                                break;
        !           289:                        case 'P':
        !           290:                                bprintf("\1n\1g%12.12s",bbs.number[i].number);
        !           291:                                break;
        !           292:                        case 'B':
        !           293:                                bprintf("\1h\1g%5u",bbs.number[i].max_rate);
        !           294:                                break;
        !           295:                        case 'M':
        !           296:                                bprintf("\1h\1b%-15.15s",bbs.number[i].modem);
        !           297:                                break;
        !           298:                        case 'Y':
        !           299:                                bprintf("\1h\1y%-25.25s",i ? nulstr : bbs.sysop[0]);
        !           300:                                break;
        !           301:                        case 'T':
        !           302:                                if(i) bputs("   ");
        !           303:                                else  bprintf("\1n\1h%3u",bbs.nodes);
        !           304:                                break;
        !           305:                        case 'U':
        !           306:                                if(i) bputs("     ");
        !           307:                                else  bprintf("\1n\1r%5u",bbs.users);
        !           308:                 break;
        !           309:                        case 'H':
        !           310:                                if(i) bprintf("%10.10s",nulstr);
        !           311:                                else  bprintf("\1h\1r%10u",bbs.megs);
        !           312:                                break;
        !           313:                        case 'L':
        !           314:                                bprintf("\1n\1c%-25.25s",bbs.number[i].location);
        !           315:                                break;
        !           316:                        case 'F':
        !           317:                                bprintf("\1n\1b%s",i ? nulstr : unixtodstr(bbs.birth,tmp));
        !           318:                                break;
        !           319:                        case 'V':
        !           320:                                bprintf("\1n\1m%s",i ? nulstr : unixtodstr(bbs.verified,tmp));
        !           321:                                break;
        !           322:                        case 'D':
        !           323:                                bprintf("\1n%s",i ? nulstr : unixtodstr(bbs.updated,tmp));
        !           324:                                break;
        !           325:                        case 'C':
        !           326:                                bprintf("\1n\1y%s",i ? nulstr : unixtodstr(bbs.created,tmp));
        !           327:                 break;
        !           328:                        default:
        !           329:                                bprintf("%c",list_fmt[j]);
        !           330:                                break;
        !           331:                                } }
        !           332:        bputs("\r\n"); }
        !           333: if(kbhit())
        !           334:        return(0);
        !           335: return(1);
        !           336: }
        !           337: 
        !           338: char long_bbs_info(bbs_t bbs)
        !           339: {
        !           340:        int i;
        !           341: 
        !           342: cls();
        !           343: bprintf("\1n\1gBBS Name: \1h%s \1n\1gsince \1h%s\r\n"
        !           344:        ,bbs.name,unixtodstr(bbs.birth,tmp));
        !           345: bprintf("\1n\1gOperator: ");
        !           346: for(i=0;i<bbs.total_sysops && i<MAX_SYSOPS;i++) {
        !           347:        if(i) {
        !           348:                if(bbs.total_sysops>2)
        !           349:                        bputs(", ");
        !           350:                else
        !           351:                        outchar(SP);
        !           352:                if(!(i%4))
        !           353:             bputs("\r\n          ");
        !           354:                if(i+1==bbs.total_sysops)
        !           355:                        bputs("and "); }
        !           356:        bprintf("\1h%s\1n\1g",bbs.sysop[i]); }
        !           357: CRLF;
        !           358: bprintf("\1n\1gSoftware: \1h%-15.15s \1n\1gNodes: \1h%-5u \1n\1g"
        !           359:        "Users: \1h%-5u \1n\1gDoors: \1h%u\r\n"
        !           360:        ,bbs.software,bbs.nodes,bbs.users,bbs.xtrns);
        !           361: bprintf("\1n\1gDownload: \1h%lu \1n\1gfiles in \1h%u \1n\1gdirectories of \1h"
        !           362:        "%luMB \1n\1gtotal space\r\n"
        !           363:        ,bbs.files,bbs.dirs,bbs.megs);
        !           364: bprintf("Messages: \1h%lu \1n\1gmessages in \1h%u \1n\1gsub-boards\r\n"
        !           365:        ,bbs.msgs,bbs.subs);
        !           366: bprintf("Networks: ");
        !           367: for(i=0;i<bbs.total_networks && i<MAX_NETS;i++) {
        !           368:        if(i) {
        !           369:                if(bbs.total_networks>2)
        !           370:                        bputs(", ");
        !           371:                else
        !           372:                        outchar(SP);
        !           373:                if(!(i%3))
        !           374:             bputs("\r\n          ");
        !           375:                if(i+1==bbs.total_networks)
        !           376:             bputs("and "); }
        !           377:        bprintf("\1h%s [%s]\1n\1g",bbs.network[i],bbs.address[i]); }
        !           378: CRLF;
        !           379: bprintf("Terminal: ");
        !           380: for(i=0;i<bbs.total_terminals && i<MAX_TERMS;i++) {
        !           381:        if(i) {
        !           382:                if(bbs.total_terminals>2)
        !           383:                        bputs(", ");
        !           384:                else
        !           385:                        outchar(SP);
        !           386:                if(i+1==bbs.total_terminals)
        !           387:             bputs("and "); }
        !           388:        bprintf("\1h%s\1n\1g",bbs.terminal[i]); }
        !           389: CRLF;
        !           390: CRLF;
        !           391: for(i=0;i<bbs.total_numbers && i<MAX_NUMBERS;i++)
        !           392:        bprintf("\1h\1b%-30.30s \1n\1g%12.12s \1h%5u \1b%-15.15s \1n\1c"
        !           393:                "Minimum: \1h%u\r\n"
        !           394:                ,i && !strcmp(bbs.number[i].location,bbs.number[i-1].location)
        !           395:                        ? nulstr : bbs.number[i].location
        !           396:                ,bbs.number[i].number
        !           397:                ,bbs.number[i].max_rate,bbs.number[i].modem
        !           398:                ,bbs.number[i].min_rate);
        !           399: 
        !           400: bputs("\r\n\1w\1h");
        !           401: for(i=0;i<5;i++) {
        !           402:        if(!bbs.desc[i][0])
        !           403:                break;
        !           404:        bprintf("%15s%s\r\n",nulstr,bbs.desc[i]); }
        !           405: 
        !           406: CRLF;
        !           407: if(bbs.misc&FROM_SMB)
        !           408:        bputs("\1r\1hImported from message base.\r\n");
        !           409: bprintf("\1n\1cEntry created on \1h%s\1n\1c by \1h%s\r\n"
        !           410:        ,timestr(&bbs.created),bbs.user);
        !           411: if(bbs.updated && bbs.userupdated[0])
        !           412:        bprintf("\1n\1c Last updated on \1h%s\1n\1c by \1h%s\r\n"
        !           413:                ,timestr(&bbs.updated),bbs.userupdated);
        !           414: if(bbs.verified && bbs.userverified[0])
        !           415:        bprintf("\1n\1cLast verified on \1h%s\1n\1c by \1h%s\r\n"
        !           416:                ,timestr(&bbs.verified),bbs.userverified);
        !           417: CRLF;
        !           418: if(aborted) {
        !           419:        aborted=0;
        !           420:        return(0); }
        !           421: if(!sbl_pause) {
        !           422:        if(kbhit())
        !           423:                return(0);
        !           424:        return(1); }
        !           425: nodesync();
        !           426: return(yesno("More"));
        !           427: }
        !           428: 
        !           429: /* Gets/updates BBS info from user. Returns 0 if aborted. */
        !           430: 
        !           431: char get_bbs_info(bbs_t *bbs)
        !           432: {
        !           433:        char str[128];
        !           434:        int i;
        !           435: 
        !           436: aborted=0;
        !           437: if(!(bbs->user[0]))
        !           438:        strcpy(bbs->user,user_name);
        !           439: if(SYSOP) {
        !           440:        bputs("\1y\1hUser Name (Creator/Owner of Entry): ");
        !           441:        if(!getstr(bbs->user,25,K_EDIT|K_LINE|K_AUTODEL))
        !           442:                return(0); }
        !           443: bputs("\1y\1hSystem Name: ");
        !           444: if(getstr(bbs->name,25,K_EDIT|K_LINE|K_AUTODEL)<2)
        !           445:        return(0);
        !           446: if(!bbs->software[0])
        !           447:        strcpy(bbs->software,"Synchronet");
        !           448: bprintf("\1y\1hSoftware: \1w",bbs->software);
        !           449: if(!getstr(bbs->software,15,K_AUTODEL|K_EDIT))
        !           450:        return(0);
        !           451: 
        !           452: for(i=0;i<MAX_SYSOPS && !aborted;i++) {
        !           453:        bprintf("\1y\1hName of System Operator #%d [\1wNone\1y]: ",i+1);
        !           454:        if(!getstr(bbs->sysop[i],25,K_EDIT|K_LINE|K_AUTODEL))
        !           455:                break; }
        !           456: bbs->total_sysops=i;
        !           457: if(aborted)
        !           458:        return(0);
        !           459: 
        !           460: unixtodstr(bbs->birth,str);
        !           461: bprintf("\1y\1hFirst Day Online (MM/DD/YY): \1w");
        !           462: if(getstr(str,8,K_UPPER|K_EDIT|K_AUTODEL))
        !           463:        bbs->birth=dstrtounix(str);
        !           464: if(aborted) return(0);
        !           465: 
        !           466: for(i=0;i<MAX_NETS && !aborted;i++) {
        !           467:        bprintf("\1y\1hName of Network #%d [\1wNone\1y]: ",i+1);
        !           468:        if(!getstr(bbs->network[i],15,K_EDIT|K_AUTODEL|K_LINE))
        !           469:                break;
        !           470:        bprintf("\1y\1hNetwork \1wAddress\1y #%d [\1wNone\1y]: \1w",i+1);
        !           471:        getstr(bbs->address[i],25,K_EDIT|K_AUTODEL); }
        !           472: bbs->total_networks=i;
        !           473: if(aborted) return(0);
        !           474: 
        !           475: for(i=0;i<MAX_TERMS && !aborted;i++) {
        !           476:        bprintf("\1y\1hSupported Terminal Type #%d (i.e. TTY, ANSI, RIP) "
        !           477:                "[\1wNone\1y]: ",i+1);
        !           478:        if(!getstr(bbs->terminal[i],15,K_EDIT|K_AUTODEL|K_LINE))
        !           479:                break; }
        !           480: bbs->total_terminals=i;
        !           481: if(aborted) return(0);
        !           482: 
        !           483: if(!bbs->nodes)
        !           484:        bbs->nodes=1;
        !           485: bprintf("\1y\1hNodes (maximum number of simultaneous REMOTE users): \1w");
        !           486: sprintf(str,"%u",bbs->nodes);
        !           487: if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL))
        !           488:        bbs->nodes=atoi(str);
        !           489: if(!bbs->nodes)
        !           490:        bbs->nodes=1;
        !           491: if(aborted) return(0);
        !           492: 
        !           493: for(i=0;i<MAX_NUMBERS;i++) {
        !           494:        if(!i && !bbs->number[i].number[0])
        !           495:                sprintf(bbs->number[i].number,"%.8s",user_phone);
        !           496:        bprintf("\1y\1hPhone Number #%d (###-###-####) [\1wNone\1y]: ",i+1);
        !           497:        if(!getstr(bbs->number[i].number,12,K_EDIT|K_LINE))
        !           498:                break;
        !           499:        if(!bbs->number[i].location[0]) {
        !           500:                if(!i)
        !           501:                        strcpy(bbs->number[i].location,user_location);
        !           502:                else
        !           503:                        strcpy(bbs->number[i].location,bbs->number[i-1].location); }
        !           504:        bprintf("\1y\1hLocation (City, State): \1w");
        !           505:        if(!getstr(bbs->number[i].location,30,K_EDIT|K_AUTODEL))
        !           506:                break;
        !           507:        if(aborted) return(0);
        !           508: 
        !           509:        if(!bbs->number[i].min_rate) {
        !           510:                if(i)
        !           511:                        bbs->number[i].min_rate=bbs->number[i-1].min_rate;
        !           512:                else
        !           513:                        bbs->number[i].min_rate=300; }
        !           514:        bprintf("\1y\1hMinimum Connect Rate: \1w");
        !           515:        sprintf(str,"%u",bbs->number[i].min_rate);
        !           516:        if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL))
        !           517:                bbs->number[i].min_rate=atoi(str);
        !           518:        if(aborted) return(0);
        !           519: 
        !           520:        if(!bbs->number[i].max_rate) {
        !           521:         if(i)
        !           522:             bbs->number[i].max_rate=bbs->number[i-1].max_rate;
        !           523:         else
        !           524:             bbs->number[i].max_rate=2400; }
        !           525:        if(bbs->number[i].max_rate<bbs->number[i].min_rate)
        !           526:         bbs->number[i].max_rate=bbs->number[i].min_rate;
        !           527:        bprintf("\1y\1hMaximum Connect Rate (i.e. 2400, 9600, 14400, etc): \1w");
        !           528:        sprintf(str,"%u",bbs->number[i].max_rate);
        !           529:        if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL))
        !           530:                bbs->number[i].max_rate=atoi(str);
        !           531:        if(aborted) return(0);
        !           532: 
        !           533:        bprintf("\1y\1hModem Description (i.e. Hayes, HST, V.32, etc): \1w");
        !           534:        getstr(bbs->number[i].modem,15,K_EDIT|K_AUTODEL);  }
        !           535: if(!i)
        !           536:        return(0);
        !           537: bbs->total_numbers=i;
        !           538: if(aborted)
        !           539:        return(0);
        !           540: 
        !           541: if(!bbs->users)
        !           542:        bbs->users=100;
        !           543: bprintf("\1y\1hTotal Number of Users: \1w");
        !           544: sprintf(str,"%u",bbs->users);
        !           545: if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL))
        !           546:        bbs->users=atoi(str);
        !           547: if(aborted) return(0);
        !           548: 
        !           549: if(!bbs->subs)
        !           550:        bbs->subs=10;
        !           551: bprintf("\1y\1hTotal Number of Sub-boards (Message Areas): \1w");
        !           552: sprintf(str,"%u",bbs->subs);
        !           553: if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL))
        !           554:        bbs->subs=atoi(str);
        !           555: if(aborted) return(0);
        !           556: 
        !           557: if(!bbs->msgs)
        !           558:        bbs->msgs=500;
        !           559: bprintf("\1y\1hTotal Number of Public Messages: \1w");
        !           560: sprintf(str,"%lu",bbs->msgs);
        !           561: if(getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL))
        !           562:        bbs->msgs=atol(str);
        !           563: if(aborted) return(0);
        !           564: 
        !           565: if(!bbs->dirs)
        !           566:        bbs->dirs=5;
        !           567: bprintf("\1y\1hTotal Number of Directories (File Areas): \1w");
        !           568: sprintf(str,"%u",bbs->dirs);
        !           569: if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL))
        !           570:        bbs->dirs=atoi(str);
        !           571: if(aborted) return(0);
        !           572: 
        !           573: if(!bbs->files)
        !           574:        bbs->files=250;
        !           575: bprintf("\1y\1hTotal Number of Downloadable Files: \1w");
        !           576: sprintf(str,"%lu",bbs->files);
        !           577: if(getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL))
        !           578:        bbs->files=atol(str);
        !           579: if(aborted) return(0);
        !           580: 
        !           581: if(!bbs->xtrns)
        !           582:     bbs->xtrns=5;
        !           583: bprintf("\1y\1hTotal Number of External Programs (Doors): \1w");
        !           584: sprintf(str,"%u",bbs->xtrns);
        !           585: if(getstr(str,5,K_NUMBER|K_EDIT|K_AUTODEL))
        !           586:     bbs->xtrns=atoi(str);
        !           587: if(aborted) return(0);
        !           588: 
        !           589: if(!bbs->megs)
        !           590:        bbs->megs=40;
        !           591: bprintf("\1y\1hTotal Storage Space (in Megabytes): \1w");
        !           592: sprintf(str,"%lu",bbs->megs);
        !           593: if(getstr(str,10,K_NUMBER|K_EDIT|K_AUTODEL))
        !           594:        bbs->megs=atol(str);
        !           595: if(aborted) return(0);
        !           596: 
        !           597: for(i=0;i<5;i++) {
        !           598:        bprintf("\1y\1hBBS Description (%d of 5): ",i+1);
        !           599:        if(!getstr(bbs->desc[i],50,K_EDIT|K_AUTODEL|K_LINE))
        !           600:                break; }
        !           601: 
        !           602: return(1);
        !           603: }
        !           604: 
        !           605: char partname(char *inname, char *inpart)
        !           606: {
        !           607:        char name[128],part[128],str[256];
        !           608: 
        !           609: strcpy(name,inname);
        !           610: strupr(name);
        !           611: strcpy(part,inpart);
        !           612: strupr(part);
        !           613: if(inname[0] && (strstr(name,part) || strstr(part,name))) {
        !           614:        sprintf(str,"\r\nDo you mean %s",inname);
        !           615:        if(yesno(str))
        !           616:                return(1); }
        !           617: return(0);
        !           618: }
        !           619: 
        !           620: int sortint_cmp(sortint_t *int1, sortint_t *int2)
        !           621: {
        !           622: 
        !           623: if(int1->i>int2->i)
        !           624:        return(-1);
        !           625: if(int1->i<int2->i)
        !           626:        return(1);
        !           627: return(0);
        !           628: }
        !           629: 
        !           630: int sortstr_cmp(sortstr_t *str1, sortstr_t *str2)
        !           631: {
        !           632: return(stricmp(str1->str,str2->str));
        !           633: }
        !           634: 
        !           635: void main(int argc, char **argv)
        !           636: {
        !           637:        char    str[512],name[128],*p,ch;
        !           638:        short   i,j,file,done,sort_by_str;
        !           639:        int     maint=0;
        !           640:        long    l,found;
        !           641:        bbs_t   bbs,tmpbbs;
        !           642:        FILE    *stream;
        !           643:        sortstr_t *sortstr;
        !           644:        sortint_t *sortint;
        !           645: 
        !           646: for(i=1;i<argc;i++)
        !           647:        if(argv[i][0]=='/')
        !           648:                switch(toupper(argv[i][1])) {
        !           649:                        case 'M':
        !           650:                                maint=1;
        !           651:                                break; }
        !           652: 
        !           653: p=getenv("SBBSNODE");
        !           654: if(p)
        !           655:        strcpy(node_dir,p);
        !           656: else {
        !           657:        printf("\nSBBSNODE environment variable must be set\n");
        !           658:        exit(0); }
        !           659: 
        !           660: if(node_dir[strlen(node_dir)-1]!='\\')
        !           661:        strcat(node_dir,"\\");
        !           662: 
        !           663: strcpy(str,"SBL.CFG");
        !           664: if((file=open(str,O_RDONLY|O_DENYNONE))==-1) {
        !           665:        printf("error opening %s\r\n",str);
        !           666:        exit(1); }
        !           667: if((stream=fdopen(file,"rb"))==NULL) {
        !           668:        printf("fdopen error with %s\r\n",str);
        !           669:        exit(1); }
        !           670: fgets(str,81,stream);
        !           671: del_days=atoi(str);
        !           672: fgets(str,81,stream);
        !           673: add_ml=atoi(str);
        !           674: fgets(str,81,stream);
        !           675: update_ml=atoi(str);
        !           676: fgets(str,81,stream);
        !           677: remove_ml=atoi(str);
        !           678: fgets(str,81,stream);
        !           679: verify_ml=atoi(str);
        !           680: fgets(str,81,stream);
        !           681: notify_user=atoi(str);
        !           682: fclose(stream);
        !           683: 
        !           684: initdata();
        !           685: if(maint)
        !           686:        user_misc=(ANSI|COLOR);
        !           687: 
        !           688: if((file=open("SBL.DAB",O_RDWR|O_BINARY|O_DENYNONE|O_CREAT
        !           689:        ,S_IWRITE|S_IREAD))==-1) {
        !           690:        bprintf("\r\n\7Error opening/creating SBL.DAB\r\n");
        !           691:        exit(1); }
        !           692: if((stream=fdopen(file,"w+b"))==NULL) {
        !           693:        bprintf("\r\n\7Error converting SBL.DAB file handle to stream\r\n");
        !           694:        exit(1); }
        !           695: setvbuf(stream,0L,_IOFBF,2048);
        !           696: 
        !           697: if(del_days) {
        !           698:     now=time(NULL);
        !           699:        strcpy(str,"SBLPURGE.DAB");
        !           700:        if((file=nopen(str,O_RDWR|O_CREAT))==-1) {
        !           701:                printf("Error creating %s\r\n",str);
        !           702:                exit(1); }
        !           703:        l=NULL;
        !           704:        read(file,&l,4);
        !           705:        if(now-l>(24L*60L*60L) || maint) {       /* more than a day since update */
        !           706:                bputs("\r\n\1n\1hRunning daily maintenance for Synchronet BBS List...");
        !           707:                lseek(file,0L,SEEK_SET);
        !           708:                write(file,&now,4);
        !           709:                close(file);
        !           710:                fseek(stream,0L,SEEK_SET);
        !           711:                while(!feof(stream)) {
        !           712:                        if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !           713:                                break;
        !           714:                        if(bbs.name[0] && !(bbs.misc&FROM_SMB)) {
        !           715:                                if((now-bbs.updated)/(24L*60L*60L)>del_days
        !           716:                                        && (now-bbs.created)/(24L*60L*60L)>del_days
        !           717:                                        && (now-bbs.verified)/(24L*60L*60L)>del_days) {
        !           718:                                        lncntr=0;
        !           719:                                        bprintf("\r\n\1n\1hAuto-deleting \1m%s\r\n",bbs.name);
        !           720:                                        sprintf(str,"\1n\1hSBL: \1mYour BBS entry for \1y%s\1m\r\n"
        !           721:                                                "     was auto-deleted from the \1cSynchronet BBS "
        !           722:                                                "List\r\n",bbs.name);
        !           723:                                        i=usernumber(bbs.user);
        !           724:                                        if(i) putsmsg(i,str);
        !           725:                                        bbs.name[0]=0;
        !           726:                                        fseek(stream,-(long)(sizeof(bbs_t)),SEEK_CUR);
        !           727:                                        fwrite(&bbs,sizeof(bbs_t),1,stream); }
        !           728:                                else { /* Warn user */
        !           729:                                        l=bbs.created;
        !           730:                                        if(l<bbs.updated)
        !           731:                                                l=bbs.updated;
        !           732:                                        if(l<bbs.verified)
        !           733:                                                l=bbs.verified;
        !           734:                                        if((now-l)/(24L*60L*60L)>=(del_days/2)) {
        !           735:                                                bprintf("\r\n\1n\1hWarning \1y%s\r\n",bbs.user);
        !           736:                                                lncntr=0;
        !           737:                                                sprintf(str,"\1n\1hSBL: \1mPlease verify your BBS "
        !           738:                                                        "entry for \1y%s\1m\r\n     "
        !           739:                                                        "in the \1cSynchronet BBS List "
        !           740:                                                        "\1mor it will be deleted in \1i\1r%u "
        !           741:                                                        "\1n\1h\1mdays.\r\n"
        !           742:                                                        ,bbs.name
        !           743:                                                        ,del_days-((now-l)/(24L*60L*60L)));
        !           744:                                                i=usernumber(bbs.user);
        !           745:                                                if(i) putsmsg(i,str); } } } } }
        !           746:        else
        !           747:                close(file); }
        !           748: 
        !           749: if(maint)
        !           750:        return;
        !           751: 
        !           752: strcpy(list_fmt,DEF_LIST_FMT);
        !           753: while(1) {
        !           754:        aborted=0;
        !           755:        attr(LIGHTGRAY);
        !           756:        cls();
        !           757:        bprintf("\1n\1m\1hSynchronet \1wBBS List \1mv1.37 (XSDK v%s)  "
        !           758:                "Developed 1994-1997 Rob Swindell\r\n\r\n",xsdk_ver);
        !           759:        sprintf(str,"~List all systems (condensed)\r\n"
        !           760:                                "~Change list format\r\n"
        !           761:                                "~Extended information on all systems\r\n"
        !           762:                                "~Turn screen pause %s\r\n"
        !           763:                                "~Find text in BBS entries\r\n"
        !           764:                                "~Generate sorted list\r\n"
        !           765:                                "~Display sorted list\r\n"
        !           766:                                "~New entry scan\r\n"
        !           767:                                "~Add a BBS entry\r\n"
        !           768:                                "~Update a BBS entry\r\n"
        !           769:                                "~Verify a BBS entry\r\n"
        !           770:                                "~Remove a BBS entry\r\n"
        !           771:                                "~Quit back to BBS\r\n"
        !           772:                                ,sbl_pause ? "OFF" : "ON");
        !           773:        mnemonics(str);
        !           774:        if(SYSOP)
        !           775:                mnemonics(      "~* Undelete entries\r\n");
        !           776: 
        !           777:        bputs("\r\n");
        !           778: 
        !           779:        l=filelength(fileno(stream));
        !           780:        if(l>0)
        !           781:                bprintf("\1n\1cThere are \1h%lu\1n\1c entries in the online BBS list "
        !           782:                        "database.\r\n",l/(long)sizeof(bbs_t));
        !           783: 
        !           784:        if(del_days) {
        !           785:                bprintf("\1n\1cEntries are auto-deleted \1h%u\1n\1c days after "
        !           786:                        "last update or verification.\r\n",del_days);
        !           787:                bputs("Users are encouraged to \1hV\1n\1cerify (vouch for) any listed "
        !           788:                        "BBSs they call.\r\n"); }
        !           789: 
        !           790:        nodesync();                     /* Display any waiting messages */
        !           791: 
        !           792:        bputs("\r\n\1y\1hWhich: \1w");
        !           793:        switch(getkeys("CLGDEFSNAURTQV!*",0)) {
        !           794:                case '!':
        !           795:                        bprintf("\r\nsizeof(bbs_t)=%u\r\n",sizeof(bbs_t));
        !           796:                        pause();
        !           797:                        break;
        !           798:                case '*':
        !           799:                        cls();
        !           800:                        if(!SYSOP)
        !           801:                                break;
        !           802:                        fseek(stream,0L,SEEK_SET);
        !           803:                        while(!feof(stream) && !aborted) {
        !           804:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !           805:                                        break;
        !           806:                                if(!bbs.name[0]) {
        !           807:                                        bbs.name[0]='?';
        !           808:                                        bbs.verified=time(NULL);
        !           809:                                        sprintf(bbs.userverified,"%.25s",user_name);
        !           810:                                        if(yesno(bbs.name)) {
        !           811:                                                bprintf("\1n\1gFirst char: \1h");
        !           812:                                                bbs.name[0]=getkey(0);
        !           813:                                                bprintf("%s\r\n",bbs.name);
        !           814:                                                fseek(stream,-(long)sizeof(bbs_t),SEEK_CUR);
        !           815:                                                fwrite(&bbs,sizeof(bbs_t),1,stream); } } }
        !           816:             break;
        !           817:                case 'L':
        !           818:                        cls();
        !           819:                        fseek(stream,0L,SEEK_SET);
        !           820:                        i=0;
        !           821:                        while(!feof(stream) && !aborted) {
        !           822:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !           823:                                        break;
        !           824:                                if(!bbs.name[0])
        !           825:                                        continue;
        !           826:                                i++;
        !           827:                                if(!short_bbs_info(bbs))
        !           828:                                        break;
        !           829:                                if(!sbl_pause)
        !           830:                                        lncntr=0; }
        !           831:                        bprintf("\r\n\1n\1h%u systems listed.\r\n",i);
        !           832:                        if(kbhit())
        !           833:                                getch();
        !           834:                        if(lncntr)
        !           835:                                pause();
        !           836:                        break;
        !           837:                case 'C':
        !           838:                        cls();
        !           839:                        bputs("\1n\1c\1hList Format Specifier Definitions:\1n\r\n\r\n");
        !           840:                        bputs("\1h\1w(\1mN\1w) \1n\1mName of System\r\n");
        !           841:                        bputs("\1h\1w(\1mS\1w) \1n\1mSoftware Used\r\n");
        !           842:                        bputs("\1h\1w(\1mP\1w) \1n\1mPhone Number\r\n");
        !           843:                        bputs("\1h\1w(\1mB\1w) \1n\1mMaximum Connect Rate (in bps)\r\n");
        !           844:                        bputs("\1h\1w(\1mM\1w) \1n\1mModem Type\r\n");
        !           845:                        bputs("\1h\1w(\1mY\1w) \1n\1mSysop's Name\r\n");
        !           846:                        bputs("\1h\1w(\1mT\1w) \1n\1mTotal Number of Nodes\r\n");
        !           847:                        bputs("\1h\1w(\1mU\1w) \1n\1mTotal Number of Users\r\n");
        !           848:                        bputs("\1h\1w(\1mH\1w) \1n\1mTotal Storage Capacity (in megabytes)\r\n");
        !           849:                        bputs("\1h\1w(\1mL\1w) \1n\1mLocation (City, State)\r\n");
        !           850:                        bputs("\1h\1w(\1mF\1w) \1n\1mDate System was First Online\r\n");
        !           851:                        bputs("\1h\1w(\1mC\1w) \1n\1mDate Entry was Created\r\n");
        !           852:                        bputs("\1h\1w(\1mV\1w) \1n\1mDate Entry was Last Verified\r\n");
        !           853:                        bputs("\1h\1w(\1mD\1w) \1n\1mDate Entry was Last Updated\r\n");
        !           854:                        bprintf("\r\n\1n\1gDefault Format: \1h%s",DEF_LIST_FMT);
        !           855:                        bprintf("\r\n\1n\1gCurrent Format: \1h%s\r\n",list_fmt);
        !           856:                        bprintf("\r\n\1y\1hNew Format: ");
        !           857:                        if(getstr(tmp,10,K_UPPER|K_LINE)) {
        !           858:                                if(!strchr(tmp,'P') || !strchr(tmp,'N')) {
        !           859:                                        bputs("\r\n\1h\1mP\1n\1mhone and \1hN\1n\1mame specifiers "
        !           860:                                                "must be present in format.\r\n\r\n");
        !           861:                                        pause(); }
        !           862:                                else
        !           863:                                        strcpy(list_fmt,tmp); }
        !           864:                        break;
        !           865:                case 'E':
        !           866:                        fseek(stream,0L,SEEK_SET);
        !           867:                        while(!feof(stream) && !aborted) {
        !           868:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !           869:                                        break;
        !           870:                                if(bbs.name[0] && !long_bbs_info(bbs))
        !           871:                                        break;
        !           872:                                if(!sbl_pause)
        !           873:                                        lncntr=0; }
        !           874:             break;
        !           875:                case 'F':   /* Find text */
        !           876:                        cls();
        !           877:                        bputs("\1y\1hText to search for: ");
        !           878:                        if(!getstr(name,25,K_UPPER|K_LINE))
        !           879:                                break;
        !           880:                        ch=yesno("\r\nDisplay extended information");
        !           881: 
        !           882:                        found=0;
        !           883:                        bputs("\1n\1h\r\nSearching...\r\n\r\n");
        !           884:                        fseek(stream,0L,SEEK_SET);
        !           885:                        while(!feof(stream) && !aborted) {
        !           886:                                if(!sbl_pause)
        !           887:                                        lncntr=0;
        !           888:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !           889:                                        break;
        !           890:                                if(!bbs.name[0])
        !           891:                                        continue;
        !           892:                                tmpbbs=bbs;
        !           893:                                strupr(tmpbbs.name);
        !           894:                                strupr(tmpbbs.user);
        !           895:                                strupr(tmpbbs.userverified);
        !           896:                                strupr(tmpbbs.userupdated);
        !           897:                                strupr(tmpbbs.software);
        !           898:                                if(strstr(tmpbbs.name,name)
        !           899:                                        || strstr(tmpbbs.user,name)
        !           900:                                        || strstr(tmpbbs.software,name)
        !           901:                                        || strstr(tmpbbs.userverified,name)
        !           902:                                        || strstr(tmpbbs.userupdated,name)
        !           903:                                        ) {
        !           904:                                        found++;
        !           905:                                        if(ch && !long_bbs_info(bbs))
        !           906:                                                break;
        !           907:                                        if(!ch && !short_bbs_info(bbs))
        !           908:                                                break;
        !           909:                                        continue; }
        !           910: 
        !           911:                                for(i=0;i<tmpbbs.total_sysops;i++) {
        !           912:                                        strupr(tmpbbs.sysop[i]);
        !           913:                                        if(strstr(tmpbbs.sysop[i],name))
        !           914:                                                break; }
        !           915:                                if(i<tmpbbs.total_sysops) {
        !           916:                                        found++;
        !           917:                                        if(ch && !long_bbs_info(bbs))
        !           918:                                                break;
        !           919:                                        if(!ch && !short_bbs_info(bbs))
        !           920:                                                break;
        !           921:                                        continue; }
        !           922: 
        !           923:                                for(i=0;i<tmpbbs.total_networks;i++) {
        !           924:                                        strupr(tmpbbs.network[i]);
        !           925:                                        strupr(tmpbbs.address[i]);
        !           926:                                        if(strstr(tmpbbs.network[i],name)
        !           927:                                                || strstr(tmpbbs.address[i],name))
        !           928:                                                break; }
        !           929:                                if(i<tmpbbs.total_networks) {
        !           930:                                        found++;
        !           931:                                        if(ch && !long_bbs_info(bbs))
        !           932:                                                break;
        !           933:                                        if(!ch && !short_bbs_info(bbs))
        !           934:                                                break;
        !           935:                     continue; }
        !           936: 
        !           937:                                for(i=0;i<tmpbbs.total_terminals;i++) {
        !           938:                                        strupr(tmpbbs.terminal[i]);
        !           939:                                        if(strstr(tmpbbs.terminal[i],name))
        !           940:                                                break; }
        !           941:                                if(i<tmpbbs.total_terminals) {
        !           942:                                        found++;
        !           943:                                        if(ch && !long_bbs_info(bbs))
        !           944:                                                break;
        !           945:                                        if(!ch && !short_bbs_info(bbs))
        !           946:                                                break;
        !           947:                     continue; }
        !           948: 
        !           949:                                for(i=0;i<tmpbbs.total_numbers;i++) {
        !           950:                                        strupr(tmpbbs.number[i].number);
        !           951:                                        strupr(tmpbbs.number[i].modem);
        !           952:                                        strupr(tmpbbs.number[i].location);
        !           953:                                        if(strstr(tmpbbs.number[i].number,name)
        !           954:                                                || strstr(tmpbbs.number[i].modem,name)
        !           955:                                                || strstr(tmpbbs.number[i].location,name))
        !           956:                                                break; }
        !           957:                                if(i<tmpbbs.total_numbers) {
        !           958:                                        found++;
        !           959:                                        if(ch && !long_bbs_info(bbs))
        !           960:                                                break;
        !           961:                                        if(!ch && !short_bbs_info(bbs))
        !           962:                                                break;
        !           963:                                        continue; } }
        !           964:                        if(!ch || !found) {
        !           965:                                CRLF;
        !           966:                                if(kbhit())
        !           967:                                        getch();
        !           968:                                if(found)
        !           969:                                        bprintf("\1n\1h%u systems listed.\r\n",found);
        !           970:                                pause(); }
        !           971:             break;
        !           972:                case 'G':   /* Generated sorted list */
        !           973:                        cls();
        !           974:                        if(!filelength(fileno(stream))) {
        !           975:                 bprintf("No BBS list exists.\r\n");
        !           976:                 pause();
        !           977:                 break; }
        !           978:                        bputs("\1n\1c\1hSort Options:\1n\r\n\r\n");
        !           979:                        bputs("\1h\1w(\1mN\1w) \1n\1mName of System\r\n");
        !           980:                        bputs("\1h\1w(\1mS\1w) \1n\1mSoftware Used\r\n");
        !           981:                        bputs("\1h\1w(\1mP\1w) \1n\1mPhone Number\r\n");
        !           982:                        bputs("\1h\1w(\1mB\1w) \1n\1mMaximum Connect Rate (in bps)\r\n");
        !           983:                        bputs("\1h\1w(\1mM\1w) \1n\1mModem Type\r\n");
        !           984:                        bputs("\1h\1w(\1mY\1w) \1n\1mSysop's Name\r\n");
        !           985:                        bputs("\1h\1w(\1mT\1w) \1n\1mTotal Number of Nodes\r\n");
        !           986:                        bputs("\1h\1w(\1mU\1w) \1n\1mTotal Number of Users\r\n");
        !           987:                        bputs("\1h\1w(\1mH\1w) \1n\1mTotal Storage Capacity (in megabytes)\r\n");
        !           988:                        bputs("\1h\1w(\1mL\1w) \1n\1mLocation (City, State)\r\n");
        !           989:                        bputs("\1h\1w(\1mF\1w) \1n\1mDate System was First Online\r\n");
        !           990:                        bputs("\1h\1w(\1mC\1w) \1n\1mDate Entry was Created\r\n");
        !           991:                        bputs("\1h\1w(\1mV\1w) \1n\1mDate Entry was Last Verified\r\n");
        !           992:             bputs("\1h\1w(\1mD\1w) \1n\1mDate Entry was Last Updated\r\n");
        !           993:                        bprintf("\r\n\1y\1hSort by (\1wQ\1y=Quit): \1w");
        !           994:                        ch=getkeys("NSPBMYTUHLFCVDQ",0);
        !           995:                        if(!ch || ch=='Q')
        !           996:                                break;
        !           997:                        cls();
        !           998:                        bputs("\1n\1hSorting...     \1m");
        !           999:                        fseek(stream,0L,SEEK_SET);
        !          1000:                        i=j=done=0;
        !          1001:                        sort_by_str=0;
        !          1002:                        sortstr=NULL;
        !          1003:                        sortint=NULL;
        !          1004:                        while(!feof(stream) && !done) {
        !          1005:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !          1006:                                        break;
        !          1007:                                j++;
        !          1008:                                bprintf("\b\b\b\b%4u",j);
        !          1009:                                if(!bbs.name[0])        /* don't sort deleted entries */
        !          1010:                     continue;
        !          1011:                                i++;
        !          1012:                                switch(ch) {
        !          1013:                                        case 'N':
        !          1014:                                                sprintf(str,"%.30s",bbs.name);
        !          1015:                                                sort_by_str=1;
        !          1016:                                                break;
        !          1017:                                        case 'S':
        !          1018:                                                sprintf(str,"%.30s",bbs.software);
        !          1019:                                                sort_by_str=1;
        !          1020:                                                break;
        !          1021:                                        case 'P':
        !          1022:                                                sprintf(str,"%.30s",bbs.number[0].number);
        !          1023:                                                sort_by_str=1;
        !          1024:                                                break;
        !          1025:                                        case 'M':
        !          1026:                                                sprintf(str,"%.30s",bbs.number[0].modem);
        !          1027:                                                sort_by_str=1;
        !          1028:                                                break;
        !          1029:                                        case 'Y':
        !          1030:                                                sprintf(str,"%.30s",bbs.sysop[0]);
        !          1031:                                                sort_by_str=1;
        !          1032:                                                break;
        !          1033:                                        case 'L':
        !          1034:                                                sprintf(str,"%.30s",bbs.number[0].location);
        !          1035:                                                sort_by_str=1;
        !          1036:                                                break;
        !          1037:                                        case 'B':
        !          1038:                                                l=bbs.number[0].max_rate;
        !          1039:                                                break;
        !          1040:                                        case 'T':
        !          1041:                                                l=bbs.nodes;
        !          1042:                                                break;
        !          1043:                                        case 'U':
        !          1044:                                                l=bbs.users;
        !          1045:                                                break;
        !          1046:                                        case 'H':
        !          1047:                                                l=bbs.megs;
        !          1048:                                                break;
        !          1049:                                        case 'F':
        !          1050:                                                l=bbs.birth;
        !          1051:                                                break;
        !          1052:                                        case 'C':
        !          1053:                                                l=bbs.created;
        !          1054:                                                break;
        !          1055:                                        case 'V':
        !          1056:                                                l=bbs.verified;
        !          1057:                                                break;
        !          1058:                                        case 'D':
        !          1059:                                                l=bbs.updated;
        !          1060:                                                break; }
        !          1061:                                if(sort_by_str) {
        !          1062:                                        if((sortstr=(sortstr_t *)farrealloc(sortstr
        !          1063:                                                ,sizeof(sortstr_t)*i))==NULL) {
        !          1064:                                                bprintf("\r\n\7Memory allocation error\r\n");
        !          1065:                                                farfree(sortstr);
        !          1066:                                                done=1;
        !          1067:                                                continue; }
        !          1068:                                        strcpy(sortstr[i-1].str,str);
        !          1069:                                        sortstr[i-1].offset=j-1; }
        !          1070:                                else {
        !          1071:                                        if((sortint=(sortint_t *)farrealloc(sortint
        !          1072:                                                ,sizeof(sortint_t)*i))==NULL) {
        !          1073:                                                bprintf("\r\n\7Memory allocation error\r\n");
        !          1074:                                                farfree(sortint);
        !          1075:                                                done=1;
        !          1076:                                                continue; }
        !          1077:                                        sortint[i-1].i=l;
        !          1078:                                        sortint[i-1].offset=j-1; } }
        !          1079: 
        !          1080:                        if(done) {
        !          1081:                                pause();
        !          1082:                                break; }
        !          1083: 
        !          1084:                        if(sort_by_str)
        !          1085:                                qsort((void *)sortstr,i,sizeof(sortstr[0])
        !          1086:                                        ,(int(*)(const void *, const void *))sortstr_cmp);
        !          1087:                        else
        !          1088:                                qsort((void *)sortint,i,sizeof(sortint[0])
        !          1089:                                        ,(int(*)(const void *, const void *))sortint_cmp);
        !          1090: 
        !          1091:                        bprintf("\r\n\r\n\1h\1gCreating index...");
        !          1092:                        sprintf(str,"SORT_%03d.NDX",node_num);
        !          1093:                        if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !          1094:                                bprintf("\r\n\7Error creating %s\r\n",str);
        !          1095:                                if(sort_by_str)
        !          1096:                                        farfree(sortstr);
        !          1097:                                else
        !          1098:                                        farfree(sortint);
        !          1099:                                pause();
        !          1100:                                break; }
        !          1101:                        for(j=0;j<i;j++)
        !          1102:                                if(sort_by_str)
        !          1103:                                        write(file,&sortstr[j].offset,2);
        !          1104:                                else
        !          1105:                                        write(file,&sortint[j].offset,2);
        !          1106:                        close(file);
        !          1107:                        if(sort_by_str)
        !          1108:                                farfree(sortstr);
        !          1109:                        else
        !          1110:                                farfree(sortint);
        !          1111:                        bputs("\r\n\r\n\1n\1hDone.\r\n");
        !          1112:                        pause();
        !          1113:                        break;
        !          1114:                case 'D':
        !          1115:                        cls();
        !          1116:                        sprintf(str,"SORT_%03d.NDX",node_num);
        !          1117:                        if((file=nopen(str,O_RDONLY))==-1) {
        !          1118:                                bputs("\1n\1r\1hSorted list not generated.\r\n");
        !          1119:                                pause(); }
        !          1120:                        ch=yesno("Display extended information");
        !          1121:                        cls();
        !          1122:                        while(!eof(file) && !aborted) {
        !          1123:                                if(read(file,&i,2)!=2)
        !          1124:                                        break;
        !          1125:                                fseek(stream,(long)i*sizeof(bbs_t),SEEK_SET);
        !          1126:                                if(!sbl_pause)
        !          1127:                                        lncntr=0;
        !          1128:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !          1129:                                        break;
        !          1130:                                if(!bbs.name[0])
        !          1131:                     continue;
        !          1132:                                if(ch && !long_bbs_info(bbs))
        !          1133:                                        break;
        !          1134:                                if(!ch && !short_bbs_info(bbs))
        !          1135:                                        break; }
        !          1136:                        close(file);
        !          1137:                        if(kbhit())
        !          1138:                                getch();
        !          1139:                        if(lncntr)
        !          1140:                 pause();
        !          1141:                        break;
        !          1142:                case 'N':   /* New (updated) entry scan */
        !          1143:                        cls();
        !          1144:                        bputs("\1y\1hLast update (MM/DD/YY): ");
        !          1145:                        if(!getstr(str,8,K_UPPER|K_LINE))
        !          1146:                                break;
        !          1147:                        l=dstrtounix(str);
        !          1148:                        ch=yesno("\r\nDisplay extended information");
        !          1149:                        found=0;
        !          1150:                        bputs("\1n\1h\r\nSearching...\r\n\r\n");
        !          1151:                        fseek(stream,0L,SEEK_SET);
        !          1152:                        while(!feof(stream) && !aborted) {
        !          1153:                                if(!sbl_pause)
        !          1154:                                        lncntr=0;
        !          1155:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !          1156:                                        break;
        !          1157:                                if(!bbs.name[0])
        !          1158:                                        continue;
        !          1159:                                if(bbs.updated>=l || bbs.created>=l) {
        !          1160:                                        if(ch && !long_bbs_info(bbs))
        !          1161:                                                break;
        !          1162:                                        if(!ch && !short_bbs_info(bbs))
        !          1163:                                                break;
        !          1164:                                        found++;
        !          1165:                                        continue; } }
        !          1166:                        if(!ch || !found) {
        !          1167:                                CRLF;
        !          1168:                                pause(); }
        !          1169:             break;
        !          1170:                case 'A':
        !          1171:                        cls();
        !          1172:                        if(user_level<add_ml) {
        !          1173:                                bprintf("\1h\1rYou have insufficient access.\r\n\r\n");
        !          1174:                                pause();
        !          1175:                                break; }
        !          1176:                        bputs("\1g\1hAdding a BBS entry:\1n\r\n\r\n");
        !          1177:                        bputs("\1n\1gHit ENTER for unknown data items.\r\n\r\n");
        !          1178:                        memset(&bbs,NULL,sizeof(bbs_t));
        !          1179:                        if(!get_bbs_info(&bbs))
        !          1180:                                break;
        !          1181:                        bputs("\1n\1h\r\nSearching for duplicates...");
        !          1182:                        fseek(stream,0L,SEEK_SET);
        !          1183:                        i=0;
        !          1184:                        dots(0);
        !          1185:                        while(!feof(stream) && !i) {
        !          1186:                                dots(1);
        !          1187:                                if(!fread(&tmpbbs,sizeof(bbs_t),1,stream))
        !          1188:                                        break;
        !          1189:                                if(!stricmp(tmpbbs.name,bbs.name)) i=1; }
        !          1190:                        if(i) {
        !          1191:                                bprintf("\7\1n\1h\1r\1i\r\n\r\n%s \1n\1h\1ralready exists!"
        !          1192:                                        "\r\n\r\n"
        !          1193:                                        ,bbs.name);
        !          1194:                                pause();
        !          1195:                                break; }
        !          1196: 
        !          1197:                        bputs("\1n\1h\r\nSaving...");
        !          1198:                        fseek(stream,0L,SEEK_SET);
        !          1199:                        dots(0);
        !          1200:                        while(!feof(stream)) {
        !          1201:                                dots(1);
        !          1202:                                if(!fread(&ch,1,1,stream))
        !          1203:                                        break;
        !          1204:                                if(!ch) {                       /* first byte is null */
        !          1205:                                        fseek(stream,-1L,SEEK_CUR);
        !          1206:                                        break; }
        !          1207:                                fseek(stream,(long)sizeof(bbs_t)-1L,SEEK_CUR); }
        !          1208:                        bbs.created=time(NULL);
        !          1209:                        fwrite(&bbs,sizeof(bbs_t),1,stream);
        !          1210:                        if(notify_user && notify_user!=user_number) {
        !          1211:                                sprintf(str,"\1n\1hSBL: \1y%s \1madded \1c%s\1m "
        !          1212:                                        "to the BBS List\r\n",user_name,bbs.name);
        !          1213:                                putsmsg(notify_user,str); }
        !          1214:                        break;
        !          1215:                case 'R':       /* Remove an entry */
        !          1216:                        cls();
        !          1217:                        if(user_level<remove_ml) {
        !          1218:                                bprintf("\1h\1rYou have insufficient access.\r\n\r\n");
        !          1219:                                pause();
        !          1220:                 break; }
        !          1221:                        bprintf("\1y\1hRemove which system: ");
        !          1222:                        if(!getstr(name,25,K_LINE|K_UPPER))
        !          1223:                                break;
        !          1224:                        bputs("\1n\1h\r\nSearching...");
        !          1225:                        fseek(stream,0L,SEEK_SET);
        !          1226:                        found=0;
        !          1227:                        dots(0);
        !          1228:                        while(!feof(stream) && !aborted) {
        !          1229:                                dots(1);
        !          1230:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !          1231:                                        break;
        !          1232:                                if(!stricmp(bbs.name,name) || partname(bbs.name,name)) {
        !          1233:                                        found=1;
        !          1234:                                        for(i=0;i<bbs.total_sysops && i<MAX_SYSOPS;i++)
        !          1235:                                                if(!stricmp(bbs.sysop[i],user_name))
        !          1236:                                                        break;
        !          1237:                                        if(SYSOP || !stricmp(bbs.user,user_name)
        !          1238:                                                || i<bbs.total_sysops) {
        !          1239:                                                fseek(stream,-(long)(sizeof(bbs_t)),SEEK_CUR);
        !          1240:                                                strcpy(tmp,bbs.name);
        !          1241:                                                bbs.name[0]=0;
        !          1242:                                                bbs.updated=time(NULL);
        !          1243:                                                fwrite(&bbs,sizeof(bbs_t),1,stream);
        !          1244:                                                bprintf("\r\n\r\n\1m%s\1c deleted."
        !          1245:                                                        ,tmp);
        !          1246:                                                if(notify_user && notify_user!=user_number) {
        !          1247:                                                        sprintf(str,"\1n\1hSBL: \1y%s \1mremoved \1c%s\1m "
        !          1248:                                                                "from the BBS List\r\n",user_name,tmp);
        !          1249:                                                        putsmsg(notify_user,str); } }
        !          1250:                                        else
        !          1251:                                                bprintf("\r\n\r\n\1rYou did not create \1m%s\1n."
        !          1252:                                                        ,bbs.name);
        !          1253:                                        break; } }
        !          1254:                        if(!found)
        !          1255:                                bprintf("\r\n\r\n\1m%s\1c not found.",name);
        !          1256:                        CRLF;
        !          1257:                        CRLF;
        !          1258:                        pause();
        !          1259:             break;
        !          1260:                case 'T':
        !          1261:                        sbl_pause=!sbl_pause;
        !          1262:                        break;
        !          1263:                case 'V':       /* Verify an entry */
        !          1264:                        cls();
        !          1265:                        if(user_level<verify_ml) {
        !          1266:                                bprintf("\1h\1rYou have insufficient access.\r\n\r\n");
        !          1267:                                pause();
        !          1268:                 break; }
        !          1269:                        bprintf("\1y\1hVerify which system: ");
        !          1270:                        if(!getstr(name,25,K_LINE|K_UPPER))
        !          1271:                                break;
        !          1272:                        bputs("\1n\1h\r\nSearching...");
        !          1273:                        fseek(stream,0L,SEEK_SET);
        !          1274:                        found=0;
        !          1275:                        dots(0);
        !          1276:                        while(!feof(stream) && !aborted) {
        !          1277:                                dots(1);
        !          1278:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !          1279:                                        break;
        !          1280:                                if(!stricmp(bbs.name,name) || partname(bbs.name,name)) {
        !          1281:                                        found=1;
        !          1282:                                        bbs.verified=time(NULL);
        !          1283:                                        sprintf(bbs.userverified,"%.25s",user_name);
        !          1284:                                        fseek(stream,-(long)(sizeof(bbs_t)),SEEK_CUR);
        !          1285:                                        fwrite(&bbs,sizeof(bbs_t),1,stream);
        !          1286:                                        bprintf("\r\n\r\n\1m%s\1c verified. \1r\1h\1iThank you!"
        !          1287:                                                ,bbs.name);
        !          1288:                                        sprintf(str,"\1n\1hSBL: \1y%s \1mverified \1c%s\1m "
        !          1289:                                                "in the BBS List\r\n",user_name,bbs.name);
        !          1290:                                        if(notify_user && notify_user!=user_number)
        !          1291:                                                putsmsg(notify_user,str);
        !          1292:                                        if(stricmp(bbs.user,user_name)) {
        !          1293:                                                i=usernumber(bbs.user);
        !          1294:                                                if(i && i!=user_number) putsmsg(i,str); }
        !          1295:                                        break; } }
        !          1296:                        if(!found)
        !          1297:                                bprintf("\r\n\r\n\1m%s\1c not found.",name);
        !          1298:                        CRLF;
        !          1299:                        CRLF;
        !          1300:                        pause();
        !          1301:             break;
        !          1302:                case 'U':       /* Update an entry */
        !          1303:                        cls();
        !          1304:                        if(user_level<update_ml) {
        !          1305:                                bprintf("\1h\1rYou have insufficient access.\r\n\r\n");
        !          1306:                                pause();
        !          1307:                 break; }
        !          1308:                        bprintf("\1y\1hUpdate which system: ");
        !          1309:                        if(!getstr(name,25,K_LINE|K_UPPER))
        !          1310:                                break;
        !          1311:                        bputs("\1n\1h\r\nSearching...");
        !          1312:                        fseek(stream,0L,SEEK_SET);
        !          1313:                        found=0;
        !          1314:                        dots(0);
        !          1315:                        while(!feof(stream) && !aborted) {
        !          1316:                                dots(1);
        !          1317:                                l=ftell(stream);
        !          1318:                                if(!fread(&bbs,sizeof(bbs_t),1,stream))
        !          1319:                                        break;
        !          1320:                                if(!stricmp(bbs.name,name) || partname(bbs.name,name)) {
        !          1321:                                        found=1;
        !          1322:                                        break; } }
        !          1323:                        if(found) {
        !          1324:                                for(i=0;i<bbs.total_sysops && i<MAX_SYSOPS;i++)
        !          1325:                                        if(!bbs.sysop[i][0] || !stricmp(bbs.sysop[i],user_name))
        !          1326:                                                break;
        !          1327:                                if(SYSOP || !stricmp(bbs.user,user_name)
        !          1328:                                        || i<bbs.total_sysops) {
        !          1329:                                        CRLF;
        !          1330:                                        CRLF;
        !          1331:                                        if(get_bbs_info(&bbs)) {
        !          1332:                                                bbs.misc&=~FROM_SMB;
        !          1333:                                                bbs.updated=time(NULL);
        !          1334:                                                sprintf(bbs.userupdated,"%.25s",user_name);
        !          1335:                                                fseek(stream,l,SEEK_SET);
        !          1336:                                                fwrite(&bbs,sizeof(bbs_t),1,stream);
        !          1337:                                                bprintf("\r\n\1h\1m%s\1c updated.",bbs.name);
        !          1338:                                                if(notify_user && notify_user!=user_number) {
        !          1339:                                                        sprintf(str,"\1n\1hSBL: \1y%s \1mupdated \1c%s\1m "
        !          1340:                                                                "in the BBS List\r\n",user_name,bbs.name);
        !          1341:                                                        putsmsg(notify_user,str); } } }
        !          1342:                 else
        !          1343:                                        bprintf("\r\n\r\n\1h\1rYou did not create \1m%s\1n."
        !          1344:                                           ,bbs.name); }
        !          1345:                        else
        !          1346:                                bprintf("\r\n\r\n\1h\1m%s\1c not found.",name);
        !          1347:                        CRLF;
        !          1348:                        CRLF;
        !          1349:                        pause();
        !          1350:             break;
        !          1351:                case 'Q':
        !          1352:                        return; } }
        !          1353: }
        !          1354: 
        !          1355: /* End of SBL.C */

unix.superglobalmegacorp.com

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