home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / BBS / MISC / XDEV_117.ZIP / XUSER.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-24  |  41.3 KB  |  1,858 lines

  1. /*======================================================================*/
  2. /*  XBBS Bulletin Board System.....CHEAP USER EDITOR (XUser)            */
  3. /*  Copyright (c) 1989/90 by M. Kimes...all rights reserved             */
  4. /*======================================================================*/
  5.  
  6. #include "msgg.h"
  7.  
  8. /* Function prototypes */
  9.  
  10. char * genin(char length,char password,char caps,char hot,char type);
  11. int    pascal swap_LMRs (word user1,word user2);
  12. int    inkey(void);
  13. void   update(void);
  14. void   displayuser(void);
  15. void   getuser(void);
  16. void   rstrip (char *);
  17. void   packusers(void);
  18. char * saydate(struct date *);
  19. char * saytime(struct time *);
  20. void   userlist(void);
  21. char   specialkey(char);
  22. char   inkey2(void);
  23. char   regularkey(char);
  24. void   left(char *a,char *b,word x);
  25. void   right(char *a,char *b,word x);
  26. void   mid(char *a,char *b,word x,word y);
  27. word   finduser(char *,word);
  28. void   printer (char *,...);
  29. ulong  diffdays(struct date *);
  30. void   deletebyday(ulong);
  31. void   getonline(void);
  32. void   set_new(void);
  33. void   prepare(void);
  34. void   readconfig(void);
  35. void   saveconfig(void);
  36. void   LMRpack(void);
  37. int    break_handler(void);
  38. void   addLMRs(void);
  39. void   display2(void);
  40. char   specialkey2(char);
  41. char   regularkey2(char);
  42. void   pack_mset(void);
  43.  
  44. /* Symbols for GENIN */
  45.  
  46. #define ALL      1
  47. #define ALPHA    2
  48. #define NUM      3
  49. #define ALPHANUM 4
  50. #define YESNO    5
  51. #define FLE      6
  52. #define FLEP     7
  53. #define FLEW     8
  54. #define FLEPW    9
  55. #define NAME     10
  56. #define NEAT     11
  57.  
  58. /* Global variables */
  59.  
  60. struct _user   user;
  61. word           userno=1;
  62. struct ffblk   f;
  63. char           changed=0;
  64. char           usedirect=1;
  65. char              online_user=0;
  66. char            nodenumber=1;
  67. word           baud=0;
  68. word           timelimit=60;
  69. struct time    starter;
  70. struct time    timeon;
  71. char           variable[10][82];
  72. char           pages;
  73. struct _mboard mboard;
  74. struct _fboard fboard;
  75. char           level=0;
  76. char           timer_off;
  77. char           age;
  78. word           *LMR;
  79. word           hold_time;
  80. struct _config conf;
  81. struct _events event[10];
  82. char           *deletelist;
  83. char           page=0;
  84. char           clear_vars=0;
  85. char            didbreak=0;
  86. char            packing=0;
  87.  
  88. struct _msetup {
  89.     unsigned long userid;
  90.     char node;
  91.     unsigned char areas[512];
  92. } mset;
  93.  
  94.  
  95.  
  96.  
  97. void main (int argc,char **argv) {
  98.  
  99.     FILE *fp;
  100.     int handle;
  101.     char *p;
  102.     register word xx;
  103.  
  104.     readconfig();
  105.     LMR=(word *)malloc(conf.nolmrs * sizeof(word));
  106.     if(LMR==NULL) {
  107.         printf("\nOOM for LMR's (%u)\n",conf.nolmrs);
  108.         exit(1);
  109.     }
  110.  
  111.    printf("\nXUSER copyright (c) 1989 by M. Kimes\nCompiled: %s  %s\n",__DATE__,__TIME__);
  112.    ctrlbrk(break_handler);
  113.    if ((argc>1) and (stricmp(argv[1],"PACK"))==0) {
  114.      deletelist=(char *)malloc((word)65535);
  115.      if(deletelist==NULL) {
  116.         printf("\nNot enough memory to run\n");
  117.         exit(2);
  118.      }
  119.      packusers();
  120.      if(deletelist) free(deletelist);
  121.      exit(0);
  122.    }
  123.    if ((argc>1) and (stricmp(argv[1],"CLEAR"))==0) {
  124.      deletelist=(char *)malloc((word)65535);
  125.      if(deletelist==NULL) {
  126.         printf("\nNot enough memory to run\n");
  127.         exit(2);
  128.      }
  129.      clear_vars=1;
  130.      packusers();
  131.      if(deletelist) free(deletelist);
  132.      exit(0);
  133.     }
  134.  
  135.    if ((argc>1) and (*argv[1]=='?' || toupper(*argv[1])=='H')) {
  136.         printf("\nUsage: XUSER <USER user_name> <DOS> <PACK> <CLEAR> <DAYS num_days>\n");
  137.         exit(0);
  138.    }
  139.  
  140.     deletelist=(char *)malloc((word)65535);
  141.     if(deletelist==NULL) {
  142.         printf("\nNot enough memory to run\n");
  143.         exit(2);
  144.     }
  145.  
  146.    if ((argc>1) and (stricmp(argv[1],"DAYS"))==0) {
  147.      if (argc<3) {
  148.         printf("\nError in command line\n");
  149.         if(deletelist) free(deletelist);
  150.         exit (2);
  151.      }
  152.      deletebyday(atol(argv[2]));
  153.      if(deletelist) free(deletelist);
  154.      exit(0);
  155.     }
  156.  
  157.    if ((argc>1) && (stricmp(argv[argc-1],"DOS"))==0) {
  158.      usedirect=0;
  159.      window(0,0,80,25);
  160.    }
  161.  
  162.    if (findfirst("USERS.BBS",&f,0)!=0) {
  163.        fputs("\nCan't find a userfile!  Do you want to make one? (y-N) ",stdout);
  164.        if (*genin(1,0,1,1,YESNO)!='Y') exit(2);
  165.        changed=1;
  166.        userno=1;
  167.        fp=fopen("users.bbs","a+b");
  168.        fclose(fp);
  169.        set_new();
  170.        update();
  171.        findfirst("users.bbs",&f,0);
  172.    }
  173.  
  174.    if((argc>2) && (stricmp(argv[1],"USER"))==0) {
  175.         userno=0;
  176.         if (strchr(argv[2],'_')==NULL) userno=(word)atol(argv[2]);
  177.         if(!userno) {
  178.             while(p=strchr(argv[2],'_')) *p=' ';
  179.             printf("\nSearching for %s...",argv[2]);
  180.             xx=0;
  181.             if (f.ff_fsize) {
  182.                 if ((handle=_open(searchpath("USERS.BBS"),O_RDONLY | O_BINARY | O_DENYNONE))==-1) {
  183.                    printf("\nError opening userfile\n");
  184.                    perror("\nERROR");
  185.                    exit(254);
  186.                 }
  187.                 fp=fdopen(handle,"rb");
  188.                 rewind(fp);
  189.                 lseek(handle,0L,SEEK_SET);
  190.                 while (!feof(fp) && !ferror(fp)) {
  191.                  xx++;
  192.                  if (!(xx%50)) printf(".");
  193.                  if (fread(&user,sizeof(user),1,fp)!=1) break;
  194.                  if (!stricmp(user.name,argv[2]) || !stricmp(user.handle,argv[2])) break;
  195.                }
  196.                if (ferror(fp)) perror("\nERROR");
  197.                if (!stricmp(user.name,argv[2]) || !stricmp(user.handle,argv[2])) {
  198.                    userno=(word)(ftell(fp)/(long)sizeof(struct _user));
  199.                }
  200.                fclose(fp);
  201.                _close(handle);
  202.             }
  203.             if(!userno) userno=1;
  204.          }
  205.    }
  206.  
  207.    getuser();
  208.    displayuser();
  209.    inkey2();
  210.    if(deletelist) free(deletelist);
  211. }
  212.  
  213.  
  214.  
  215. int break_handler (void) {
  216.  
  217.     if(packing) {
  218.         cprintf("\r\nNot safe to stop while packing!\r\n");
  219.         didbreak=1;
  220.         return 1;
  221.     }
  222.     else return 0;
  223. }
  224.  
  225.  
  226.  
  227. void displayuser (void) { /* Display user */
  228.  
  229.  int a;
  230.  word temp;
  231.  register word x;
  232.  struct date dos_date;
  233.  struct time dos_time;
  234.  char *p;
  235.  char *pp;
  236.  
  237.  if(didbreak) {
  238.     printf("\nStopping in response to previous user BREAK\n");
  239.     exit(0);
  240.  }
  241.  if (findfirst("USERS.BBS",&f,0)!=0) {
  242.    printf("\nYou have to have a user file.\n");
  243.    exit(2);
  244.  }
  245. Restart:
  246.  if(page){
  247.     display2();
  248.     return;
  249.  }
  250.  if (usedirect) {
  251.     clrscr();
  252.     textattr(BLACK | LIGHTGRAY * 16);
  253.  }
  254.  else printf("\x1b[0m\x1b[2J\x1b[0;1;37m\x1b[7m");
  255.  if (online_user) printer("  XBBS USER EDITOR  *  Online.XBS User  (%u)",userno);
  256.  else printer("  XBBS USER EDITOR  *  User #%u of %lu",userno,f.ff_fsize/(long)sizeof(struct _user));
  257.  if (user.stat[0]==0) printer("  *  LOCKED OUT");
  258.  if (usedirect) {
  259.     textattr (LIGHTGRAY | BLACK * 16);
  260.  }
  261.  else printf("\x1b[0;1;37m");
  262.  printf("\x1b[0;74H");
  263.  printer("%03hu\nA. Real Name: %-36s\nB. Handle: %-36s\n",user.violations,user.name,user.handle);
  264.  a=inkey();
  265.  if (a==(-81)) {
  266.      x=userno+1;
  267.      if ((f.ff_fsize/(long)sizeof(struct _user)<x) or (x<0)) x=1;
  268.      userno=x;
  269.      getuser();
  270.      goto Restart;
  271.  }
  272.  if (a==(-73)) {
  273.      x=userno-1;
  274.      if ((f.ff_fsize/(long)sizeof(struct _user)<x) or (x<0)) x=(unsigned int)(f.ff_fsize/(long)sizeof(struct _user));
  275.      if (x==0) x=(unsigned int)(f.ff_fsize/(long)sizeof(struct _user));
  276.      userno=x;
  277.      getuser();
  278.      goto Restart;
  279.  }
  280.       if (conf.genstatezip) {
  281.         p="";
  282.         pp="";
  283.       }
  284.       else {
  285.         p=user.zip;
  286.         pp="   Alt-F. ZipCode: ";
  287.       }
  288.       printer("C. Password: %-12s   D. City: %-36s\n                            E. State: %-2s%s%-5s\n",user.password,user.city,user.state,pp,p);
  289.       printer("F. Home Phone: %10s   G. Other Phone: %10s\n",user.phone1,user.phone2);
  290.       printer("H. BirthDate: %-10s   ",saydate(&user.birthdate));
  291.       printer("I. Length: %02hu   J. Width: %02hu\n",user.length,user.width);
  292.       printer("K. S0: %05u S1: %05u S2: %05u S3: %05u S4: %05u\n   S5: %05u S6: %05u S7: %05u S8: %05u S9:%05u",user.stat[0],user.stat[1],user.stat[2],user.stat[3],user.stat[4],user.stat[5],user.stat[6],user.stat[7],user.stat[8],user.stat[9]);
  293.       printer("\nM. Calls/Day: %03u   N. Time/Call: %03u   ",user.callsperday,user.timepercall);
  294.       printer("O. Total time: %03u\nP. Calls today: %03u   ",user.totaltime,user.callstoday);
  295.       printer("Q. Total Calls: %05lu   R. Time Today: %05u\n",user.times,user.timetoday);
  296.       printer("S. LastDate: %-10s   T. LastTime: %-8s\n",saydate(&user.lastdate),saytime(&user.lasttime));
  297.       printer("U. UpK: %08lu   V. DownK: %08lu   W. UpNo: %05u  X. DownNo: %05u\n",user.upk,user.downk,user.upno,user.downno);
  298.       printer("Y. Posts: %05u   Z. Credit: %04d   ALT-A. Comp. Type: %hu",user.posts,user.credit,user.comptype);
  299.  
  300.        printer("\n0. ANSI: ");
  301.        user.graphics ? printer("X") : printer("-");
  302.        printer("   1. ED: ");
  303.        user.fullscreen ? printer("X") : printer("-");
  304.        printer("   2. CLR: ");
  305.        user.scrnclr ? printer("-"): printer("X");
  306.        printer("   3. Spec: ");
  307.        user.commodore ? printer("X"): printer("-");
  308.        printer("   4. Expert: ");
  309.        user.expert ? printer("X"): printer("-");
  310.        printer("   5. More: ");
  311.        user.more ? printer("-"): printer("X");
  312.        printer("\n6. HOURS: ");
  313.        user.ignorehrs ? printer("X") : printer("-");
  314.        printer("   7. RATIO: ");
  315.        user.ignorerat ? printer("X") : printer("-");
  316.        printer("   8. NOKILL: ");
  317.        user.nokill ? printer("X") : printer("-");
  318.        printer("   9. DEL: ");
  319.        user.deleted ? printer("X") : printer("-");
  320.        printer("   ; TWIT: ");
  321.        user.twit ? printer("X") : printer("-");
  322.        printer("   : COLD: ");
  323.        user.cold ? printer("X") : printer("-");
  324.        printer("\nAlt0. ANSIMENU: ");
  325.        user.ansimenus ? printer("-") : printer("X");
  326.        printer("   Alt1. Genl#1: ");
  327.        user.gen1 ? printer("X") : printer("-");
  328.        printer("   Alt2. Genl#2: ");
  329.        user.gen2 ? printer("X") : printer("-");
  330.        printer("   Alt3. Genl#3: ");
  331.        user.gen2 ? printer("X") : printer("-");
  332.        printer("\nAlt4. Flags: [");
  333.        for (x=0;x<16;x++) {
  334.            temp=1;
  335.            temp=temp<<x;
  336.            (user.attr2 & temp) ? printer("X") : printer ("-");
  337.        }
  338.        printer("]  Alt5. UKDay: %05u  Alt6. DKDay: %05u",user.uktoday,user.dktoday);
  339.        printer("\nAlt7. HiBit: ");
  340.        user.hiok ? printer("X") : printer("-");
  341.        printer("   Alt8. LastMsgArea: %04u",user.lastmsgarea);
  342.        printer("\n%lu days since last * ",diffdays(&user.lastdate));
  343.        getdate(&dos_date);
  344.        gettime(&dos_time);
  345.        age=((dos_date.da_year-user.birthdate.da_year)-1);
  346.        if (dos_date.da_mon>user.birthdate.da_mon) age++;
  347.        else if ((dos_date.da_mon==user.birthdate.da_mon) && (dos_date.da_day>=user.birthdate.da_day)) age++;
  348.        printer("Age: %hu ** User id: %08lx.%03hu ** ALT-P. Point: %u\n",age,user.id,user.node,user.pointid);
  349.      if (usedirect) {
  350.         textattr(BLACK | LIGHTGRAY * 16);
  351.      }
  352.      else printf("\x1b[0;1;37m\x1b[7m");
  353.        printer("F1=LST F2=FND F3=PK F4=LCK F5=SRCH F6=ONLN F7=D_LK F8=D_DAY F9=CLR F10=ADD ?");
  354.      if (usedirect) {
  355.         textattr(LIGHTGRAY | BLACK * 16);
  356.      }
  357.      else printf("\x1b[0;2;37m");
  358.        printer("\nCommand: ");
  359.  
  360. }
  361.  
  362.  
  363.  
  364. void display2 (void) {
  365.  
  366.  register word x;
  367.  
  368.  printf("\x1b[2J");
  369.  if (usedirect) {
  370.     clrscr();
  371.     textattr(BLACK | LIGHTGRAY * 16);
  372.  }
  373.  else printf("\x1b[0m\x1b[2J\x1b[0;1;37m\x1b[7m");
  374.  if (online_user) printer("  XBBS USER EDITOR  *  Online.XBS User  (%u)",userno);
  375.  else printer("  XBBS USER EDITOR  *  User #%u of %lu",userno,f.ff_fsize/(long)sizeof(struct _user));
  376.  if (user.stat[0]==0) printer("  *  LOCKED OUT");
  377.  if (usedirect) {
  378.     textattr (LIGHTGRAY | BLACK * 16);
  379.  }
  380.  printf("\x1b[0;74H");
  381.  printer("%03hu\nReal Name: %-36s\nHandle: %-36s\n\n",user.violations,user.name,user.handle);
  382.  printer("Numeric variables:\n");
  383.  printer("0. %05u   1. %05u   2. %05u   3. %05u   4. %05u\n",user.numvars[0],user.numvars[1],user.numvars[2],user.numvars[3],user.numvars[4]);
  384.  printer("5. %05u   6. %05u   7. %05u   8. %05u   9. %05u\n\n",user.numvars[5],user.numvars[6],user.numvars[7],user.numvars[8],user.numvars[9]);
  385.  printer("String variables: (ALT+#)\n");
  386.  for(x=0;x<5;x++) printer("%u. %s\n",x,user.variable[x]);
  387.      if (usedirect) {
  388.         textattr(LIGHTGRAY | BLACK * 16);
  389.      }
  390.      else printf("\x1b[0;2;37m");
  391.        printer("\nCommand: ");
  392.  
  393. }
  394.  
  395.  
  396.  
  397. void packusers (void)  /* Pack out deleted users */
  398.  
  399. {
  400.  
  401. struct _user check;
  402. register word deleted=0;
  403. register word x=1;
  404. word y;
  405. FILE *fp;
  406. FILE *pf;
  407. FILE *id;
  408.  
  409.     packing=1;
  410.     printf("\nPacking user database...");
  411.  
  412.     remove("users.bak");
  413.  
  414.     if (rename("users.bbs","users.bak")!=0) {
  415.       printf("\nRename error...");
  416.       packing=0;
  417.       return;
  418.     }
  419.  
  420. if(!(fp=fopen("users.bbs","a+b"))) {
  421.    perror("\nUSERS.BBS ERROR");
  422.    packing=0;
  423.    return;
  424. }
  425. if(!(pf=fopen("users.bak","rb"))) {
  426.    perror("\nUSERS.BAK ERROR");
  427.    printf("\nRestoring old user database...\n");
  428.    remove("users.bbs");
  429.    rename("users.bak","users.bbs");
  430.    packing=0;
  431.    return;
  432. }
  433.  
  434.   rewind(fp);
  435.   rewind(pf);
  436.  
  437.   id=fopen("deleted.ids","a+b");
  438.   if(id)fseek(id,0L,SEEK_END);
  439.  
  440.      while (feof(pf)==0) {
  441.        if (fread(&check,sizeof(check),1,pf)!=1) break;
  442.        if (feof(pf)!=0) break;
  443.        if (ferror(pf)) perror("\nUSERS.BAK READ ERROR");
  444.        if (!check.deleted || x==1) {
  445.          deletelist[x-1]=1;
  446.          deletelist[x]=0;
  447.          if(clear_vars) {
  448.             for(y=0;y<10;y++) check.numvars[y]=0;
  449.             for(y=0;y<5;y++) strset(check.variable[y],0);
  450.          }
  451.          fwrite(&check,sizeof(check),1,fp);
  452.          printf("%5u\b\b\b\b\b",x);
  453.        }
  454.        else {
  455.  
  456.             char delfile[133];
  457.  
  458.             deletelist[x-1]=0;
  459.             deletelist[x]=0;
  460.             if(id) {
  461.                 fwrite(&check.id,sizeof(long),1,id);
  462.                 fwrite(&check.node,sizeof(char),1,id);
  463.             }
  464.             deleted++;
  465.             sprintf(delfile,"%sFORCE\\%08lx.%03hu\n",conf.homepath,check.id,check.node);
  466.             remove(delfile);
  467.             printf("\nDeleted %s",check.name);
  468.        }
  469.        if (ferror(fp)) perror("\nUSERS.BBS WRITE ERROR");
  470.        x++;
  471.      }
  472.        fclose(fp);
  473.        fclose(pf);
  474.        if(id)fclose(id);
  475.  
  476.   if(deleted) {
  477.     printf("\nPacking LMR files...");
  478.     LMRpack();
  479.   }
  480.   pack_mset();
  481.   printf("\nPacking complete.  %u users removed from database.\n",deleted);
  482.   conf.lastusernum=0;
  483.   saveconfig();
  484.   packing=0;
  485. }
  486.  
  487.  
  488. void dellocked(void)  /* Pack out locked/deleted users */
  489.  
  490. {
  491.  
  492. struct _user check;
  493. register word x=1;
  494. register word deleted=0;
  495. FILE *fp;
  496. FILE *pf;
  497. FILE *id;
  498.  
  499.     packing=1;
  500.     printf("\nPacking user database...deleting locked-out users...");
  501.  
  502.     remove("users.bak");
  503.  
  504.     if (rename("users.bbs","users.bak")!=0)
  505.      {
  506.       printf("\nRename error...");
  507.       packing=0;
  508.       return;
  509.      }
  510.  
  511.  
  512. if(!(fp=fopen("users.bbs","a+b"))) {
  513.    perror("\nUSERS.BBS ERROR");
  514.    packing=0;
  515.    return;
  516.   }
  517.  
  518. if(!(pf=fopen("users.bak","rb")))
  519.   {
  520.    perror("\nUSERS.BAK ERROR");
  521.    printf("\nRestoring old user database...\n");
  522.    remove("users.bbs");
  523.    rename("users.bak","users.bbs");
  524.    packing=0;
  525.    return;
  526.   }
  527.  
  528.   rewind(fp);
  529.   rewind(pf);
  530.  
  531.   id=fopen("deleted.ids","a+b");
  532.   if(id)fseek(id,0L,SEEK_END);
  533.  
  534.      while (!feof(pf) && !ferror(pf)) {
  535.        if (fread(&check,sizeof(check),1,pf)!=1) break;
  536.        if (feof(pf)!=0) break;
  537.        if (ferror(pf)) perror("\nUSERS.BAK READ ERROR");
  538.        if (check.nokill || x==1) {
  539.          deletelist[x-1]=1;
  540.          deletelist[x]=0;
  541.          if (fwrite(&check,sizeof(check),1,fp)!=1) break;
  542.          printf("%5u\b\b\b\b\b",x);
  543.          goto SkipIt;
  544.        }
  545.        if ((!check.deleted) and (check.stat[0]!=0))
  546.          {
  547.           deletelist[x-1]=1;
  548.           deletelist[x]=0;
  549.           if (fwrite(&check,sizeof(check),1,fp)!=1) break;
  550.          printf("%5u\b\b\b\b\b",x);
  551.          }
  552.        else {
  553.  
  554.          char delfile[133];
  555.  
  556.          deletelist[x-1]=0;
  557.          deletelist[x]=0;
  558.          if(id) {
  559.             fwrite(&check.id,sizeof(long),1,id);
  560.             fwrite(&check.node,sizeof(char),1,id);
  561.          }
  562.          deleted++;
  563.          sprintf(delfile,"%sFORCE\\%08lx.%03hu\n",conf.homepath,check.id,check.node);
  564.          remove(delfile);
  565.          printf("\nDeleted %s",check.name);
  566.        }
  567. SkipIt:
  568.        if (ferror(fp)) perror("\nUSERS.BBS WRITE ERROR");
  569.        x++;
  570.      }
  571.      fclose(fp);
  572.      fclose(pf);
  573.      if(id)fclose(id);
  574.  
  575.   if(deleted) {
  576.     printf("\nPacking LMR files...");
  577.     LMRpack();
  578.   }
  579.   pack_mset();
  580.   printf("\nPacking complete.  %u users removed from database.\n",deleted);
  581.   conf.lastusernum=0;
  582.   saveconfig();
  583.   packing=0;
  584. }
  585.  
  586.  
  587.  
  588. void deletebyday(numdays)  /* Pack out users who haven't called in x days */
  589.  
  590. ulong numdays;
  591.  
  592. {
  593.  
  594. struct _user check;
  595. register word x=1;
  596. register word deleted=0;
  597. FILE *fp;
  598. FILE *pf;
  599. FILE *id;
  600.  
  601.     if (numdays<=0) {
  602.         printf("\nError in daycount...\n");
  603.         return;
  604.     }
  605.  
  606.     packing=1;
  607.     printf("\nPacking user database...killing users who haven't called in %lu days...",numdays);
  608.  
  609.     remove("users.bak");
  610.  
  611.     if (rename("users.bbs","users.bak")!=0) {
  612.       printf("\nRename error...");
  613.       packing=0;
  614.       return;
  615.      }
  616.  
  617.  
  618. if(!(fp=fopen("users.bbs","a+b"))) {
  619.    perror("\nUSERS.BBS ERROR");
  620.    rename("users.bak","users.bbs");
  621.    packing=0;
  622.    return;
  623.   }
  624.  
  625. if(!(pf=fopen("users.bak","rb"))) {
  626.    perror("\nUSERS.BAK ERROR");
  627.    printf("\nRestoring old user database...\n");
  628.    remove("users.bbs");
  629.    rename("users.bak","users.bbs");
  630.    packing=0;
  631.    return;
  632.   }
  633.  
  634.   rewind(fp);
  635.   rewind(pf);
  636.  
  637.   id=fopen("deleted.ids","a+b");
  638.   if(id)fseek(id,0L,SEEK_END);
  639.  
  640.      while (!feof(pf)) {
  641.        if (fread(&check,sizeof(check),1,pf)!=1) break;
  642.        if (feof(pf)) break;
  643.        if (ferror(pf)) perror("\nUSERS.BAK READ ERROR");
  644.        if (check.nokill || x==1) {
  645.          deletelist[x-1]=1;
  646.          deletelist[x]=0;
  647.          fwrite(&check,sizeof(check),1,fp);
  648.          printf("%5u\b\b\b\b\b",x);
  649.          goto SkipIt;
  650.        }
  651.        if ((numdays>diffdays(&check.lastdate)) && (!check.deleted)) {
  652.          deletelist[x-1]=1;
  653.          deletelist[x]=0;
  654.          fwrite(&check,sizeof(check),1,fp);
  655.          printf("%5u\b\b\b\b\b",x);
  656.        }
  657.        else {
  658.  
  659.          char delfile[133];
  660.  
  661.          deletelist[x-1]=0;
  662.          deletelist[x]=0;
  663.          if(id) {
  664.             fwrite(&check.id,sizeof(long),1,id);
  665.             fwrite(&check.node,sizeof(char),1,id);
  666.          }
  667.          deleted++;
  668.          sprintf(delfile,"%sFORCE\\%08lx.%03hu\n",conf.homepath,check.id,check.node);
  669.          remove(delfile);
  670.          printf("\nDeleted %s",check.name);
  671.          if (!check.deleted) printf("*");
  672.        }
  673. SkipIt:
  674.        if (ferror(fp)) perror("\nUSERS.BBS WRITE ERROR");
  675.        x++;
  676.       }
  677.        fclose(fp);
  678.        fclose(pf);
  679.        if(id)fclose(id);
  680.  
  681.   if(deleted) {
  682.     printf("\nPacking LMR files...");
  683.     LMRpack();
  684.   }
  685.   pack_mset();
  686.   printf("\nPacking complete.  %u users removed from database.\n",deleted);
  687.   conf.lastusernum=0;
  688.   saveconfig();
  689.   packing=0;
  690. }
  691.  
  692.  
  693.  
  694. char * genin (length,password,caps,hot,type)  /* GENERIC INPUT ROUTINE */
  695.  
  696. char length;
  697. char password;
  698. char caps;
  699. char hot;
  700. char type;
  701.  
  702. {
  703.  
  704. static char input[256];
  705. char x=0;
  706. char one=0;
  707.  
  708.  length--;
  709.  strset(input,0);
  710.  
  711.  while (1) {
  712.  
  713.   one=inkey();
  714.   if (one == 13) break;
  715.   if (one == 8) {
  716.       if (x>0) {
  717.          printf("\b \b");
  718.          input [--x]=0;
  719.       }
  720.       continue;
  721.   }
  722.   if ((caps) or (type==YESNO)) one=toupper(one);
  723.   if (x <= length) {
  724.       if (type==NAME) {
  725.         if((isalpha(one)==0) and (one!=' ') and (one!='.') and
  726.         (one!='\'') and (one!='-') or (x==0 and one==' ')) continue;
  727.       }
  728.       if (type==NEAT) {
  729.         if((isalnum(one)==0) and (one!=' ') or (x==0 and one==' ')) continue;
  730.       }
  731.       if ((type==NEAT) or (type==NAME)) {
  732.          if(x==0) one=toupper(one);
  733.          else one=tolower(one);
  734.       }
  735.       if((type==NEAT) or (type==NAME)) {
  736.         if((x>0) and ((input[x-1]==' ') or (input[x-1]=='.') ||
  737.         (input[x-1]=='\'') or (input[x-1]=='-'))) one=toupper(one);
  738.       }
  739.       if ((type==ALL) and ((isprint(one)==0) and (one!=1))) continue;
  740.       if ((type==ALPHA) and (isalpha(one)==0) and (one!=' ')) continue;
  741.       if ((type==NUM) and (isdigit(one)==0)) continue;
  742.       if ((type==ALPHANUM) and (isalnum(one)==0) and (one!=' ')) continue;
  743.       if ((type==YESNO) and (one!='Y' and one!='N')) continue;
  744.       if (type==FLE) {
  745.          if ((isalnum(one)==0) and (!strchr("._-+=!@#$%^&<>/",one))) continue;
  746.       }
  747.       if (type==FLEP) {
  748.          if ((isalnum(one)==0) and (!strchr("._-+=!@#$%^&<>/\:",one))) continue;
  749.       }
  750.       if (type==FLEW) {
  751.           if ((isalnum(one)==0) and (!strchr("._-+=!@#$%^&<>/?*",one))) continue;
  752.       }
  753.       if (type==FLEPW) {
  754.        if ((isalnum(one)==0) and (!strchr("._-+=!@#$%^&<>/?*\:",one))) continue;
  755.       }
  756.    }
  757.  
  758.    if ((one!=0) and (x <= length)) {
  759.       input[x]=one;
  760.       input[++x]=0;
  761.       if (!password) printer(&input[x-1]);
  762.       if (password) printer("*");
  763.       if ((hot)and(x >= length)) return (input);
  764.    }
  765.  
  766.  }
  767.  
  768.   return (input);
  769.  
  770. }
  771.  
  772.  
  773.  
  774. void update (void) {
  775.  
  776. FILE *fp;
  777.  
  778.     if (!changed) return;
  779.     changed=0;
  780.     if (!online_user) {
  781.         if(!(fp=fopen("users.bbs","r+b"))) {
  782.            perror("\nUSERS.BBS ERROR");
  783.            exit(1);
  784.         }
  785.         fseek(fp,(long)sizeof(struct _user)*(userno-1),SEEK_SET);
  786.         clearerr(fp);
  787.         if (ferror(fp)) {
  788.             perror("\nERROR");
  789.             return;
  790.         }
  791.         fwrite(&user,sizeof(struct _user),1,fp);
  792.         if (ferror(fp)) perror("\nERROR");
  793.         fclose(fp);
  794.     }
  795.     else {
  796.         prepare();
  797.         online_user=0;
  798.     }
  799. }
  800.  
  801.  
  802.  
  803. void getuser (void) {
  804.  
  805.    FILE *fp;
  806.  
  807.    if (!online_user) {
  808.        if(!(fp=fopen("users.bbs","rb"))) {
  809.             perror("\nUSERS.BBS ERROR");
  810.             return;
  811.        }
  812.        fseek(fp,(long)sizeof(struct _user)*(userno-1),SEEK_SET);
  813.        clearerr(fp);
  814.        if ((fread(&user,sizeof(struct _user),1,fp)!=1) || ferror(fp)) perror("\nERROR READING USER");
  815.        fclose(fp);
  816.    }
  817.    else getonline();
  818.  
  819. }
  820.  
  821.  
  822.  
  823.  
  824. void rstrip(a)
  825.  
  826. char *a;
  827.  
  828. {
  829.  
  830.   while ((strlen(a)!=0) and (a[strlen(a)-1]==' ')) a[strlen(a)-1]=0;
  831.  
  832. }
  833.  
  834.  
  835. void userlist (void)
  836.  
  837. {
  838.  
  839. char line[81];
  840. struct _user check;
  841. FILE *fp;
  842. char p[37];
  843. char pp[37];
  844. word register x;
  845. word register y;
  846. struct date dos_date;
  847. struct time dos_time;
  848. char *mmore;
  849.  
  850.   printer("\nString to search for or [Enter] for all: ");
  851.   strcpy(p,strupr(genin(36,0,0,0,NAME)));
  852.  
  853. if(!(fp=fopen("users.bbs","rb")))
  854.   {
  855.    printer("\nError with userfile...\n");
  856.    perror("\nERROR");
  857.    return;
  858.   }
  859.  
  860.    printer("\nName/handle:                          Last on:\n");
  861.    printer("------------------------------------  ------------------------------------\n");
  862.    rewind(fp);
  863.    y=0;
  864.    while (feof(fp)==0)
  865.     {
  866.      if (fread(&check,sizeof(check),1,fp)!=1) break;
  867.      if (feof(fp)) break;
  868.      pp[0]=0;
  869.      strncpy(pp,check.handle,36);
  870.      if ((strstr(strupr(check.handle),p)) or (p[0]==0))
  871.       {
  872.        line[0]=0;
  873.        strcpy(line,pp);
  874.        for (x=strlen(line);x!=38;strcat(line," "),x++);
  875.         strcat(line,saydate(&check.lastdate));
  876.         strcat(line,"  ");
  877.         strcat(line,saytime(&check.lasttime));
  878.         printer(line);
  879.         if (check.deleted) printer("*");
  880.         printer("\n");
  881.         y++;
  882.       }
  883.       if (y>23) {
  884.         printer ("More? (Y-n) ");
  885.         mmore = genin (1,0,1,1,YESNOM);
  886.         printer("\r");
  887.         y=0;
  888.         if (*mmore == 'N') break;
  889.       }
  890.     }
  891.    printer("\n");
  892.  
  893.  fclose(fp);
  894.  
  895. return;
  896.  
  897. }
  898.  
  899.  
  900.  
  901. char * saydate (struct date *a)
  902.  
  903. {
  904.  
  905. static char xdate[11];
  906.  
  907.  sprintf(xdate,"%02hu/%02hu/%02d",a->da_mon,a->da_day,a->da_year);
  908.  return(xdate);
  909.  
  910. }
  911.  
  912.  
  913.  
  914. char * saytime(struct time *a)
  915.  
  916. {
  917.  
  918. static char xtime[9];
  919.  
  920.  sprintf(xtime,"%02u:%02u:%02u",a->ti_hour,a->ti_min,a->ti_sec);
  921.  return(xtime);
  922.  
  923. }
  924.  
  925.  
  926.  
  927.  
  928. int inkey (void)  /* MIMICS BASIC'S INKEY$ FUNCTION */
  929.  
  930. {
  931.  
  932. union REGS r;
  933.  
  934.   r.h.ah=11;
  935.   int86(33,&r,&r);
  936.   if (r.h.al) {
  937.     r.h.ah=8;
  938.     int86(33,&r,&r);
  939.     if (r.h.al) return(r.h.al);
  940.     r.h.ah=8;
  941.     int86(33,&r,&r);
  942.     return-(r.h.al);
  943.   }
  944.   return(0);
  945.  
  946. }
  947.  
  948.  
  949. char inkey2 (void)  /* MIMICS BASIC'S INKEY$ FUNCTION */
  950.  
  951. {
  952.  
  953. union REGS r;
  954.  
  955.  while (1) {
  956.   r.h.ah=11;
  957.   int86(33,&r,&r);
  958.   if (r.h.al) {
  959.     r.h.ah=8;
  960.     int86(33,&r,&r);
  961.     if (!r.h.al) {
  962.         r.h.ah=8;
  963.         int86(33,&r,&r);
  964.         if(!page)specialkey(r.h.al);
  965.         else specialkey2(r.h.al);
  966.     }
  967.     else {
  968.         if(!page)regularkey(r.h.al);
  969.         else regularkey2(r.h.al);
  970.     }
  971.   }
  972.  }
  973.  return 0;
  974. }
  975.  
  976.  
  977. char specialkey (char a) {
  978.  
  979.     register word x;
  980.     ulong numdays;
  981.     char temp[16];
  982.     char tempo;
  983.     char *p;
  984.  
  985.   strset(temp,0);
  986.  
  987.   switch ((int)a) {
  988.     case 132:
  989.     case 118:   page=1-page;
  990.                 displayuser();
  991.                 break;
  992.     case 81:
  993.      update();
  994.      x=userno+1;
  995.      if ((f.ff_fsize/(long)sizeof(struct _user)<x) or (x<0)) x=1;
  996.      userno=x;
  997.      getuser();
  998.      displayuser();
  999.     break;
  1000.     case 73:
  1001.      update();
  1002.      x=userno-1;
  1003.      if ((f.ff_fsize/(long)sizeof(struct _user)<x) or (x<0)) x=(unsigned int)(f.ff_fsize/(long)sizeof(struct _user));
  1004.      if (x==0) x=(unsigned int)(f.ff_fsize/(long)sizeof(struct _user));
  1005.      userno=x;
  1006.      getuser();
  1007.      displayuser();
  1008.     break;
  1009.     case 113:
  1010.         if(online_user) {
  1011.             printer("\nNot while editting online user, dummy.\n");
  1012.             sleep(1);
  1013.             break;
  1014.         }
  1015.         printer("\nSwap this user with which user #? (1-%u) ",(word)(f.ff_fsize/(long)sizeof(struct _user)));
  1016.         fgets(temp,16,stdin);
  1017.         if((word)atol(temp)<1 || (word)atol(temp)==userno || (word)atol(temp)>(word)(f.ff_fsize/(long)sizeof(struct _user))) {
  1018.             printer("\nInvalid.\n");
  1019.             sleep(1);
  1020.             displayuser();
  1021.             break;
  1022.         }
  1023.         {
  1024.             struct _user tempuser;
  1025.             word tempuserno;
  1026.             char temp2[17];
  1027.  
  1028.             memcpy(&tempuser,&user,sizeof(struct _user));
  1029.             tempuserno=userno;
  1030.             userno=(word)atol(temp);
  1031.             getuser();
  1032.             printer("\nSwap %s with %s? (Y-n) ",tempuser.name,user.name);
  1033.             fgets(temp2,16,stdin);
  1034.             if(toupper(*temp2)=='N') {
  1035. NoSwap:
  1036.                 userno=tempuserno;
  1037.                 getuser();
  1038.                 displayuser();
  1039.                 break;
  1040.             }
  1041.             if(swap_LMRs(tempuserno,userno))
  1042.                 goto NoSwap; /* Couldn't swap LMRs */
  1043.             changed=1;
  1044.             userno=tempuserno;
  1045.             update();
  1046.             memcpy(&user,&tempuser,sizeof(struct _user));
  1047.             userno=(word)atol(temp);
  1048.             changed=1;
  1049.             update();
  1050.             displayuser();
  1051.         }
  1052.         break;
  1053.     case 68:
  1054.         if(online_user) {
  1055.             printer("\nNot while editting online user, dummy.\n");
  1056.             sleep(1);
  1057.             break;
  1058.         }
  1059.        userno=(word)(f.ff_fsize/(long)sizeof(struct _user))+1;
  1060.        printer("\nUse current user for template? (y-N) ");
  1061.        fgets(temp,16,stdin);
  1062.        printer("\n");
  1063.        if(toupper(*temp)!='Y') set_new();
  1064.        changed=1;
  1065.        update();
  1066.        addLMRs();
  1067.        findfirst("users.bbs",&f,0);
  1068.        displayuser();
  1069.       break;
  1070.     case 45:
  1071.      update();
  1072.      exit (0);
  1073.     case 60:
  1074.      printer("\nUser #: ");
  1075.      fgets(temp,16,stdin);
  1076.      if (*temp=='\n') {
  1077.         displayuser();
  1078.         break;
  1079.      }
  1080.      x=(word)atol(temp);
  1081.      if (x<0) {
  1082.         displayuser();
  1083.         break;
  1084.      }
  1085.      if (f.ff_fsize/(long)sizeof(struct _user)<x) {
  1086.       printer("\nUser number too high.\n");
  1087.       printer("\n[Enter] to continue...");
  1088.       getch();
  1089.       displayuser();
  1090.       break;
  1091.      }
  1092.      update();
  1093.      userno=x;
  1094.      getuser();
  1095.      displayuser();
  1096.     break;
  1097.     case 59:
  1098.      userlist();
  1099.      printer("\n[Enter] to continue...");
  1100.      getch();
  1101.      displayuser();
  1102.     break;
  1103.     case 61:
  1104.      update();
  1105.      packusers();
  1106.      userno=1;
  1107.      if((findfirst("USERS.BBS",&f,0)!=0) or (f.ff_fsize==0L)) {
  1108.        printf("\nYou must have a user file.\n");
  1109.        exit(2);
  1110.      }
  1111.      printer("\n[Enter] to continue...");
  1112.      getch();
  1113.      getuser();
  1114.      displayuser();
  1115.     break;
  1116.     case 62:
  1117.      user.stat[0]=0;
  1118.      changed=1;
  1119.      displayuser();
  1120.     break;
  1121.     case 71:
  1122.      update();
  1123.      userno=1;
  1124.      getuser();
  1125.      displayuser();
  1126.      break;
  1127.     case 79:
  1128.      update();
  1129.      userno=(unsigned int)(f.ff_fsize/(long)sizeof(struct _user));
  1130.      if (userno==0) userno=(unsigned int)(f.ff_fsize/(long)sizeof(struct _user));
  1131.      getuser();
  1132.      displayuser();
  1133.     break;
  1134.     case 63:
  1135.      update();
  1136.      printer("\nEnter string to search for: ");
  1137.      x=finduser(strupr(genin(36,0,0,0,NAME)),userno);
  1138.      if ((f.ff_fsize/(long)sizeof(struct _user)<(long)x) or (x<1)) x=userno;
  1139.      userno=x;
  1140.      getuser();
  1141.      displayuser();
  1142.     break;
  1143.     case 66:
  1144.      update();
  1145.      printf("\nNumber of days to delete from? ");
  1146.      fgets(temp,16,stdin);
  1147.      if (*temp=='\n') {
  1148.         displayuser();
  1149.         break;
  1150.      }
  1151.      numdays=(word)atol(temp);
  1152.      if (numdays<=1) {
  1153.         printer("\nI think you goofed.\n[Enter] to continue...");
  1154.         getch();
  1155.         displayuser();
  1156.         break;
  1157.      }
  1158.      deletebyday(numdays);
  1159.      userno=1;
  1160.      if((findfirst("USERS.BBS",&f,0)!=0) or (f.ff_fsize==0L)) {
  1161.        printf("\nYou must have a user file.\n");
  1162.        exit(2);
  1163.      }
  1164.      printer("\n[Enter] to continue...");
  1165.      getch();
  1166.      getuser();
  1167.      displayuser();
  1168.      break;
  1169.     case 65:
  1170.      update();
  1171.      dellocked();
  1172.      userno=1;
  1173.      if((findfirst("USERS.BBS",&f,0)!=0) or (f.ff_fsize==0L)) {
  1174.        printf("\nYou must have a user file.\n");
  1175.        exit(2);
  1176.      }
  1177.      printer("\n[Enter] to continue...");
  1178.      getch();
  1179.      getuser();
  1180.      displayuser();
  1181.      break;
  1182.     case 33:
  1183.      if (conf.genstatezip) break;
  1184.      printer("\nZipcode: ");
  1185.      p=genin(5,0,0,0,NUM);
  1186.      if (strlen(p)==5) {
  1187.        strcpy(user.zip,p);
  1188.        changed=1;
  1189.      }
  1190.      displayuser();
  1191.     break;
  1192.     case 67:
  1193.      user.violations=0;
  1194.      changed=1;
  1195.      displayuser();
  1196.      break;
  1197.     case 129: user.ansimenus=1-user.ansimenus;
  1198.               changed=1;
  1199.               displayuser();
  1200.               break;
  1201.     case 120: user.gen1=1-user.gen1;
  1202.               changed=1;
  1203.               displayuser();
  1204.               break;
  1205.     case 121: user.gen2=1-user.gen2;
  1206.               changed=1;
  1207.               displayuser();
  1208.               break;
  1209.     case 122: user.gen3=1-user.gen3;
  1210.               changed=1;
  1211.               displayuser();
  1212.               break;
  1213.     case 123: printer("\nFlag # to toggle (1-16): ");
  1214.               tempo=(word)atoi(genin(2,0,0,0,NUM));
  1215.               if (tempo<1 || tempo>16) {
  1216.                 displayuser();
  1217.                 break;
  1218.               }
  1219.               x=1;
  1220.               x=x<<(tempo-1);
  1221.               user.attr2 = user.attr2 ^ x;
  1222.               changed=1;
  1223.               displayuser();
  1224.               break;
  1225.     case 124: printer("\nNew Upload K for today: ");
  1226.               p=genin(5,0,0,0,NUM);
  1227.               if (!*p) break;
  1228.               user.uktoday=(word)atol(p);
  1229.               changed=1;
  1230.               displayuser();
  1231.               break;
  1232.     case 125: printer("\nNew Download K for today: ");
  1233.               p=genin(5,0,0,0,NUM);
  1234.               if (!*p) break;
  1235.               user.dktoday=(word)atol(p);
  1236.               changed=1;
  1237.               displayuser();
  1238.               break;
  1239.     case 30:
  1240. Retry:
  1241.               printer("\nNew Computer Type (1-255): ");
  1242.               p=genin(3,0,0,0,NUM);
  1243.               if ((char)atoi(p)<1 || (char)atoi(p)>255) goto Retry;
  1244.               user.comptype=(char)atoi(p);
  1245.               changed=1;
  1246.               displayuser();
  1247.               break;
  1248.     case 64:  if (online_user) {
  1249.                   changed=1;
  1250.                   update();
  1251.                   online_user=0;
  1252.                   getuser();
  1253.                   displayuser();
  1254.               }
  1255.               else {
  1256.                   changed=1;
  1257.                   update();
  1258.                   online_user=1;
  1259.                   getuser();
  1260.                   displayuser();
  1261.               }
  1262.               break;
  1263.     case 17:  {
  1264.  
  1265.                 char dostring[133];
  1266.  
  1267.                   sprintf(dostring,"USERED.BAT %sFORCE\\%08lx.%03hu\n",conf.homepath,user.id,user.node);
  1268.                   system(dostring);
  1269.                   displayuser();
  1270.  
  1271.               }
  1272.               break;
  1273.     case 126: user.hiok=1-user.hiok;
  1274.               changed=1;
  1275.               displayuser();
  1276.               break;
  1277.     case 127: printer("\nNew Last Msg Area #: ");
  1278.               p=genin(5,0,0,0,NUM);
  1279.               if (!*p) break;
  1280.               if((word)atol(p)<1024) {
  1281.                 user.lastmsgarea=(word)atol(p);
  1282.                 changed=1;
  1283.               }
  1284.               else {
  1285.                 printer("\n0-1023...");
  1286.                 sleep(1);
  1287.               }
  1288.               displayuser();
  1289.               break;
  1290.     case 25:  printer("\nNew Point #: ");
  1291.               p=genin(5,0,0,0,NUM);
  1292.               if(!*p) break;
  1293.               user.pointid=(word)atol(p);
  1294.               changed=1;
  1295.               displayuser();
  1296.               break;
  1297.     default:  fputs("\07",stdout);
  1298.               return 0;
  1299.   }
  1300.   return 0;
  1301.  
  1302. }
  1303.  
  1304.  
  1305.  
  1306. char regularkey (char a) {
  1307.  
  1308.  word x;
  1309.  char *p;
  1310.  char text[24];
  1311.  word temp=0;
  1312.  char tempo[16];
  1313.  
  1314.  strset(tempo,0);
  1315.  
  1316.   switch ((int)toupper(a))
  1317.    {
  1318.     case 'A':
  1319.      printer("\nName: ");
  1320.      p=genin(35,0,0,0,NAME);
  1321.      rstrip(p);
  1322.      if (strlen(p)>1)
  1323.       {
  1324.        strcpy(user.name,p);
  1325.        changed=1;
  1326.       }
  1327.      displayuser();
  1328.     break;
  1329.     case 'B':
  1330.      printer("\nHandle: ");
  1331.      p=genin(35,0,0,0,NAME);
  1332.      rstrip(p);
  1333.      if (strlen(p)>1)
  1334.       {
  1335.        strcpy(user.handle,p);
  1336.        changed=1;
  1337.       }
  1338.      displayuser();
  1339.     break;
  1340.     case 'C':
  1341.      printer("\nPassword: ");
  1342.      p=genin(11,0,0,0,ALL);
  1343.      rstrip(p);
  1344.      if (strlen(p)>2)
  1345.       {
  1346.        strcpy(user.password,p);
  1347.        changed=1;
  1348.       }
  1349.      displayuser();
  1350.     break;
  1351.     case 'D':
  1352.      printer("\nCity: ");
  1353.      p=genin(23,0,0,0,NEAT);
  1354.      rstrip(p);
  1355.      if (strlen(p)>1)
  1356.       {
  1357.        strcpy(user.city,p);
  1358.        changed=1;
  1359.       }
  1360.      displayuser();
  1361.     break;
  1362.     case 'E':
  1363.      if (!conf.genstatezip) {
  1364.          printer("\nState abbreviation: ");
  1365.          p=genin(2,0,1,0,ALPHA);
  1366.          rstrip(p);
  1367.          if (strlen(p)==2)
  1368.           {
  1369.            strcpy(user.state,p);
  1370.            changed=1;
  1371.           }
  1372.      }
  1373.      else {
  1374.         printer("\nGeneric field: ");
  1375.         p=genin(8,0,0,0,ALPHANUM);
  1376.         changed=1;
  1377.         rstrip(p);
  1378.         strcpy(user.state,p);
  1379.      }
  1380.      displayuser();
  1381.     break;
  1382.     case 'F':
  1383.      printer("\nPhone 1: ");
  1384.      p=genin(10,0,1,0,NUM);
  1385.      rstrip(p);
  1386.      if(strlen(p)==10)
  1387.       {
  1388.        strcpy(user.phone1,p);
  1389.        changed=1;
  1390.       }
  1391.      displayuser();
  1392.     break;
  1393.     case 'G':
  1394.      printer("\nPhone 2: ");
  1395.      p=genin(10,0,1,0,NUM);
  1396.      rstrip(p);
  1397.      if(strlen(p)==10)
  1398.       {
  1399.        strcpy(user.phone2,p);
  1400.        changed=1;
  1401.       }
  1402.      displayuser();
  1403.     break;
  1404.     case 'H':
  1405.      printer("\nBirthdate: ");
  1406.      p=genin(10,0,0,0,ALL);
  1407.      left(text,p,2);
  1408.      user.birthdate.da_mon=atoi(text);
  1409.      mid(text,p,4,2);
  1410.      user.birthdate.da_day=atoi(text);
  1411.      right(text,p,4);
  1412.      user.birthdate.da_year=atoi(text);
  1413.      changed=1;
  1414. nope:
  1415.      displayuser();
  1416.     break;
  1417.     case 'I':
  1418.      printer("\nLength: ");
  1419.      p=genin(2,0,1,0,NUM);
  1420.      rstrip(p);
  1421.      if(strlen(p)>0)
  1422.       {
  1423.        user.length=(char)atoi(p);
  1424.        if (user.length<10) user.length=10;
  1425.        if (user.length>66) user.length=66;
  1426.        changed=1;
  1427.       }
  1428.      displayuser();
  1429.     break;
  1430.     case 'J':
  1431.      printer("\nWidth: ");
  1432.      p=genin(2,0,1,0,NUM);
  1433.      rstrip(p);
  1434.      if(strlen(p)>0)
  1435.       {
  1436.        user.width=(char)atoi(p);
  1437.        if (user.width<32) user.width=32;
  1438.        if (user.width>80) user.width=80;
  1439.        changed=1;
  1440.       }
  1441.      displayuser();
  1442.     break;
  1443.     case 'K':
  1444.      printer("\nSecurity Level #: ");
  1445.      fgets(tempo,16,stdin);
  1446.      temp=(char)atol(tempo);
  1447.      if ((!strlen(tempo)) || temp<0 || temp>9 || *tempo=='\n') {
  1448.         displayuser();
  1449.         break;
  1450.      }
  1451.      printer("Enter new seclvl: ");
  1452.      fgets(tempo,16,stdin);
  1453.      if ((!strlen(tempo)) || *tempo=='\n') {
  1454.         displayuser();
  1455.         break;
  1456.      }
  1457.      user.stat[temp]=(word)atol(tempo);
  1458.      changed=1;
  1459.      displayuser();
  1460.     break;
  1461.     case 'L':
  1462.      break;
  1463.     case 'M':
  1464.      printer("\nCalls Per Day: ");
  1465.      p=genin(5,0,1,0,NUM);
  1466.      rstrip(p);
  1467.      if(strlen(p)>0)
  1468.       {
  1469.        user.callsperday=(word)atol(p);
  1470.        changed=1;
  1471.       }
  1472.      displayuser();
  1473.     break;
  1474.     case 'N':
  1475.      printer("\nTime Per Call: ");
  1476.      p=genin(5,0,1,0,NUM);
  1477.      rstrip(p);
  1478.      if(strlen(p)>0)
  1479.       {
  1480.        user.timepercall=(word)atol(p);
  1481.        changed=1;
  1482.       }
  1483.      displayuser();
  1484.     break;
  1485.     case 'O':
  1486.      printer("\nTotal Time: ");
  1487.      p=genin(5,0,1,0,NUM);
  1488.      rstrip(p);
  1489.      if(strlen(p)>0)
  1490.       {
  1491.        user.totaltime=(word)atol(p);
  1492.        changed=1;
  1493.       }
  1494.      displayuser();
  1495.     break;
  1496.     case 'P':
  1497.      printer("\nCalls Today: ");
  1498.      p=genin(5,0,1,0,NUM);
  1499.      rstrip(p);
  1500.      if(strlen(p)>0)
  1501.       {
  1502.        user.callstoday=(word)atol(p);
  1503.        changed=1;
  1504.       }
  1505.      displayuser();
  1506.     break;
  1507.     case 'Q':
  1508.      printer("\nTotal Calls: ");
  1509.      p=genin(6,0,1,0,NUM);
  1510.      rstrip(p);
  1511.      if(strlen(p)>0)
  1512.       {
  1513.        user.times=atol(p);
  1514.        changed=1;
  1515.       }
  1516.      displayuser();
  1517.     break;
  1518.     case 'R':
  1519.      printer("\nTime Today: ");
  1520.      p=genin(5,0,1,0,NUM);
  1521.      rstrip(p);
  1522.      if(strlen(p)>0)
  1523.       {
  1524.        user.timetoday=(word)atol(p);
  1525.        changed=1;
  1526.       }
  1527.      displayuser();
  1528.     break;
  1529.     case 'S':
  1530.      printer("\nLast Call Date (MM/DD/YYYY): ");
  1531.      p=genin(10,0,0,0,ALL);
  1532.      rstrip(p);
  1533.      if (strlen(p)<10) goto nope2;
  1534.      left(text,p,2);
  1535.      user.lastdate.da_mon=atoi(text);
  1536.      mid(text,p,4,2);
  1537.      user.lastdate.da_day=atoi(text);
  1538.      right(text,p,4);
  1539.      user.lastdate.da_year=atoi(text);
  1540.      changed=1;
  1541. nope2:
  1542.      displayuser();
  1543.     break;
  1544.     case 'T':
  1545.      printer("\nLast Call Date (HH:MM:SS): ");
  1546.      p=genin(8,0,0,0,ALL);
  1547.      rstrip(p);
  1548.      if (strlen(p)<8) goto nope3;
  1549.      left(text,p,2);
  1550.      user.lasttime.ti_hour=atoi(text);
  1551.      mid(text,p,4,2);
  1552.      user.lasttime.ti_min=atoi(text);
  1553.      right(text,p,2);
  1554.      user.lasttime.ti_sec=atoi(text);
  1555.      changed=1;
  1556. nope3:
  1557.      displayuser();
  1558.     break;
  1559.     case 'U':
  1560.      printer("\nUploaded KBytes: ");
  1561.      p=genin(6,0,1,0,NUM);
  1562.      rstrip(p);
  1563.      if(strlen(p)>0)
  1564.       {
  1565.        user.upk=atol(p);
  1566.        changed=1;
  1567.       }
  1568.      displayuser();
  1569.     break;
  1570.     case 'V':
  1571.      printer("\nDownloaded KBytes: ");
  1572.      p=genin(6,0,1,0,NUM);
  1573.      rstrip(p);
  1574.      if(strlen(p)>0)
  1575.       {
  1576.        user.downk=atol(p);
  1577.        changed=1;
  1578.       }
  1579.      displayuser();
  1580.     break;
  1581.     case 'W':
  1582.      printer("\nNumber of files uploaded: ");
  1583.      p=genin(6,0,1,0,NUM);
  1584.      rstrip(p);
  1585.      if(strlen(p)>0)
  1586.       {
  1587.        user.upno=(word)atol(p);
  1588.        changed=1;
  1589.       }
  1590.      displayuser();
  1591.     break;
  1592.     case 'X':
  1593.      printer("\nNumber of files downloaded: ");
  1594.      p=genin(6,0,1,0,NUM);
  1595.      rstrip(p);
  1596.      if(strlen(p)>0)
  1597.       {
  1598.        user.downno=(word)atol(p);
  1599.        changed=1;
  1600.       }
  1601.      displayuser();
  1602.     break;
  1603.     case 'Y':
  1604.      printer("\nNumber of messages posted: ");
  1605.      p=genin(6,0,1,0,NUM);
  1606.      rstrip(p);
  1607.      if(strlen(p)>0)
  1608.       {
  1609.        user.posts=atol(p);
  1610.        changed=1;
  1611.       }
  1612.      displayuser();
  1613.     break;
  1614.     case 'Z':
  1615.      printer("\nCredit in cents: ");
  1616.      p=genin(5,0,1,0,NUM);
  1617.      rstrip(p);
  1618.      if(strlen(p)>0)
  1619.       {
  1620.        user.credit=atoi(p);
  1621.        changed=1;
  1622.       }
  1623.      displayuser();
  1624.     break;
  1625.     case '0': user.graphics=1-user.graphics;
  1626.               changed=1;
  1627.               displayuser();
  1628.               break;
  1629.     case '1': user.fullscreen=1-user.fullscreen;
  1630.               changed=1;
  1631.               displayuser();
  1632.               break;
  1633.     case '2': user.scrnclr=1-user.scrnclr;
  1634.               changed=1;
  1635.               displayuser();
  1636.               break;
  1637.     case '3': user.commodore=1-user.commodore;
  1638.               changed=1;
  1639.               displayuser();
  1640.               break;
  1641.     case '4': user.expert=1-user.expert;
  1642.               changed=1;
  1643.               displayuser();
  1644.               break;
  1645.     case '5': user.more=1-user.more;
  1646.               changed=1;
  1647.               displayuser();
  1648.               break;
  1649.     case '6': user.ignorehrs=1-user.ignorehrs;
  1650.               changed=1;
  1651.               displayuser();
  1652.               break;
  1653.     case '7': user.ignorerat=1-user.ignorerat;
  1654.               changed=1;
  1655.               displayuser();
  1656.               break;
  1657.     case '8': user.nokill=1-user.nokill;
  1658.               changed=1;
  1659.               displayuser();
  1660.               break;
  1661.     case '9': if (user.nokill && !user.deleted) {
  1662.                     printf("\x7");
  1663.                     break;
  1664.               }
  1665.               user.deleted=1-user.deleted;
  1666.               changed=1;
  1667.               displayuser();
  1668.               break;
  1669.     case ':': user.cold=1-user.cold;
  1670.               changed=1;
  1671.               displayuser();
  1672.               break;
  1673.     case ';': user.twit=1-user.twit;
  1674.               changed=1;
  1675.               displayuser();
  1676.               break;
  1677.     case '?': fputs("\r",stdout);
  1678.               printer("ALT-X to exit, CTRL-Page Up or CTRL-Page Down for next page,\n");
  1679.               printer("Page Up or Page Down for previous or next user\n");
  1680.               printer("ALT-W on first user page will spawn USERED.BAT with unique id filename.\n");
  1681.               printer("ALT-F10 will allow you to swap two users.");
  1682.               while(!kbhit());
  1683.               displayuser();
  1684.               break;
  1685.     default:  fputs("\x7",stdout);
  1686.               return 0;
  1687.  }
  1688.  
  1689.  return 0;
  1690.  
  1691. }
  1692.  
  1693.  
  1694.  
  1695. void left(a,b,x)
  1696.  
  1697. char *a,*b;
  1698. word x;
  1699.  
  1700. {
  1701.  
  1702.   word i=0;
  1703.  
  1704.   x = (x <= strlen(b)) ? x : strlen(b);
  1705.  
  1706.   while (i++ < x) *a++ = *b++;
  1707.  
  1708.     *a = '\0';
  1709.  
  1710. }
  1711.  
  1712.  
  1713. void right(a,b,x)
  1714.  
  1715. char *a,*b;
  1716. word x;
  1717.  
  1718. {
  1719.  
  1720.   word i,l;
  1721.  
  1722.   l = strlen(b);
  1723.   x=(x>l) ? l : x;
  1724.   i = l - x;
  1725.  
  1726.   while (*a++ = *(b + i++));
  1727.  
  1728. }
  1729.  
  1730.  
  1731. void mid(a,b,x,y)
  1732.  
  1733. char *a,*b;
  1734. word x,y;
  1735.  
  1736. {
  1737.  
  1738.   word l;
  1739.  
  1740.   --x;
  1741.   y+=x;
  1742.   l = strlen(b);
  1743.  
  1744.   while (x<y and x<=l) *a++ = *(b + x++);
  1745.  
  1746.   *a = '\0';
  1747.  
  1748. }
  1749.  
  1750.  
  1751. word finduser (string,x)
  1752.  
  1753. char *string;
  1754. word  x;
  1755.  
  1756. {
  1757.  
  1758. struct _user check;
  1759. FILE *fp;
  1760. word start;
  1761.  
  1762. start=x;
  1763.  
  1764. strupr(string);
  1765. if(!(fp=fopen("users.bbs","rb"))) {
  1766.    printer("\nError with userfile...\n");
  1767.    perror("\nERROR");
  1768.    return(0);
  1769. }
  1770. Restart:
  1771.    fseek(fp,(long)((long)(x+1)*(long)sizeof(struct _user)),SEEK_SET);
  1772.    while (!feof(fp) && !ferror(fp)) {
  1773.      ++x;
  1774.      if (x==start) goto Notfound;
  1775.      if ((fread(&check,sizeof(struct _user),1,fp)!=1)) break;
  1776.      strupr(check.name);
  1777.      strupr(check.handle);
  1778.      if (strstr(check.name,string) || strstr(check.handle,string)) {
  1779.         fclose(fp);
  1780.         return (++x);
  1781.      }
  1782.    }
  1783.  if (start) {
  1784.     x=0;
  1785.     goto Restart;
  1786.  }
  1787.  
  1788. Notfound:
  1789.  
  1790.  fclose(fp);
  1791.  return (0);
  1792.  
  1793. }
  1794.  
  1795.  
  1796. void printer (char *string,...)
  1797.  
  1798. {
  1799.  
  1800. static char text[256];
  1801. char *p;
  1802. char *pp;
  1803.  
  1804.  va_list ap;
  1805.  va_start(ap,string);
  1806.  vsprintf(text,string,ap);
  1807.  va_end(ap);
  1808.  if (usedirect>0) {
  1809.     if ((p=strchr(text,'\n'))==NULL) cputs(text);
  1810.     else {
  1811.         pp=text;
  1812.         do {
  1813.             p=strchr(pp,'\n');
  1814.             if (p) *p++=0;
  1815.             cputs(pp);
  1816.             if (p) {
  1817.                 cputs("\r\n");
  1818.                 pp=p;
  1819.             }
  1820.         } while (p && *pp!=0);
  1821.     }
  1822.  }
  1823.  else fputs(text,stdout);
  1824.  
  1825. }
  1826.  
  1827.  
  1828. ulong diffdays (then)
  1829.  
  1830.   struct date *then;
  1831.  
  1832. {
  1833.   ulong numdays=0;
  1834.   ulong today=0;
  1835.   word register x;
  1836.   struct date dos_date;
  1837.   char month[13]={
  1838.     0,31,28,31,30,31,30,31,31,30,31,30,31
  1839.   };
  1840.  
  1841.   getdate(&dos_date);
  1842.   for (x=1987;x<dos_date.da_year;x++) numdays=numdays+365;
  1843.   for (x=1;x<dos_date.da_mon;x++) numdays=numdays+month[x];
  1844.   today=numdays+dos_date.da_day;
  1845.   numdays=0;
  1846.   for (x=1987;x<then->da_year;x++) numdays=numdays+365;
  1847.   for (x=1;x<then->da_mon;x++) numdays=numdays+month[x];
  1848.   numdays=numdays+then->da_day;
  1849.   if(today<numdays) {
  1850.     printf("\nToday: %lu\nNumdays: %lu\n",today,numdays);
  1851.     return 0;
  1852.   }
  1853.   return (today-numdays);
  1854.  
  1855. }
  1856.  
  1857.  
  1858.