|
|
1.1 ! root 1: /* str.cpp */ ! 2: ! 3: /* Synchronet high-level string i/o routines */ ! 4: ! 5: /* $Id: str.cpp,v 1.13 2000/12/11 23:21:12 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: ! 40: const char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; ! 41: const char *mon[]={"Jan","Feb","Mar","Apr","May","Jun" ! 42: ,"Jul","Aug","Sep","Oct","Nov","Dec"}; ! 43: ! 44: /****************************************************************************/ ! 45: /* Lists all users who have access to the current sub. */ ! 46: /****************************************************************************/ ! 47: void sbbs_t::userlist(char mode) ! 48: { ! 49: char name[256],sort=0; ! 50: char tmp[512]; ! 51: int i,j,k,users=0; ! 52: char * line[1000]; ! 53: user_t user; ! 54: ! 55: if(lastuser(&cfg)<=1000) ! 56: sort=yesno(text[SortAlphaQ]); ! 57: if(sort) { ! 58: bputs(text[CheckingSlots]); } ! 59: else { ! 60: CRLF; } ! 61: j=0; ! 62: k=lastuser(&cfg); ! 63: for(i=1;i<=k && !msgabort();i++) { ! 64: if(sort && (online==ON_LOCAL || !rioctl(TXBC))) ! 65: bprintf("%-4d\b\b\b\b",i); ! 66: user.number=i; ! 67: getuserdat(&cfg,&user); ! 68: if(user.misc&(DELETED|INACTIVE)) ! 69: continue; ! 70: users++; ! 71: if(mode==UL_SUB) { ! 72: if(!usrgrps) ! 73: continue; ! 74: if(!chk_ar(cfg.grp[usrgrp[curgrp]]->ar,&user)) ! 75: continue; ! 76: if(!chk_ar(cfg.sub[usrsub[curgrp][cursub[curgrp]]]->ar,&user) ! 77: || (cfg.sub[usrsub[curgrp][cursub[curgrp]]]->read_ar[0] ! 78: && !chk_ar(cfg.sub[usrsub[curgrp][cursub[curgrp]]]->read_ar,&user))) ! 79: continue; } ! 80: else if(mode==UL_DIR) { ! 81: if(user.rest&FLAG('T')) ! 82: continue; ! 83: if(!usrlibs) ! 84: continue; ! 85: if(!chk_ar(cfg.lib[usrlib[curlib]]->ar,&user)) ! 86: continue; ! 87: if(!chk_ar(cfg.dir[usrdir[curlib][curdir[curlib]]]->ar,&user)) ! 88: continue; } ! 89: if(sort) { ! 90: if((line[j]=(char *)MALLOC(128))==0) { ! 91: errormsg(WHERE,ERR_ALLOC,nulstr,83); ! 92: for(i=0;i<j;i++) ! 93: FREE(line[i]); ! 94: return; } ! 95: sprintf(name,"%s #%d",user.alias,i); ! 96: sprintf(line[j],text[UserListFmt],name ! 97: ,cfg.sys_misc&SM_LISTLOC ? user.location : user.note ! 98: ,unixtodstr(&cfg,user.laston,tmp) ! 99: ,user.modem); } ! 100: else { ! 101: sprintf(name,"%s #%u",user.alias,i); ! 102: bprintf(text[UserListFmt],name ! 103: ,cfg.sys_misc&SM_LISTLOC ? user.location : user.note ! 104: ,unixtodstr(&cfg,user.laston,tmp) ! 105: ,user.modem); } ! 106: j++; } ! 107: if(i<=k) { /* aborted */ ! 108: if(sort) ! 109: for(i=0;i<j;i++) ! 110: FREE(line[i]); ! 111: return; } ! 112: if(!sort) { ! 113: CRLF; } ! 114: bprintf(text[NTotalUsers],users); ! 115: if(mode==UL_SUB) ! 116: bprintf(text[NUsersOnCurSub],j); ! 117: else if(mode==UL_DIR) ! 118: bprintf(text[NUsersOnCurDir],j); ! 119: if(!sort) ! 120: return; ! 121: CRLF; ! 122: qsort((void *)line,j,sizeof(line[0]) ! 123: ,(int(*)(const void*, const void*))pstrcmp); ! 124: for(i=0;i<j && !msgabort();i++) ! 125: bputs(line[i]); ! 126: for(i=0;i<j;i++) ! 127: FREE(line[i]); ! 128: } ! 129: ! 130: /****************************************************************************/ ! 131: /* SIF input function. See SIF.DOC for more info */ ! 132: /****************************************************************************/ ! 133: void sbbs_t::sif(char *fname, char *answers, long len) ! 134: { ! 135: char str[256],tmplt[256],HUGE16 *buf; ! 136: uint t,max,min,mode,cr; ! 137: int file; ! 138: long length,l=0,m,top,a=0; ! 139: ! 140: sprintf(str,"%s%s.sif",cfg.text_dir,fname); ! 141: if((file=nopen(str,O_RDONLY))==-1) { ! 142: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 143: answers[0]=0; ! 144: return; } ! 145: length=filelength(file); ! 146: if((buf=(char *)MALLOC(length))==0) { ! 147: close(file); ! 148: errormsg(WHERE,ERR_ALLOC,str,length); ! 149: answers[0]=0; ! 150: return; } ! 151: if(lread(file,buf,length)!=length) { ! 152: close(file); ! 153: errormsg(WHERE,ERR_READ,str,length); ! 154: answers[0]=0; ! 155: return; } ! 156: close(file); ! 157: while(l<length && online) { ! 158: mode=min=max=t=cr=0; ! 159: top=l; ! 160: while(l<length && buf[l++]!=STX); ! 161: for(m=l;m<length;m++) ! 162: if(buf[m]==ETX || !buf[m]) { ! 163: buf[m]=0; ! 164: break; } ! 165: if(l>=length) break; ! 166: if(online==ON_REMOTE) { ! 167: rioctl(IOCM|ABORT); ! 168: rioctl(IOCS|ABORT); } ! 169: putmsg(buf+l,P_SAVEATR); ! 170: m++; ! 171: if(toupper(buf[m])!='C' && toupper(buf[m])!='S') ! 172: continue; ! 173: SYNC; ! 174: if(online==ON_REMOTE) ! 175: rioctl(IOSM|ABORT); ! 176: if(a>=len) { ! 177: errormsg(WHERE,ERR_LEN,fname,len); ! 178: break; } ! 179: if((buf[m]&0xdf)=='C') { ! 180: if((buf[m+1]&0xdf)=='U') { /* Uppercase only */ ! 181: mode|=K_UPPER; ! 182: m++; } ! 183: else if((buf[m+1]&0xdf)=='N') { /* Numbers only */ ! 184: mode|=K_NUMBER; ! 185: m++; } ! 186: if((buf[m+1]&0xdf)=='L') { /* Draw line */ ! 187: if(useron.misc&COLOR) ! 188: attr(cfg.color[clr_inputline]); ! 189: else ! 190: attr(BLACK|(LIGHTGRAY<<4)); ! 191: bputs(" \b"); ! 192: m++; } ! 193: if((buf[m+1]&0xdf)=='R') { /* Add CRLF */ ! 194: cr=1; ! 195: m++; } ! 196: if(buf[m+1]=='"') { ! 197: m+=2; ! 198: for(l=m;l<length;l++) ! 199: if(buf[l]=='"') { ! 200: buf[l]=0; ! 201: break; } ! 202: answers[a++]=(char)getkeys((char *)buf+m,0); } ! 203: else { ! 204: answers[a]=getkey(mode); ! 205: outchar(answers[a++]); ! 206: attr(LIGHTGRAY); ! 207: CRLF; } ! 208: if(cr) { ! 209: answers[a++]=CR; ! 210: answers[a++]=LF; } } ! 211: else if((buf[m]&0xdf)=='S') { /* String */ ! 212: if((buf[m+1]&0xdf)=='U') { /* Uppercase only */ ! 213: mode|=K_UPPER; ! 214: m++; } ! 215: else if((buf[m+1]&0xdf)=='F') { /* Force Upper/Lowr case */ ! 216: mode|=K_UPRLWR; ! 217: m++; } ! 218: else if((buf[m+1]&0xdf)=='N') { /* Numbers only */ ! 219: mode|=K_NUMBER; ! 220: m++; } ! 221: if((buf[m+1]&0xdf)=='L') { /* Draw line */ ! 222: mode|=K_LINE; ! 223: m++; } ! 224: if((buf[m+1]&0xdf)=='R') { /* Add CRLF */ ! 225: cr=1; ! 226: m++; } ! 227: if(isdigit(buf[m+1])) { ! 228: max=buf[++m]&0xf; ! 229: if(isdigit(buf[m+1])) ! 230: max=max*10+(buf[++m]&0xf); } ! 231: if(buf[m+1]=='.' && isdigit(buf[m+2])) { ! 232: m++; ! 233: min=buf[++m]&0xf; ! 234: if(isdigit(buf[m+1])) ! 235: min=min*10+(buf[++m]&0xf); } ! 236: if(buf[m+1]=='"') { ! 237: m++; ! 238: mode&=~K_NUMBER; ! 239: while(buf[++m]!='"' && t<80) ! 240: tmplt[t++]=buf[m]; ! 241: tmplt[t]=0; ! 242: max=strlen(tmplt); } ! 243: if(t) { ! 244: if(gettmplt(str,tmplt,mode)<min) { ! 245: l=top; ! 246: continue; } } ! 247: else { ! 248: if(!max) ! 249: continue; ! 250: if(getstr(str,max,mode)<min) { ! 251: l=top; ! 252: continue; } } ! 253: if(!cr) { ! 254: for(cr=0;str[cr];cr++) ! 255: answers[a+cr]=str[cr]; ! 256: while(cr<max) ! 257: answers[a+cr++]=ETX; ! 258: a+=max; } ! 259: else { ! 260: putrec(answers,a,max,str); ! 261: putrec(answers,a+max,2,crlf); ! 262: a+=max+2; } } } ! 263: answers[a]=0; ! 264: FREE((char *)buf); ! 265: } ! 266: ! 267: /****************************************************************************/ ! 268: /* SIF output function. See SIF.DOC for more info */ ! 269: /****************************************************************************/ ! 270: void sbbs_t::sof(char *fname, char *answers, long len) ! 271: { ! 272: char str[256],HUGE16 *buf,max,min,cr; ! 273: int file; ! 274: long length,l=0,m,a=0; ! 275: ! 276: sprintf(str,"%s%s.sif",cfg.text_dir,fname); ! 277: if((file=nopen(str,O_RDONLY))==-1) { ! 278: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 279: answers[0]=0; ! 280: return; } ! 281: length=filelength(file); ! 282: if((buf=(char *)MALLOC(length))==0) { ! 283: close(file); ! 284: errormsg(WHERE,ERR_ALLOC,str,length); ! 285: answers[0]=0; ! 286: return; } ! 287: if(lread(file,buf,length)!=length) { ! 288: close(file); ! 289: errormsg(WHERE,ERR_READ,str,length); ! 290: answers[0]=0; ! 291: return; } ! 292: close(file); ! 293: while(l<length && online) { ! 294: min=max=cr=0; ! 295: while(l<length && buf[l++]!=STX); ! 296: for(m=l;m<length;m++) ! 297: if(buf[m]==ETX || !buf[m]) { ! 298: buf[m]=0; ! 299: break; } ! 300: if(l>=length) break; ! 301: if(online==ON_REMOTE) { ! 302: rioctl(IOCM|ABORT); ! 303: rioctl(IOCS|ABORT); } ! 304: putmsg(buf+l,P_SAVEATR); ! 305: m++; ! 306: if(toupper(buf[m])!='C' && toupper(buf[m])!='S') ! 307: continue; ! 308: SYNC; ! 309: if(online==ON_REMOTE) ! 310: rioctl(IOSM|ABORT); ! 311: if(a>=len) { ! 312: bprintf("\r\nSOF: %s defined more data than buffer size " ! 313: "(%lu bytes)\r\n",fname,len); ! 314: break; } ! 315: if((buf[m]&0xdf)=='C') { ! 316: if((buf[m+1]&0xdf)=='U') /* Uppercase only */ ! 317: m++; ! 318: else if((buf[m+1]&0xdf)=='N') /* Numbers only */ ! 319: m++; ! 320: if((buf[m+1]&0xdf)=='L') { /* Draw line */ ! 321: if(useron.misc&COLOR) ! 322: attr(cfg.color[clr_inputline]); ! 323: else ! 324: attr(BLACK|(LIGHTGRAY<<4)); ! 325: bputs(" \b"); ! 326: m++; } ! 327: if((buf[m+1]&0xdf)=='R') { /* Add CRLF */ ! 328: cr=1; ! 329: m++; } ! 330: outchar(answers[a++]); ! 331: attr(LIGHTGRAY); ! 332: CRLF; ! 333: if(cr) ! 334: a+=2; } ! 335: else if((buf[m]&0xdf)=='S') { /* String */ ! 336: if((buf[m+1]&0xdf)=='U') ! 337: m++; ! 338: else if((buf[m+1]&0xdf)=='F') ! 339: m++; ! 340: else if((buf[m+1]&0xdf)=='N') /* Numbers only */ ! 341: m++; ! 342: if((buf[m+1]&0xdf)=='L') { ! 343: if(useron.misc&COLOR) ! 344: attr(cfg.color[clr_inputline]); ! 345: else ! 346: attr(BLACK|(LIGHTGRAY<<4)); ! 347: m++; } ! 348: if((buf[m+1]&0xdf)=='R') { ! 349: cr=1; ! 350: m++; } ! 351: if(isdigit(buf[m+1])) { ! 352: max=buf[++m]&0xf; ! 353: if(isdigit(buf[m+1])) ! 354: max=max*10+(buf[++m]&0xf); } ! 355: if(buf[m+1]=='.' && isdigit(buf[m+2])) { ! 356: m++; ! 357: min=buf[++m]&0xf; ! 358: if(isdigit(buf[m+1])) ! 359: min=min*10+(buf[++m]&0xf); } ! 360: if(buf[m+1]=='"') { ! 361: max=0; ! 362: m++; ! 363: while(buf[++m]!='"' && max<80) ! 364: max++; } ! 365: if(!max) ! 366: continue; ! 367: getrec(answers,a,max,str); ! 368: bputs(str); ! 369: attr(LIGHTGRAY); ! 370: CRLF; ! 371: if(!cr) ! 372: a+=max; ! 373: else ! 374: a+=max+2; } } ! 375: FREE((char *)buf); ! 376: } ! 377: ! 378: /****************************************************************************/ ! 379: /* Creates data file 'datfile' from input via sif file 'siffile' */ ! 380: /****************************************************************************/ ! 381: void sbbs_t::create_sif_dat(char *siffile, char *datfile) ! 382: { ! 383: char *buf; ! 384: int file; ! 385: ! 386: if((buf=(char *)MALLOC(SIF_MAXBUF))==NULL) { ! 387: errormsg(WHERE,ERR_ALLOC,siffile,SIF_MAXBUF); ! 388: return; } ! 389: memset(buf,SIF_MAXBUF,0); /* initialize to null */ ! 390: sif(siffile,buf,SIF_MAXBUF); ! 391: if((file=nopen(datfile,O_WRONLY|O_TRUNC|O_CREAT))==-1) { ! 392: FREE(buf); ! 393: errormsg(WHERE,ERR_OPEN,datfile,O_WRONLY|O_TRUNC|O_CREAT); ! 394: return; } ! 395: write(file,buf,strlen(buf)); ! 396: close(file); ! 397: FREE(buf); ! 398: } ! 399: ! 400: /****************************************************************************/ ! 401: /* Reads data file 'datfile' and displays output via sif file 'siffile' */ ! 402: /****************************************************************************/ ! 403: void sbbs_t::read_sif_dat(char *siffile, char *datfile) ! 404: { ! 405: char *buf; ! 406: int file; ! 407: long length; ! 408: ! 409: if((file=nopen(datfile,O_RDONLY))==-1) { ! 410: errormsg(WHERE,ERR_OPEN,datfile,O_RDONLY); ! 411: return; } ! 412: length=filelength(file); ! 413: if(!length) { ! 414: close(file); ! 415: return; } ! 416: if((buf=(char *)MALLOC(length))==NULL) { ! 417: close(file); ! 418: errormsg(WHERE,ERR_ALLOC,datfile,length); ! 419: return; } ! 420: read(file,buf,length); ! 421: close(file); ! 422: sof(siffile,buf,length); ! 423: FREE(buf); ! 424: } ! 425: ! 426: /****************************************************************************/ ! 427: /* Get string by template. A=Alpha, N=Number, !=Anything */ ! 428: /* First character MUST be an A,N or !. */ ! 429: /* Modes - K_LINE and K_UPPER are supported. */ ! 430: /****************************************************************************/ ! 431: uint sbbs_t::gettmplt(char *strout,char *templt, long mode) ! 432: { ! 433: char ch,str[256]; ! 434: char tmplt[128]; ! 435: uint t=strlen(templt),c=0; ! 436: ! 437: sys_status&=~SS_ABORT; ! 438: sprintf(tmplt, "%.*s",sizeof(tmplt)-1, templt); ! 439: strupr(tmplt); ! 440: if(useron.misc&ANSI) { ! 441: if(mode&K_LINE) { ! 442: if(useron.misc&COLOR) ! 443: attr(cfg.color[clr_inputline]); ! 444: else ! 445: attr(BLACK|(LIGHTGRAY<<4)); } ! 446: while(c<t) { ! 447: if(tmplt[c]=='N' || tmplt[c]=='A' || tmplt[c]=='!') ! 448: outchar(SP); ! 449: else ! 450: outchar(tmplt[c]); ! 451: c++; } ! 452: bprintf("\x1b[%dD",t); } ! 453: c=0; ! 454: if(mode&K_EDIT) { ! 455: strcpy(str,strout); ! 456: bputs(str); ! 457: c=strlen(str); } ! 458: while((ch=getkey(mode))!=CR && online && !(sys_status&SS_ABORT)) { ! 459: if(ch==BS) { ! 460: if(!c) ! 461: continue; ! 462: for(ch=1,c--;c;c--,ch++) ! 463: if(tmplt[c]=='N' || tmplt[c]=='A' || tmplt[c]=='!') ! 464: break; ! 465: if(useron.misc&ANSI) ! 466: bprintf("\x1b[%dD",ch); ! 467: else while(ch--) ! 468: outchar(BS); ! 469: bputs(" \b"); ! 470: continue; } ! 471: if(ch==24) { /* Ctrl-X */ ! 472: for(;c;c--) { ! 473: outchar(BS); ! 474: if(tmplt[c-1]=='N' || tmplt[c-1]=='A' || tmplt[c-1]=='!') ! 475: bputs(" \b"); ! 476: } ! 477: } ! 478: else if(c<t) { ! 479: if(tmplt[c]=='N' && !isdigit(ch)) ! 480: continue; ! 481: if(tmplt[c]=='A' && !isalpha(ch)) ! 482: continue; ! 483: outchar(ch); ! 484: str[c++]=ch; ! 485: while(c<t && tmplt[c]!='N' && tmplt[c]!='A' && tmplt[c]!='!'){ ! 486: str[c]=tmplt[c]; ! 487: outchar(tmplt[c++]); } } } ! 488: str[c]=0; ! 489: attr(LIGHTGRAY); ! 490: CRLF; ! 491: if(!(sys_status&SS_ABORT)) ! 492: strcpy(strout,str); ! 493: return(c); ! 494: } ! 495: ! 496: /*****************************************************************************/ ! 497: /* Accepts a user's input to change a new-scan time pointer */ ! 498: /* Returns 0 if input was aborted or invalid, 1 if complete */ ! 499: /*****************************************************************************/ ! 500: bool sbbs_t::inputnstime(time_t *dt) ! 501: { ! 502: int hour; ! 503: struct tm tm; ! 504: struct tm * tp; ! 505: char pm,str[256]; ! 506: ! 507: bputs(text[NScanDate]); ! 508: bputs(timestr(dt)); ! 509: CRLF; ! 510: tp=gmtime(dt); ! 511: if(tp==NULL) { ! 512: errormsg(WHERE,ERR_CHK,"time ptr",0); ! 513: return(FALSE); ! 514: } ! 515: tm=*tp; ! 516: ! 517: bputs(text[NScanYear]); ! 518: ultoa(tm.tm_year+1900,str,10); ! 519: if(!getstr(str,4,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) { ! 520: CRLF; ! 521: return(false); } ! 522: tm.tm_year=atoi(str); ! 523: if(tm.tm_year<1970) { /* unix time is seconds since 1/1/1970 */ ! 524: CRLF; ! 525: return(false); } ! 526: tm.tm_year-=1900; /* tm_year is years since 1900 */ ! 527: ! 528: bputs(text[NScanMonth]); ! 529: ultoa(tm.tm_mon+1,str,10); ! 530: if(!getstr(str,2,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) { ! 531: CRLF; ! 532: return(false); } ! 533: tm.tm_mon=atoi(str); ! 534: if(tm.tm_mon<1 || tm.tm_mon>12) { ! 535: CRLF; ! 536: return(false); } ! 537: tm.tm_mon--; /* tm_mon is zero-based */ ! 538: ! 539: bputs(text[NScanDay]); ! 540: ultoa(tm.tm_mday,str,10); ! 541: if(!getstr(str,2,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) { ! 542: CRLF; ! 543: return(false); } ! 544: tm.tm_mday=atoi(str); ! 545: if(tm.tm_mday<1 || tm.tm_mday>31) { ! 546: CRLF; ! 547: return(false); } ! 548: bputs(text[NScanHour]); ! 549: if(cfg.sys_misc&SM_MILITARY) ! 550: hour=tm.tm_hour; ! 551: else { ! 552: if(tm.tm_hour==0) { /* 12 midnite */ ! 553: pm=0; ! 554: hour=12; } ! 555: else if(tm.tm_hour>12) { ! 556: hour=tm.tm_hour-12; ! 557: pm=1; } ! 558: else { ! 559: hour=tm.tm_hour; ! 560: pm=0; } } ! 561: ultoa(hour,str,10); ! 562: if(!getstr(str,2,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) { ! 563: CRLF; ! 564: return(false); } ! 565: tm.tm_hour=atoi(str); ! 566: if(tm.tm_hour>24) { ! 567: CRLF; ! 568: return(false); } ! 569: ! 570: bputs(text[NScanMinute]); ! 571: ultoa(tm.tm_min,str,10); ! 572: if(!getstr(str,2,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) { ! 573: CRLF; ! 574: return(false); } ! 575: ! 576: tm.tm_min=atoi(str); ! 577: if(tm.tm_min>59) { ! 578: CRLF; ! 579: return(false); } ! 580: tm.tm_sec=0; ! 581: if(!(cfg.sys_misc&SM_MILITARY) && tm.tm_hour && tm.tm_hour<13) { ! 582: if(pm && yesno(text[NScanPmQ])) { ! 583: if(tm.tm_hour<12) ! 584: tm.tm_hour+=12; } ! 585: else if(!pm && !yesno(text[NScanAmQ])) { ! 586: if(tm.tm_hour<12) ! 587: tm.tm_hour+=12; } ! 588: else if(tm.tm_hour==12) ! 589: tm.tm_hour=0; } ! 590: else { ! 591: CRLF; } ! 592: *dt=mktime(&tm); ! 593: return(true); ! 594: } ! 595: ! 596: /*****************************************************************************/ ! 597: /* Checks a password for uniqueness and validity */ ! 598: /*****************************************************************************/ ! 599: bool sbbs_t::chkpass(char *pass, user_t* user, bool unique) ! 600: { ! 601: char c,d,first[128],last[128],sysop[41],sysname[41],*p; ! 602: char alias[LEN_ALIAS+1], name[LEN_NAME+1], handle[LEN_HANDLE+1]; ! 603: ! 604: if(strlen(pass)<4) { ! 605: bputs(text[PasswordTooShort]); ! 606: return(0); } ! 607: if(!strcmp(pass,user->pass)) { ! 608: bputs(text[PasswordNotChanged]); ! 609: return(0); } ! 610: d=strlen(pass); ! 611: for(c=1;c<d;c++) ! 612: if(pass[c]!=pass[c-1]) ! 613: break; ! 614: if(c==d) { ! 615: bputs(text[PasswordInvalid]); ! 616: return(0); } ! 617: for(c=0;c<3;c++) /* check for 1234 and ABCD */ ! 618: if(pass[c]!=pass[c+1]+1) ! 619: break; ! 620: if(c==3) { ! 621: bputs(text[PasswordObvious]); ! 622: return(0); } ! 623: for(c=0;c<3;c++) /* check for 4321 and ZYXW */ ! 624: if(pass[c]!=pass[c+1]-1) ! 625: break; ! 626: if(c==3) { ! 627: bputs(text[PasswordObvious]); ! 628: return(0); } ! 629: strcpy(name,user->name); ! 630: strupr(name); ! 631: strcpy(alias,user->alias); ! 632: strupr(alias); ! 633: strcpy(first,alias); ! 634: p=strchr(first,SP); ! 635: if(p) { ! 636: *p=0; ! 637: strcpy(last,p+1); } ! 638: else ! 639: last[0]=0; ! 640: strcpy(handle,user->handle); ! 641: strupr(handle); ! 642: strcpy(sysop,cfg.sys_op); ! 643: strupr(sysop); ! 644: strcpy(sysname,cfg.sys_name); ! 645: strupr(sysname); ! 646: if((unique && user->pass[0] ! 647: && (strstr(pass,user->pass) || strstr(user->pass,pass))) ! 648: || (name[0] ! 649: && (strstr(pass,name) || strstr(name,pass))) ! 650: || strstr(pass,alias) || strstr(alias,pass) ! 651: || strstr(pass,first) || strstr(first,pass) ! 652: || (last[0] ! 653: && (strstr(pass,last) || strstr(last,pass))) ! 654: || strstr(pass,handle) || strstr(handle,pass) ! 655: || (user->zipcode[0] ! 656: && (strstr(pass,user->zipcode) || strstr(user->zipcode,pass))) ! 657: || (sysname[0] ! 658: && (strstr(pass,sysname) || strstr(sysname,pass))) ! 659: || (sysop[0] ! 660: && (strstr(pass,sysop) || strstr(sysop,pass))) ! 661: || (cfg.sys_id[0] ! 662: && (strstr(pass,cfg.sys_id) || strstr(cfg.sys_id,pass))) ! 663: || (cfg.node_phone[0] && strstr(pass,cfg.node_phone)) ! 664: || (user->phone[0] && strstr(user->phone,pass)) ! 665: || !strncmp(pass,"QWER",3) ! 666: || !strncmp(pass,"ASDF",3) ! 667: || !strncmp(pass,"!@#$",3) ! 668: ) ! 669: { ! 670: bputs(text[PasswordObvious]); ! 671: return(0); } ! 672: return(1); ! 673: } ! 674: ! 675: /****************************************************************************/ ! 676: /* Displays information about sub-board subnum */ ! 677: /****************************************************************************/ ! 678: void sbbs_t::subinfo(uint subnum) ! 679: { ! 680: char str[256]; ! 681: ! 682: bputs(text[SubInfoHdr]); ! 683: bprintf(text[SubInfoLongName],cfg.sub[subnum]->lname); ! 684: bprintf(text[SubInfoShortName],cfg.sub[subnum]->sname); ! 685: bprintf(text[SubInfoQWKName],cfg.sub[subnum]->qwkname); ! 686: bprintf(text[SubInfoMaxMsgs],cfg.sub[subnum]->maxmsgs); ! 687: if(cfg.sub[subnum]->misc&SUB_QNET) ! 688: bprintf(text[SubInfoTagLine],cfg.sub[subnum]->tagline); ! 689: if(cfg.sub[subnum]->misc&SUB_FIDO) ! 690: bprintf(text[SubInfoFidoNet] ! 691: ,cfg.sub[subnum]->origline ! 692: ,faddrtoa(cfg.sub[subnum]->faddr)); ! 693: sprintf(str,"%s%s.msg",cfg.sub[subnum]->data_dir,cfg.sub[subnum]->code); ! 694: if(fexist(str) && yesno(text[SubInfoViewFileQ])) ! 695: printfile(str,0); ! 696: } ! 697: ! 698: /****************************************************************************/ ! 699: /* Displays information about transfer directory dirnum */ ! 700: /****************************************************************************/ ! 701: void sbbs_t::dirinfo(uint dirnum) ! 702: { ! 703: char str[256]; ! 704: ! 705: bputs(text[DirInfoHdr]); ! 706: bprintf(text[DirInfoLongName],cfg.dir[dirnum]->lname); ! 707: bprintf(text[DirInfoShortName],cfg.dir[dirnum]->sname); ! 708: if(cfg.dir[dirnum]->exts[0]) ! 709: bprintf(text[DirInfoAllowedExts],cfg.dir[dirnum]->exts); ! 710: bprintf(text[DirInfoMaxFiles],cfg.dir[dirnum]->maxfiles); ! 711: sprintf(str,"%s%s.msg",cfg.dir[dirnum]->data_dir,cfg.dir[dirnum]->code); ! 712: if(fexist(str) && yesno(text[DirInfoViewFileQ])) ! 713: printfile(str,0); ! 714: } ! 715: ! 716: /****************************************************************************/ ! 717: /* Searches the file <name>.can in the TEXT directory for matches */ ! 718: /* Returns 1 if found in list, 0 if not. */ ! 719: /****************************************************************************/ ! 720: extern "C" BOOL DLLCALL trashcan(scfg_t* cfg, char* insearch, char* name) ! 721: { ! 722: char* p; ! 723: char str[128]; ! 724: char search[81]; ! 725: int c; ! 726: BOOL found; ! 727: FILE* stream; ! 728: ! 729: sprintf(str,"%s%s.can",cfg->text_dir,name); ! 730: ! 731: if((stream=fopen(str,"r"))==NULL) ! 732: return(FALSE); ! 733: ! 734: sprintf(search,"%.*s",sizeof(search)-1,insearch); ! 735: strupr(search); ! 736: ! 737: found=FALSE; ! 738: ! 739: while(!feof(stream) && !ferror(stream) && !found) { ! 740: if(!fgets(str,sizeof(str),stream)) ! 741: break; ! 742: ! 743: found=FALSE; ! 744: ! 745: p=str; ! 746: while(*p && *p<=' ') p++; /* Skip white-space */ ! 747: ! 748: if(*p==';') /* comment */ ! 749: continue; ! 750: ! 751: if(*p=='!') { /* !match */ ! 752: found=TRUE; ! 753: p++; ! 754: } ! 755: ! 756: truncsp(p); ! 757: c=strlen(p); ! 758: if(c) { ! 759: c--; ! 760: strupr(p); ! 761: if(p[c]=='~') { ! 762: p[c]=0; ! 763: if(strstr(search,p)) ! 764: found=!found; ! 765: } ! 766: ! 767: else if(p[c]=='^') { ! 768: p[c]=0; ! 769: if(!strncmp(p,search,c)) ! 770: found=!found; ! 771: } ! 772: ! 773: else if(!strcmp(p,search)) ! 774: found=!found; ! 775: } ! 776: } ! 777: fclose(stream); ! 778: return(found); ! 779: } ! 780: ! 781: bool sbbs_t::trashcan(char *insearch, char *name) ! 782: { ! 783: char str[256]; ! 784: bool result; ! 785: ! 786: result=::trashcan(&cfg, insearch, name); ! 787: if(result) { ! 788: sprintf(str,"%sbad%s.msg",cfg.text_dir,name); ! 789: if(fexist(str)) ! 790: printfile(str,0); ! 791: } ! 792: return(result); ! 793: } ! 794: ! 795: ! 796: /****************************************************************************/ ! 797: /* Error handling routine. Prints to local and remote screens the error */ ! 798: /* information, function, action, object and access and then attempts to */ ! 799: /* write the error information into the file ERROR.LOG and NODE.LOG */ ! 800: /****************************************************************************/ ! 801: void sbbs_t::errormsg(int line, char *source, char action, char *object ! 802: ,ulong access, char *extinfo) ! 803: { ! 804: char str[512]; ! 805: char tmp[512]; ! 806: char actstr[256]; ! 807: ! 808: if(errormsg_inside) ! 809: return; ! 810: errormsg_inside=true; ! 811: switch(action) { ! 812: case ERR_OPEN: ! 813: strcpy(actstr,"opening"); ! 814: break; ! 815: case ERR_CLOSE: ! 816: strcpy(actstr,"closing"); ! 817: break; ! 818: case ERR_FDOPEN: ! 819: strcpy(actstr,"fdopen"); ! 820: break; ! 821: case ERR_READ: ! 822: strcpy(actstr,"reading"); ! 823: break; ! 824: case ERR_WRITE: ! 825: strcpy(actstr,"writing"); ! 826: break; ! 827: case ERR_REMOVE: ! 828: strcpy(actstr,"removing"); ! 829: break; ! 830: case ERR_ALLOC: ! 831: strcpy(actstr,"allocating memory"); ! 832: break; ! 833: case ERR_CHK: ! 834: strcpy(actstr,"checking"); ! 835: break; ! 836: case ERR_LEN: ! 837: strcpy(actstr,"checking length"); ! 838: break; ! 839: case ERR_EXEC: ! 840: strcpy(actstr,"executing"); ! 841: break; ! 842: case ERR_CHDIR: ! 843: strcpy(actstr,"changing directory"); ! 844: break; ! 845: case ERR_CREATE: ! 846: strcpy(actstr,"creating"); ! 847: break; ! 848: case ERR_LOCK: ! 849: strcpy(actstr,"locking"); ! 850: break; ! 851: case ERR_UNLOCK: ! 852: strcpy(actstr,"unlocking"); ! 853: break; ! 854: case ERR_TIMEOUT: ! 855: strcpy(actstr,"time-out waiting for resource"); ! 856: break; ! 857: case ERR_IOCTL: ! 858: strcpy(actstr,"sending IOCTL"); ! 859: break; ! 860: default: ! 861: strcpy(actstr,"UNKNOWN"); } ! 862: lprintf("!Node %d: ERROR %d (0x%X) in %s line %d %s %s access=%d" ! 863: ,cfg.node_num, errno, errno, source, line, actstr, object, access); ! 864: bprintf("\7\r\nERROR - action: %s",actstr); /* tell user about error */ ! 865: bprintf("\7\r\n object: %s",object); ! 866: bprintf("\7\r\n access: %ld",access); ! 867: if(access>9 && (long)access!=-1 && (short)access!=-1 && (char)access!=-1) ! 868: bprintf(" (%lXh)",access); ! 869: if(cfg.sys_misc&SM_ERRALARM) { ! 870: sbbs_beep(500,220); sbbs_beep(250,220); ! 871: sbbs_beep(500,220); sbbs_beep(250,220); ! 872: sbbs_beep(500,220); sbbs_beep(250,220); ! 873: nosound(); } ! 874: bputs("\r\n\r\nThe sysop has been notified. <Hit a key>"); ! 875: getkey(0); ! 876: CRLF; ! 877: sprintf(str,"\r\n source: %s\r\n line: %d\r\n action: %s\r\n" ! 878: " object: %s\r\n access: %ld" ! 879: ,source,line,actstr,object,access); ! 880: if(access>9 && (long)access!=-1 && (short)access!=-1 && (char)access!=-1) { ! 881: sprintf(tmp," (%lXh)",access); ! 882: strcat(str,tmp); } ! 883: if(extinfo!=NULL) { ! 884: sprintf(tmp,"\r\n info: %s",extinfo); ! 885: strcat(str,tmp); ! 886: } ! 887: if(errno) { ! 888: sprintf(tmp,"\r\n errno: %d",errno); ! 889: strcat(str,tmp); ! 890: } ! 891: #if defined(__MSDOS__) || defined(_WIN32) ! 892: if(_doserrno && _doserrno!=(ulong)errno) { ! 893: sprintf(tmp,"\r\n doserrno: %d",_doserrno); ! 894: strcat(str,tmp); ! 895: } ! 896: errno=_doserrno=0; ! 897: #endif ! 898: #if defined(_WIN32) ! 899: if(GetLastError()!=0) { ! 900: sprintf(tmp,"\r\n winerrno: %d (0x%X)",GetLastError(), GetLastError()); ! 901: strcat(str,tmp); ! 902: } ! 903: #endif ! 904: errorlog(str); ! 905: errormsg_inside=false; ! 906: } ! 907: ! 908: /*****************************************************************************/ ! 909: /* Error logging to NODE.LOG and DATA\ERROR.LOG function */ ! 910: /*****************************************************************************/ ! 911: void sbbs_t::errorlog(char *text) ! 912: { ! 913: char hdr[256],str[256],tmp2[256]; ! 914: int file; ! 915: ! 916: if(errorlog_inside) /* let's not go recursive on this puppy */ ! 917: return; ! 918: errorlog_inside=1; ! 919: if(cfg.node_num>0) { ! 920: getnodedat(cfg.node_num,&thisnode,1); ! 921: criterrs=++thisnode.errors; ! 922: putnodedat(cfg.node_num,&thisnode); ! 923: } ! 924: now=time(NULL); ! 925: logline("!!",text); ! 926: sprintf(str,"%serror.log",cfg.data_dir); ! 927: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) { ! 928: sprintf(tmp2,"ERROR opening/creating %s",str); ! 929: logline("!!",tmp2); ! 930: errorlog_inside=0; ! 931: return; } ! 932: sprintf(hdr,"%s Node %2d: %s #%d" ! 933: ,timestr(&now),cfg.node_num,useron.alias,useron.number); ! 934: write(file,hdr,strlen(hdr)); ! 935: write(file,crlf,2); ! 936: write(file,text,strlen(text)); ! 937: write(file,"\r\n\r\n",4); ! 938: close(file); ! 939: errorlog_inside=0; ! 940: } ! 941: ! 942: /****************************************************************************/ ! 943: /* Generates a 24 character ASCII string that represents the time_t pointer */ ! 944: /* Used as a replacement for ctime() */ ! 945: /****************************************************************************/ ! 946: char * sbbs_t::timestr(time_t *intime) ! 947: { ! 948: char mer[3],hour; ! 949: struct tm *gm; ! 950: ! 951: gm=localtime(intime); ! 952: if(gm==NULL) { ! 953: strcpy(timestr_output,"Invalid Time"); ! 954: return(timestr_output); } ! 955: if(cfg.sys_misc&SM_MILITARY) { ! 956: sprintf(timestr_output,"%s %s %02d %4d %02d:%02d:%02d" ! 957: ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year ! 958: ,gm->tm_hour,gm->tm_min,gm->tm_sec); ! 959: return(timestr_output); } ! 960: if(gm->tm_hour>=12) { ! 961: if(gm->tm_hour==12) ! 962: hour=12; ! 963: else ! 964: hour=gm->tm_hour-12; ! 965: strcpy(mer,"pm"); } ! 966: else { ! 967: if(gm->tm_hour==0) ! 968: hour=12; ! 969: else ! 970: hour=gm->tm_hour; ! 971: strcpy(mer,"am"); } ! 972: sprintf(timestr_output,"%s %s %02d %4d %02d:%02d %s" ! 973: ,wday[gm->tm_wday],mon[gm->tm_mon],gm->tm_mday,1900+gm->tm_year ! 974: ,hour,gm->tm_min,mer); ! 975: return(timestr_output); ! 976: } ! 977:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.