home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / STR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-13  |  27.1 KB  |  1,081 lines

  1. #line 1 "STR.C"
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. /*****************************************************/
  6. /* Functions that perform lengthy string i/o rotines */
  7. /*****************************************************/
  8.  
  9. #include "sbbs.h"
  10.  
  11. /****************************************************************************/
  12. /* Lists all users who have access to the current sub.                      */
  13. /****************************************************************************/
  14. void userlist(char mode)
  15. {
  16.     uchar name[256],sort=0;
  17.     int i,j,k,users=0;
  18.     uchar *line[1000];
  19.     user_t user;
  20.  
  21. if(lastuser()<=1000)
  22.     sort=yesno(text[SortAlphaQ]);
  23. if(sort) {
  24.     bputs(text[CheckingSlots]); }
  25. else {
  26.     CRLF; }
  27. j=0;
  28. k=lastuser();
  29. for(i=1;i<=k && !msgabort();i++) {
  30.     if(sort && (online==ON_LOCAL || !rioctl(TXBC)))
  31.         bprintf("%-4d\b\b\b\b",i);
  32.     user.number=i;
  33.     getuserdat(&user);
  34.     if(user.misc&(DELETED|INACTIVE))
  35.         continue;
  36.     users++;
  37.     if(mode==UL_SUB) {
  38.         if(!usrgrps)
  39.             continue;
  40.         if(!chk_ar(grp[usrgrp[curgrp]]->ar,user))
  41.             continue;
  42.         if(!chk_ar(sub[usrsub[curgrp][cursub[curgrp]]]->ar,user)
  43.             || (sub[usrsub[curgrp][cursub[curgrp]]]->read_ar[0]
  44.             && !chk_ar(sub[usrsub[curgrp][cursub[curgrp]]]->read_ar,user)))
  45.             continue; }
  46.     else if(mode==UL_DIR) {
  47.         if(user.rest&FLAG('T'))
  48.             continue;
  49.         if(!usrlibs)
  50.             continue;
  51.         if(!chk_ar(lib[usrlib[curlib]]->ar,user))
  52.             continue;
  53.         if(!chk_ar(dir[usrdir[curlib][curdir[curlib]]]->ar,user))
  54.             continue; }
  55.     if(sort) {
  56.         if((line[j]=(char *)MALLOC(128))==0) {
  57.             errormsg(WHERE,ERR_ALLOC,nulstr,83);
  58.             for(i=0;i<j;i++)
  59.                 FREE(line[i]);
  60.             return; }
  61.         sprintf(name,"%s #%d",user.alias,i);
  62.         sprintf(line[j],text[UserListFmt],name
  63.             ,sys_misc&SM_LISTLOC ? user.location : user.note
  64.             ,unixtodstr(user.laston,tmp)
  65.             ,user.modem); }
  66.     else {
  67.         sprintf(name,"%s #%u",user.alias,i);
  68.         bprintf(text[UserListFmt],name
  69.             ,sys_misc&SM_LISTLOC ? user.location : user.note
  70.             ,unixtodstr(user.laston,tmp)
  71.             ,user.modem); }
  72.     j++; }
  73. if(i<=k) {    /* aborted */
  74.     if(sort)
  75.         for(i=0;i<j;i++)
  76.             FREE(line[i]);
  77.     return; }
  78. if(!sort) {
  79.     CRLF; }
  80. bprintf(text[NTotalUsers],users);
  81. if(mode==UL_SUB)
  82.     bprintf(text[NUsersOnCurSub],j);
  83. else if(mode==UL_DIR)
  84.     bprintf(text[NUsersOnCurDir],j);
  85. if(!sort)
  86.     return;
  87. CRLF;
  88. qsort((void *)line,j,sizeof(line[0])
  89.     ,(int(*)(const void*, const void*))pstrcmp);
  90. for(i=0;i<j && !msgabort();i++)
  91.     bputs(line[i]);
  92. for(i=0;i<j;i++)
  93.     FREE(line[i]);
  94. }
  95.  
  96. /****************************************************************************/
  97. /* SIF input function. See SIF.DOC for more info                            */
  98. /****************************************************************************/
  99. void sif(char *fname, char *answers, long len)
  100. {
  101.     char str[256],template[256],HUGE16 *buf,t,max,min,mode,cr;
  102.     int file;
  103.     ulong length,l=0,m,top,a=0;
  104.  
  105. sprintf(str,"%s%s.SIF",text_dir,strupr(fname));
  106. if((file=nopen(str,O_RDONLY))==-1) {
  107.     errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
  108.     answers[0]=0;
  109.     return; }
  110. length=filelength(file);
  111. if((buf=(char *)MALLOC(length))==0) {
  112.     close(file);
  113.     errormsg(WHERE,ERR_ALLOC,str,length);
  114.     answers[0]=0;
  115.     return; }
  116. if(lread(file,buf,length)!=length) {
  117.     close(file);
  118.     errormsg(WHERE,ERR_READ,str,length);
  119.     answers[0]=0;
  120.     return; }
  121. close(file);
  122. while(l<length && online) {
  123.     mode=min=max=t=cr=0;
  124.     top=l;
  125.     while(l<length && buf[l++]!=STX);
  126.     for(m=l;m<length;m++)
  127.         if(buf[m]==ETX || !buf[m]) {
  128.             buf[m]=0;
  129.             break; }
  130.     if(l>=length) break;
  131.     if(online==ON_REMOTE) {
  132.         rioctl(IOCM|ABORT);
  133.         rioctl(IOCS|ABORT); }
  134.     putmsg(buf+l,P_SAVEATR);
  135.     m++;
  136.     if(toupper(buf[m])!='C' && toupper(buf[m])!='S')
  137.         continue;
  138.     SYNC;
  139.     if(online==ON_REMOTE)
  140.         rioctl(IOSM|ABORT);
  141.     if(a>=len) {
  142.         errormsg(WHERE,ERR_LEN,fname,len);
  143.         break; }
  144.     if((buf[m]&0xdf)=='C') {
  145.         if((buf[m+1]&0xdf)=='U') {        /* Uppercase only */
  146.             mode|=K_UPPER;
  147.             m++; }
  148.         else if((buf[m+1]&0xdf)=='N') {    /* Numbers only */
  149.             mode|=K_NUMBER;
  150.             m++; }
  151.         if((buf[m+1]&0xdf)=='L') {        /* Draw line */
  152.             if(useron.misc&COLOR)
  153.                 attr(color[clr_inputline]);
  154.             else
  155.                 attr(BLACK|(LIGHTGRAY<<4));
  156.             bputs(" \b");
  157.             m++; }
  158.         if((buf[m+1]&0xdf)=='R') {        /* Add CRLF */
  159.             cr=1;
  160.             m++; }
  161.         if(buf[m+1]=='"') {
  162.             m+=2;
  163.             for(l=m;l<length;l++)
  164.                 if(buf[l]=='"') {
  165.                     buf[l]=0;
  166.                     break; }
  167.             answers[a++]=getkeys((char *)buf+m,0); }
  168.         else {
  169.             answers[a]=getkey(mode);
  170.             outchar(answers[a++]);
  171.             attr(LIGHTGRAY);
  172.             CRLF; }
  173.         if(cr) {
  174.             answers[a++]=CR;
  175.             answers[a++]=LF; } }
  176.     else if((buf[m]&0xdf)=='S') {        /* String */
  177.         if((buf[m+1]&0xdf)=='U') {        /* Uppercase only */
  178.             mode|=K_UPPER;
  179.             m++; }
  180.         else if((buf[m+1]&0xdf)=='F') { /* Force Upper/Lowr case */
  181.             mode|=K_UPRLWR;
  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.             mode|=K_LINE;
  188.             m++; }
  189.         if((buf[m+1]&0xdf)=='R') {        /* Add CRLF */
  190.             cr=1;
  191.             m++; }
  192.         if(isdigit(buf[m+1])) {
  193.             max=buf[++m]&0xf;
  194.             if(isdigit(buf[m+1]))
  195.                 max=max*10+(buf[++m]&0xf); }
  196.         if(buf[m+1]=='.' && isdigit(buf[m+2])) {
  197.             m++;
  198.             min=buf[++m]&0xf;
  199.             if(isdigit(buf[m+1]))
  200.                 min=min*10+(buf[++m]&0xf); }
  201.         if(buf[m+1]=='"') {
  202.             m++;
  203.             mode&=~K_NUMBER;
  204.             while(buf[++m]!='"' && t<80)
  205.                 template[t++]=buf[m];
  206.             template[t]=0;
  207.             max=strlen(template); }
  208.         if(t) {
  209.             if(gettmplt(str,template,mode)<min) {
  210.                 l=top;
  211.                 continue; } }
  212.         else {
  213.             if(!max)
  214.                 continue;
  215.             if(getstr(str,max,mode)<min) {
  216.                 l=top;
  217.                 continue; } }
  218.         if(!cr) {
  219.             for(cr=0;str[cr];cr++)
  220.                 answers[a+cr]=str[cr];
  221.             while(cr<max)
  222.                 answers[a+cr++]=ETX;
  223.             a+=max; }
  224.         else {
  225.             putrec(answers,a,max,str);
  226.             putrec(answers,a+max,2,crlf);
  227.             a+=max+2; } } }
  228. answers[a]=0;
  229. FREE((char *)buf);
  230. }
  231.  
  232. /****************************************************************************/
  233. /* SIF output function. See SIF.DOC for more info                            */
  234. /****************************************************************************/
  235. void sof(char *fname, char *answers, long len)
  236. {
  237.     char str[256],HUGE16 *buf,max,min,cr;
  238.     int file;
  239.     ulong length,l=0,m,a=0;
  240.  
  241. sprintf(str,"%s%s.SIF",text_dir,strupr(fname));
  242. if((file=nopen(str,O_RDONLY))==-1) {
  243.     errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
  244.     answers[0]=0;
  245.     return; }
  246. length=filelength(file);
  247. if((buf=(char *)MALLOC(length))==0) {
  248.     close(file);
  249.     errormsg(WHERE,ERR_ALLOC,str,length);
  250.     answers[0]=0;
  251.     return; }
  252. if(lread(file,buf,length)!=length) {
  253.     close(file);
  254.     errormsg(WHERE,ERR_READ,str,length);
  255.     answers[0]=0;
  256.     return; }
  257. close(file);
  258. while(l<length && online) {
  259.     min=max=cr=0;
  260.     while(l<length && buf[l++]!=STX);
  261.     for(m=l;m<length;m++)
  262.         if(buf[m]==ETX || !buf[m]) {
  263.             buf[m]=0;
  264.             break; }
  265.     if(l>=length) break;
  266.     if(online==ON_REMOTE) {
  267.         rioctl(IOCM|ABORT);
  268.         rioctl(IOCS|ABORT); }
  269.     putmsg(buf+l,P_SAVEATR);
  270.     m++;
  271.     if(toupper(buf[m])!='C' && toupper(buf[m])!='S')
  272.         continue;
  273.     SYNC;
  274.     if(online==ON_REMOTE)
  275.         rioctl(IOSM|ABORT);
  276.     if(a>=len) {
  277.         bprintf("\r\nSOF: %s defined more data than buffer size "
  278.             "(%lu bytes)\r\n",fname,len);
  279.         break; }
  280.     if((buf[m]&0xdf)=='C') {
  281.         if((buf[m+1]&0xdf)=='U')          /* Uppercase only */
  282.             m++;
  283.         else if((buf[m+1]&0xdf)=='N')      /* Numbers only */
  284.             m++;
  285.         if((buf[m+1]&0xdf)=='L') {        /* Draw line */
  286.             if(useron.misc&COLOR)
  287.                 attr(color[clr_inputline]);
  288.             else
  289.                 attr(BLACK|(LIGHTGRAY<<4));
  290.             bputs(" \b");
  291.             m++; }
  292.         if((buf[m+1]&0xdf)=='R') {        /* Add CRLF */
  293.             cr=1;
  294.             m++; }
  295.         outchar(answers[a++]);
  296.         attr(LIGHTGRAY);
  297.         CRLF;
  298.         if(cr)
  299.             a+=2; }
  300.     else if((buf[m]&0xdf)=='S') {        /* String */
  301.         if((buf[m+1]&0xdf)=='U')
  302.             m++;
  303.         else if((buf[m+1]&0xdf)=='F')
  304.             m++;
  305.         else if((buf[m+1]&0xdf)=='N')   /* Numbers only */
  306.             m++;
  307.         if((buf[m+1]&0xdf)=='L') {
  308.             if(useron.misc&COLOR)
  309.                 attr(color[clr_inputline]);
  310.             else
  311.                 attr(BLACK|(LIGHTGRAY<<4));
  312.             m++; }
  313.         if((buf[m+1]&0xdf)=='R') {
  314.             cr=1;
  315.             m++; }
  316.         if(isdigit(buf[m+1])) {
  317.             max=buf[++m]&0xf;
  318.             if(isdigit(buf[m+1]))
  319.                 max=max*10+(buf[++m]&0xf); }
  320.         if(buf[m+1]=='.' && isdigit(buf[m+2])) {
  321.             m++;
  322.             min=buf[++m]&0xf;
  323.             if(isdigit(buf[m+1]))
  324.                 min=min*10+(buf[++m]&0xf); }
  325.         if(buf[m+1]=='"') {
  326.             max=0;
  327.             m++;
  328.             while(buf[++m]!='"' && max<80)
  329.                 max++; }
  330.         if(!max)
  331.             continue;
  332.         getrec(answers,a,max,str);
  333.         bputs(str);
  334.         attr(LIGHTGRAY);
  335.         CRLF;
  336.         if(!cr)
  337.             a+=max;
  338.         else
  339.             a+=max+2; } }
  340. FREE((char *)buf);
  341. }
  342.  
  343. /****************************************************************************/
  344. /* Creates data file 'datfile' from input via sif file 'siffile'            */
  345. /****************************************************************************/
  346. void create_sif_dat(char *siffile, char *datfile)
  347. {
  348.     char *buf;
  349.     int file;
  350.  
  351. if((buf=(char *)MALLOC(SIF_MAXBUF))==NULL) {
  352.     errormsg(WHERE,ERR_ALLOC,siffile,SIF_MAXBUF);
  353.     return; }
  354. memset(buf,SIF_MAXBUF,0);     /* initialize to null */
  355. sif(siffile,buf,SIF_MAXBUF);
  356. if((file=nopen(datfile,O_WRONLY|O_TRUNC|O_CREAT))==-1) {
  357.     FREE(buf);
  358.     errormsg(WHERE,ERR_OPEN,datfile,O_WRONLY|O_TRUNC|O_CREAT);
  359.     return; }
  360. write(file,buf,strlen(buf));
  361. close(file);
  362. FREE(buf);
  363. }
  364.  
  365. /****************************************************************************/
  366. /* Reads data file 'datfile' and displays output via sif file 'siffile'     */
  367. /****************************************************************************/
  368. void read_sif_dat(char *siffile, char *datfile)
  369. {
  370.     char *buf;
  371.     int file;
  372.     long length;
  373.  
  374. if((file=nopen(datfile,O_RDONLY))==-1) {
  375.     errormsg(WHERE,ERR_OPEN,datfile,O_RDONLY);
  376.     return; }
  377. length=filelength(file);
  378. if(!length) {
  379.     close(file);
  380.     return; }
  381. if((buf=(char *)MALLOC(length))==NULL) {
  382.     close(file);
  383.     errormsg(WHERE,ERR_ALLOC,datfile,length);
  384.     return; }
  385. read(file,buf,length);
  386. close(file);
  387. sof(siffile,buf,length);
  388. FREE(buf);
  389. }
  390.  
  391. /****************************************************************************/
  392. /* Get string by template. A=Alpha, N=Number, !=Anything                    */
  393. /* First character MUST be an A,N or !.                                     */
  394. /* Modes - K_LINE and K_UPPER are supported.                                */
  395. /****************************************************************************/
  396. char gettmplt(char *strout,char *template,int mode)
  397. {
  398.     uchar t=strlen(template),c=0,ch,str[256];
  399.  
  400. sys_status&=~SS_ABORT;
  401. strupr(template);
  402. if(useron.misc&ANSI) {
  403.     if(mode&K_LINE) {
  404.         if(useron.misc&COLOR)
  405.             attr(color[clr_inputline]);
  406.         else
  407.             attr(BLACK|(LIGHTGRAY<<4)); }
  408.     while(c<t) {
  409.         if(template[c]=='N' || template[c]=='A' || template[c]=='!')
  410.             outchar(SP);
  411.         else
  412.             outchar(template[c]);
  413.         c++; }
  414.     bprintf("\x1b[%dD",t); }
  415. c=0;
  416. if(mode&K_EDIT) {
  417.     strcpy(str,strout);
  418.     bputs(str);
  419.     c=strlen(str); }
  420. while((ch=getkey(mode))!=CR && online && !(sys_status&SS_ABORT)) {
  421.     if(ch==BS) {
  422.         if(!c)
  423.             continue;
  424.         for(ch=1,c--;c;c--,ch++)
  425.             if(template[c]=='N' || template[c]=='A' || template[c]=='!')
  426.                 break;
  427.         if(useron.misc&ANSI)
  428.             bprintf("\x1b[%dD",ch);
  429.         else while(ch--)
  430.             outchar(BS);
  431.         bputs(" \b");
  432.         continue; }
  433.     if(ch==24) {    /* Ctrl-X */
  434.         for(c--;c!=0xff;c--) {
  435.             outchar(BS);
  436.             if(template[c]=='N' || template[c]=='A' || template[c]=='!')
  437.                 bputs(" \b"); }
  438.         c=0; }
  439.     else if(c<t) {
  440.         if(template[c]=='N' && !isdigit(ch))
  441.             continue;
  442.         if(template[c]=='A' && !isalpha(ch))
  443.             continue;
  444.         outchar(ch);
  445.         str[c++]=ch;
  446.         while(c<t && template[c]!='N' && template[c]!='A' && template[c]!='!'){
  447.             str[c]=template[c];
  448.             outchar(template[c++]); } } }
  449. str[c]=0;
  450. attr(LIGHTGRAY);
  451. CRLF;
  452. if(!(sys_status&SS_ABORT))
  453.     strcpy(strout,str);
  454. return(c);
  455. }
  456.  
  457. /*****************************************************************************/
  458. /* Accepts a user's input to change a new-scan time pointer                  */
  459. /* Returns 0 if input was aborted or invalid, 1 if complete                     */
  460. /*****************************************************************************/
  461. char inputnstime(time_t *dt)
  462. {
  463.     int hour;
  464.     struct date tmpdate;
  465.     struct time tmptime;
  466.     char pm,str[256];
  467.  
  468. bputs(text[NScanDate]);
  469. bputs(timestr(dt));
  470. CRLF;
  471. unixtodos(*dt,&tmpdate,&tmptime);
  472. bputs(text[NScanYear]);
  473. itoa(tmpdate.da_year,str,10);
  474. if(!getstr(str,4,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) {
  475.     CRLF;
  476.     return(0); }
  477. tmpdate.da_year=atoi(str);
  478. if(tmpdate.da_year<1970) {
  479.     CRLF;
  480.     return(0); }
  481. bputs(text[NScanMonth]);
  482. itoa(tmpdate.da_mon,str,10);
  483. if(!getstr(str,2,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) {
  484.     CRLF;
  485.     return(0); }
  486. tmpdate.da_mon=atoi(str);
  487. if(tmpdate.da_mon<1 || tmpdate.da_mon>12) {
  488.     CRLF;
  489.     return(0); }
  490. bputs(text[NScanDay]);
  491. itoa(tmpdate.da_day,str,10);
  492. if(!getstr(str,2,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) {
  493.     CRLF;
  494.     return(0); }
  495. tmpdate.da_day=atoi(str);
  496. if(tmpdate.da_day<1 || tmpdate.da_day>31) {
  497.     CRLF;
  498.     return(0); }
  499. bputs(text[NScanHour]);
  500. if(sys_misc&SM_MILITARY)
  501.     hour=tmptime.ti_hour;
  502. else {
  503.     if(tmptime.ti_hour==0) {    /* 12 midnite */
  504.         pm=0;
  505.         hour=12; }
  506.     else if(tmptime.ti_hour>12) {
  507.         hour=tmptime.ti_hour-12;
  508.         pm=1; }
  509.     else {
  510.         hour=tmptime.ti_hour;
  511.         pm=0; } }
  512. itoa(hour,str,10);
  513. if(!getstr(str,2,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) {
  514.     CRLF;
  515.     return(0); }
  516.  
  517. tmptime.ti_hour=atoi(str);
  518. if(tmptime.ti_hour>24) {
  519.     CRLF;
  520.     return(0); }
  521. bputs(text[NScanMinute]);
  522. itoa(tmptime.ti_min,str,10);
  523. if(!getstr(str,2,K_EDIT|K_AUTODEL|K_NUMBER|K_NOCRLF) || sys_status&SS_ABORT) {
  524.     CRLF;
  525.     return(0); }
  526.  
  527. tmptime.ti_min=atoi(str);
  528. if(tmptime.ti_min>59) {
  529.     CRLF;
  530.     return(0); }
  531. tmptime.ti_sec=0;
  532. if(!(sys_misc&SM_MILITARY) && tmptime.ti_hour && tmptime.ti_hour<13) {
  533.     if(pm && yesno(text[NScanPmQ])) {
  534.             if(tmptime.ti_hour<12)
  535.                 tmptime.ti_hour+=12; }
  536.     else if(!pm && !yesno(text[NScanAmQ])) {
  537.             if(tmptime.ti_hour<12)
  538.                 tmptime.ti_hour+=12; }
  539.     else if(tmptime.ti_hour==12)
  540.         tmptime.ti_hour=0; }
  541. else {
  542.     CRLF; }
  543. *dt=dostounix(&tmpdate,&tmptime);
  544. return(1);
  545. }
  546.  
  547. /*****************************************************************************/
  548. /* Checks a password for uniqueness and validity                              */
  549. /*****************************************************************************/
  550. char chkpass(char *pass, user_t user)
  551. {
  552.     char c,d,first[128],last[128],sysop[41],sysname[41],*p;
  553.  
  554. if(strlen(pass)<4) {
  555.     bputs(text[PasswordTooShort]);
  556.     return(0); }
  557. if(!strcmp(pass,user.pass)) {
  558.     bputs(text[PasswordNotChanged]);
  559.     return(0); }
  560. d=strlen(pass);
  561. for(c=1;c<d;c++)
  562.     if(pass[c]!=pass[c-1])
  563.         break;
  564. if(c==d) {
  565.     bputs(text[PasswordInvalid]);
  566.     return(0); }
  567. for(c=0;c<3;c++)    /* check for 1234 and ABCD */
  568.     if(pass[c]!=pass[c+1]+1)
  569.         break;
  570. if(c==3) {
  571.     bputs(text[PasswordObvious]);
  572.     return(0); }
  573. for(c=0;c<3;c++)    /* check for 4321 and ZYXW */
  574.     if(pass[c]!=pass[c+1]-1)
  575.         break;
  576. if(c==3) {
  577.     bputs(text[PasswordObvious]);
  578.     return(0); }
  579. strupr(user.name);
  580. strupr(user.alias);
  581. strcpy(first,user.alias);
  582. p=strchr(first,SP);
  583. if(p) {
  584.     *p=0;
  585.     strcpy(last,p+1); }
  586. else
  587.     last[0]=0;
  588. strupr(user.handle);
  589. strcpy(sysop,sys_op);
  590. strupr(sysop);
  591. strcpy(sysname,sys_name);
  592. strupr(sysname);
  593. if((user.pass[0]
  594.         && (strstr(pass,user.pass) || strstr(user.pass,pass)))
  595.     || (user.name[0]
  596.         && (strstr(pass,user.name) || strstr(user.name,pass)))
  597.     || strstr(pass,user.alias) || strstr(user.alias,pass)
  598.     || strstr(pass,first) || strstr(first,pass)
  599.     || (last[0]
  600.         && (strstr(pass,last) || strstr(last,pass)))
  601.     || strstr(pass,user.handle) || strstr(user.handle,pass)
  602.     || (user.zipcode[0]
  603.         && (strstr(pass,user.zipcode) || strstr(user.zipcode,pass)))
  604.     || (sysname[0]
  605.         && (strstr(pass,sysname) || strstr(sysname,pass)))
  606.     || (sysop[0]
  607.         && (strstr(pass,sysop) || strstr(sysop,pass)))
  608.     || (sys_id[0]
  609.         && (strstr(pass,sys_id) || strstr(sys_id,pass)))
  610.     || (node_phone[0] && strstr(pass,node_phone))
  611.     || (user.phone[0] && strstr(user.phone,pass))
  612.     || !strncmp(pass,"QWER",3)
  613.     || !strncmp(pass,"ASDF",3)
  614.     || !strncmp(pass,"!@#$",3)
  615.     )
  616.     {
  617.     bputs(text[PasswordObvious]);
  618.     return(0); }
  619. return(1);
  620. }
  621.  
  622. /****************************************************************************/
  623. /* Prompts user for detailed information regarding their computer             */
  624. /* and places that information into 'computer'                                */
  625. /* Called from function newuser                                                */
  626. /****************************************************************************/
  627. void getcomputer(char *computer)
  628. {
  629.     char str[256];
  630.  
  631. if(!(uq&UQ_MC_COMP)) {
  632.     while(online) {
  633.         bputs(text[EnterYourComputer]);
  634.         if(getstr(computer,LEN_COMP,K_LINE))
  635.             break; }
  636.     return; }
  637. bputs(text[ComputerTypeMenu]);
  638. bputs(text[ComputerTypePrompt]);
  639. switch(getkeys("ABCDE",0)) {
  640.     case 'A':
  641.         sif("COMPUTER",str,8);
  642.         if(!online) return;
  643.         switch(str[0]) {
  644.             case 'A':
  645.                 strcpy(computer,"XT");
  646.                 break;
  647.             case 'B':
  648.                 strcpy(computer,"286");
  649.                 break;
  650.             case 'C':
  651.                 strcpy(computer,"386SX");
  652.                 break;
  653.             case 'D':
  654.                 strcpy(computer,"386DX");
  655.                 break;
  656.             case 'E':
  657.                 strcpy(computer,"486");
  658.                 break; }
  659.         switch(str[1]) {
  660.             case 'A':
  661.                 strcat(computer,"-4 ");
  662.                 break;
  663.             case 'B':
  664.                 strcat(computer,"-6 ");
  665.                 break;
  666.             case 'C':
  667.                 strcat(computer,"-8 ");
  668.                 break;
  669.             case 'D':
  670.                 strcat(computer,"-10 ");
  671.                 break;
  672.             case 'E':
  673.                 strcat(computer,"-12 ");
  674.                 break;
  675.             case 'F':
  676.                 strcat(computer,"-16 ");
  677.                 break;
  678.             case 'G':
  679.                 strcat(computer,"-20 ");
  680.                 break;
  681.             case 'H':
  682.                 strcat(computer,"-25 ");
  683.                 break;
  684.             case 'I':
  685.                 strcat(computer,"-33 ");
  686.                 break;
  687.             case 'J':
  688.                 strcat(computer,"-40 ");
  689.                 break;
  690.             case 'K':
  691.                 strcat(computer,"-50 ");
  692.                 break; }
  693.         switch(str[2]) {
  694.             case 'A':
  695.                 strcat(computer,"8bit ");
  696.                 break;
  697.             case 'B':
  698.                 strcat(computer,"ISA ");
  699.                 break;
  700.             case 'C':
  701.                 strcat(computer,"MCA ");
  702.                 break;
  703.             case 'D':
  704.                 strcat(computer,"EISA ");
  705.                 break; }
  706.         switch(str[3]) {
  707.             case 'A':
  708.                 strcat(computer,"MDA ");
  709.                 break;
  710.             case 'B':
  711.                 strcat(computer,"HERC ");
  712.                 break;
  713.             case 'C':
  714.                 strcat(computer,"CGA ");
  715.                 break;
  716.             case 'D':
  717.                 strcat(computer,"EGA ");
  718.                 break;
  719.             case 'E':
  720.                 strcat(computer,"MCGA ");
  721.                 break;
  722.             case 'F':
  723.                 strcat(computer,"VGA ");
  724.                 break;
  725.             case 'G':
  726.                 strcat(computer,"SVGA ");
  727.                 break;
  728.             case 'H':
  729.                 strcat(computer,"MVGA ");
  730.                 break;
  731.             case 'I':
  732.                 strcat(computer,"8514 ");
  733.                 break;
  734.             case 'J':
  735.                 strcat(computer,"XGA ");
  736.                 break;
  737.             case 'K':
  738.                 strcat(computer,"TIGA ");
  739.                 break; }
  740.         switch(str[4]) {
  741.             case 'A':
  742.                 strcat(computer,"<1 ");
  743.                 break;
  744.             case 'B':
  745.                 strcat(computer,"1 ");
  746.                 break;
  747.             case 'C':
  748.                 strcat(computer,"2 ");
  749.                 break;
  750.             case 'D':
  751.                 strcat(computer,"3 ");
  752.                 break;
  753.             case 'E':
  754.                 strcat(computer,"4 ");
  755.                 break;
  756.             case 'F':
  757.                 strcat(computer,"5 ");
  758.                 break;
  759.             case 'G':
  760.                 strcat(computer,"6 ");
  761.                 break;
  762.             case 'H':
  763.                 strcat(computer,"8 ");
  764.                 break;
  765.             case 'I':
  766.                 strcat(computer,"10 ");
  767.                 break;
  768.             case 'J':
  769.                 strcat(computer,"12 ");
  770.                 break;
  771.             case 'K':
  772.                 strcat(computer,"16 ");
  773.                 break;
  774.             case 'L':
  775.                 strcat(computer,"18 ");
  776.                 break;
  777.             case 'M':
  778.                 strcat(computer,"24 ");
  779.                 break;
  780.             case 'N':
  781.                 strcat(computer,"32 ");
  782.                 break;
  783.             case 'O':
  784.                 strcat(computer,"64 ");
  785.                 break; }
  786.         switch(str[5]) {
  787.             case 'A':
  788.                 strcat(computer,"0 ");
  789.                 break;
  790.             case 'B':
  791.                 strcat(computer,"10 ");
  792.                 break;
  793.             case 'C':
  794.                 strcat(computer,"20 ");
  795.                 break;
  796.             case 'D':
  797.                 strcat(computer,"30 ");
  798.                 break;
  799.             case 'E':
  800.                 strcat(computer,"40 ");
  801.                 break;
  802.             case 'F':
  803.                 strcat(computer,"60 ");
  804.                 break;
  805.             case 'G':
  806.                 strcat(computer,"80 ");
  807.                 break;
  808.             case 'H':
  809.                 strcat(computer,"100 ");
  810.                 break;
  811.             case 'I':
  812.                 strcat(computer,"120 ");
  813.                 break;
  814.             case 'J':
  815.                 strcat(computer,"150 ");
  816.                 break;
  817.             case 'K':
  818.                 strcat(computer,"200 ");
  819.                 break;
  820.             case 'L':
  821.                 strcat(computer,"250 ");
  822.                 break;
  823.             case 'M':
  824.                 strcat(computer,"300 ");
  825.                 break;
  826.             case 'N':
  827.                 strcat(computer,"400 ");
  828.                 break;
  829.             case 'O':
  830.                 strcat(computer,"500 ");
  831.                 break;
  832.             case 'P':
  833.                 strcat(computer,"600 ");
  834.                 break;
  835.             case 'Q':
  836.                 strcat(computer,"700 ");
  837.                 break;
  838.             case 'R':
  839.                 strcat(computer,"800 ");
  840.                 break;
  841.             case 'S':
  842.                 strcat(computer,"900 ");
  843.                 break;
  844.             case 'T':
  845.                 strcat(computer,"1GB ");
  846.                 break; }
  847.         switch(str[6]) {
  848.             case 'A':
  849.                 strcat(computer,"ST506");
  850.                 break;
  851.             case 'B':
  852.                 strcat(computer,"SCSI");
  853.                 break;
  854.             case 'C':
  855.                 strcat(computer,"SCSI2");
  856.                 break;
  857.             case 'D':
  858.                 strcat(computer,"ESDI");
  859.                 break;
  860.             case 'E':
  861.                 strcat(computer,"IDE"); }
  862.         break;
  863.     case 'B':
  864.         sprintf(computer,"%.*s",LEN_COMP,text[ComputerTypeB]);
  865.         return;
  866.     case 'C':
  867.         sprintf(computer,"%.*s",LEN_COMP,text[ComputerTypeC]);
  868.         return;
  869.     case 'D':
  870.         sprintf(computer,"%.*s",LEN_COMP,text[ComputerTypeD]);
  871.         return;
  872.     case 'E':
  873.         sprintf(computer,"%.*s",LEN_COMP,text[ComputerTypeE]);
  874.         return; }
  875. }
  876.  
  877. /****************************************************************************/
  878. /* Displays information about sub-board subnum                                */
  879. /****************************************************************************/
  880. void subinfo(uint subnum)
  881. {
  882.     char str[256];
  883.  
  884. bputs(text[SubInfoHdr]);
  885. bprintf(text[SubInfoLongName],sub[subnum]->lname);
  886. bprintf(text[SubInfoShortName],sub[subnum]->sname);
  887. bprintf(text[SubInfoQWKName],sub[subnum]->qwkname);
  888. bprintf(text[SubInfoMaxMsgs],sub[subnum]->maxmsgs);
  889. if(sub[subnum]->misc&SUB_QNET)
  890.     bprintf(text[SubInfoTagLine],sub[subnum]->tagline);
  891. if(sub[subnum]->misc&SUB_FIDO)
  892.     bprintf(text[SubInfoFidoNet]
  893.         ,sub[subnum]->origline
  894.         ,faddrtoa(sub[subnum]->faddr));
  895. sprintf(str,"%s%s.MSG",sub[subnum]->data_dir,sub[subnum]->code);
  896. if(fexist(str) && yesno(text[SubInfoViewFileQ]))
  897.     printfile(str,0);
  898. }
  899.  
  900. /****************************************************************************/
  901. /* Displays information about transfer directory dirnum                     */
  902. /****************************************************************************/
  903. void dirinfo(uint dirnum)
  904. {
  905.     char str[256];
  906.  
  907. bputs(text[DirInfoHdr]);
  908. bprintf(text[DirInfoLongName],dir[dirnum]->lname);
  909. bprintf(text[DirInfoShortName],dir[dirnum]->sname);
  910. if(dir[dirnum]->exts[0])
  911.     bprintf(text[DirInfoAllowedExts],dir[dirnum]->exts);
  912. bprintf(text[DirInfoMaxFiles],dir[dirnum]->maxfiles);
  913. sprintf(str,"%s%s.MSG",dir[dirnum]->data_dir,dir[dirnum]->code);
  914. if(fexist(str) && yesno(text[DirInfoViewFileQ]))
  915.     printfile(str,0);
  916. }
  917.  
  918. /****************************************************************************/
  919. /* Searches the file <name>.CAN in the TEXT directory for matches            */
  920. /* Returns 1 if found in list, 0 if not.                                    */
  921. /****************************************************************************/
  922. char trashcan(char *insearch, char *name)
  923. {
  924.     char str[256],search[256],c,found=0;
  925.     int file;
  926.     FILE *stream;
  927.  
  928. sprintf(str,"%s%s.CAN",text_dir,name);
  929. if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
  930.     if(fexist(str))
  931.         errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
  932.     return(0); }
  933. strcpy(search,insearch);
  934. strupr(search);
  935. while(!feof(stream) && !ferror(stream) && !found) {
  936.     if(!fgets(str,81,stream))
  937.         break;
  938.     truncsp(str);
  939.     c=strlen(str);
  940.     if(c) {
  941.         c--;
  942.         strupr(str);
  943.         if(str[c]=='~') {
  944.             str[c]=0;
  945.             if(strstr(search,str))
  946.                 found=1; }
  947.  
  948.         else if(str[c]=='^') {
  949.             str[c]=0;
  950.             if(!strncmp(str,search,c))
  951.                 found=1; }
  952.  
  953.         else if(!strcmp(str,search))
  954.             found=1; } }
  955. fclose(stream);
  956. if(found) {
  957.     sprintf(str,"%sBAD%s.MSG",text_dir,name);
  958.     if(fexist(str))
  959.         printfile(str,0);
  960.     return(1); }
  961. return(0);
  962. }
  963.  
  964. /****************************************************************************/
  965. /* Error handling routine. Prints to local and remote screens the error     */
  966. /* information, function, action, object and access and then attempts to    */
  967. /* write the error information into the file ERROR.LOG and NODE.LOG         */
  968. /****************************************************************************/
  969. void errormsg(int line, char *source, char action, char *object, ulong access)
  970. {
  971.     char str[512];
  972.     char actstr[256];
  973.  
  974. switch(action) {
  975.     case ERR_OPEN:
  976.         strcpy(actstr,"opening");
  977.         break;
  978.     case ERR_CLOSE:
  979.         strcpy(actstr,"closing");
  980.         break;
  981.     case ERR_FDOPEN:
  982.         strcpy(actstr,"fdopen");
  983.         break;
  984.     case ERR_READ:
  985.         strcpy(actstr,"reading");
  986.         break;
  987.     case ERR_WRITE:
  988.         strcpy(actstr,"writing");
  989.         break;
  990.     case ERR_REMOVE:
  991.         strcpy(actstr,"removing");
  992.         break;
  993.     case ERR_ALLOC:
  994.         strcpy(actstr,"allocating memory");
  995.         break;
  996.     case ERR_CHK:
  997.         strcpy(actstr,"checking");
  998.         break;
  999.     case ERR_LEN:
  1000.         strcpy(actstr,"checking length");
  1001.         break;
  1002.     case ERR_EXEC:
  1003.         strcpy(actstr,"executing");
  1004.         break;
  1005.     case ERR_CHDIR:
  1006.         strcpy(actstr,"changing directory");
  1007.         break;
  1008.     case ERR_CREATE:
  1009.         strcpy(actstr,"creating");
  1010.         break;
  1011.     case ERR_LOCK:
  1012.         strcpy(actstr,"locking");
  1013.         break;
  1014.     case ERR_UNLOCK:
  1015.         strcpy(actstr,"unlocking");
  1016.         break;
  1017.     default:
  1018.         strcpy(actstr,"UNKNOWN"); }
  1019. bprintf("\7\r\nERROR -   action: %s",actstr);   /* tell user about error */
  1020. bprintf("\7\r\n          object: %s",object);
  1021. bprintf("\7\r\n          access: %ld",access);
  1022. if(access>9 && (long)access!=-1 && (short)access!=-1 && (char)access!=-1)
  1023.     bprintf(" (%lXh)",access);
  1024. if(sys_misc&SM_ERRALARM) {
  1025.     beep(500,220); beep(250,220);
  1026.     beep(500,220); beep(250,220);
  1027.     beep(500,220); beep(250,220);
  1028.     nosound(); }
  1029. bputs("\r\n\r\nThe sysop has been notified. <Hit a key>");
  1030. getkey(0);
  1031. CRLF;
  1032. sprintf(str,"\r\n      file: %s\r\n      line: %d\r\n    action: %s\r\n"
  1033.     "    object: %s\r\n    access: %ld"
  1034.     ,source,line,actstr,object,access);
  1035. if(access>9 && (long)access!=-1 && (short)access!=-1 && (char)access!=-1) {
  1036.     sprintf(tmp," (%lXh)",access);
  1037.     strcat(str,tmp); }
  1038. if(errno) {
  1039.     sprintf(tmp,"\r\n     errno: %d",errno);
  1040.     strcat(str,tmp); }
  1041. if(_doserrno && _doserrno!=errno) {
  1042.     sprintf(tmp,"\r\n  doserrno: %d",_doserrno);
  1043.     strcat(str,tmp); }
  1044. errno=_doserrno=0;
  1045. errorlog(str);
  1046. }
  1047.  
  1048. /*****************************************************************************/
  1049. /* Error logging to NODE.LOG and DATA\ERROR.LOG function                     */
  1050. /*****************************************************************************/
  1051. void errorlog(char *text)
  1052. {
  1053.     static char inside;
  1054.     char hdr[256],str[256],tmp2[256];
  1055.     int file;
  1056.  
  1057. if(inside)        /* let's not go recursive on this puppy */
  1058.     return;
  1059. inside=1;
  1060. getnodedat(node_num,&thisnode,1);
  1061. criterrs=++thisnode.errors;
  1062. putnodedat(node_num,thisnode);
  1063. now=time(NULL);
  1064. logline("!!",text);
  1065. sprintf(str,"%sERROR.LOG",data_dir);
  1066. if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) {
  1067.     sprintf(tmp2,"ERROR opening/creating %s",str);
  1068.     logline("!!",tmp2);
  1069.     inside=0;
  1070.     return; }
  1071. sprintf(hdr,"%s Node %2d: %s #%d"
  1072.     ,timestr(&now),node_num,useron.alias,useron.number);
  1073. write(file,hdr,strlen(hdr));
  1074. write(file,crlf,2);
  1075. write(file,text,strlen(text));
  1076. write(file,"\r\n\r\n",4);
  1077. close(file);
  1078. inside=0;
  1079. }
  1080.  
  1081.