|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.