|
|
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.