home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / ALLUSERS / ALLUSERS.C next >
Encoding:
C/C++ Source or Header  |  1997-04-13  |  10.8 KB  |  368 lines

  1. /* ALLUSERS.C */
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. /****************************************************************************/
  6. /* Makes global changes to Synchronet user database (USER.DAT)                */
  7. /* Compatible with Version 2.1 of Synchronet BBS Software                    */
  8. /****************************************************************************/
  9.  
  10. #include <io.h>
  11. #include <share.h>
  12. #include <stdio.h>
  13. #include <fcntl.h>
  14. #include <errno.h>
  15. #include <stdlib.h>
  16. #include <sys/stat.h>
  17.  
  18. #include "sbbsdefs.h"
  19.  
  20. int  min=0,max=99;
  21. long reqflags[4]={0},reqrest=0,reqexempt=0;
  22.  
  23. char *usage=
  24. "\nusage: allusers [data\\user path] [[-require] [...]] "
  25.     "/modify [[/modify] [...]]\n"
  26. "\nwhere require is one of:\n"
  27. "       L#                  set minimum level to # (default=0)\n"
  28. "       M#                  set maximum level to # (default=99)\n"
  29. "       F#<flags>           set required flags from flag set #\n"
  30. "       E<flags>            set required exemptions\n"
  31. "       R<flags>            set required restrictions\n"
  32. "\nwhere modify is one of:\n"
  33. "       L#                  change security level to #\n"
  34. "       F#[+|-]<flags>      add or remove flags from flag set #\n"
  35. "       E[+|-]<flags>       add or remove exemption flags\n"
  36. "       R[+|-]<flags>       add or remove restriction flags\n"
  37. "\nExamples:\n"
  38. "       ALLUSERS -L30 /FA   add 'A' to flag set #1 for all level 30+ users\n"
  39. "       ALLUSERS /F3-G      remove 'G' from flag set #3 for all users\n"
  40. "       ALLUSERS -F2B /E-P  remove 'P' exemption for all users with FLAG '2B'\n"
  41. "       ALLUSERS /R+W       add 'W' restriction for all users\n"
  42. ;
  43.  
  44. /****************************************************************************/
  45. /* Attempts to lock a user record, retries for up to 10 seconds             */
  46. /* Returns 0 on success, -1 on failure                                        */
  47. /****************************************************************************/
  48. int lockuser(FILE *stream, ulong offset)
  49. {
  50.     time_t start;
  51.  
  52. if(lock(fileno(stream),offset,U_LEN)==0)
  53.     return(0);
  54. start=time(NULL);
  55. while(1) {
  56.     if(lock(fileno(stream),offset,U_LEN)==0)
  57.         return(0);
  58.     if(time(NULL)-start>=10L)
  59.         break; }
  60. return(-1);
  61. }
  62.  
  63. /****************************************************************************/
  64. /* Converts an ASCII Hex string into an ulong                                */
  65. /****************************************************************************/
  66. ulong ahtoul(char *str)
  67. {
  68.     ulong l,val=0;
  69.  
  70. while((l=(*str++)|0x20)!=0x20)
  71.     val=(l&0xf)+(l>>6&1)*9+val*16;
  72. return(val);
  73. }
  74.  
  75. /****************************************************************************/
  76. /* Truncates white-space chars off end of 'str' and terminates at first tab */
  77. /****************************************************************************/
  78. void truncsp(char *str)
  79. {
  80.     char c;
  81.  
  82. str[strcspn(str,"\t")]=0;
  83. c=strlen(str);
  84. while(c && (uchar)str[c-1]<=SP) c--;
  85. str[c]=0;
  86. }
  87.  
  88. /****************************************************************************/
  89. /* Returns bytes offset into user record for flag set # 'set'               */
  90. /****************************************************************************/
  91. long getflagoff(int set)
  92. {
  93. switch(set) {
  94.     default:
  95.         return(U_FLAGS1);
  96.     case 2:
  97.         return(U_FLAGS2);
  98.     case 3:
  99.         return(U_FLAGS3);
  100.     case 4:
  101.         return(U_FLAGS4); }
  102. }
  103.  
  104. /****************************************************************************/
  105. /* Checks a user record against the requirements set on the command line    */
  106. /* Returns 1 if the user meets the requirements (or no requirements were    */
  107. /* specified) or 0 if the user does not meet any of the requirements.        */
  108. /****************************************************************************/
  109. int chkuser(FILE *stream, long offset)
  110. {
  111.     char str[128];
  112.     int i;
  113.  
  114. if(min || max!=99) {            /* Check security level */
  115.     fseek(stream,offset+U_LEVEL,SEEK_SET);
  116.     if(!fread(str,2,1,stream))
  117.         return(0);
  118.     str[2]=0;
  119.     i=atoi(str);
  120.     if(i<min || i>max)            /* not within range */
  121.         return(0); }            /* so skip this user */
  122.  
  123. for(i=0;i<4;i++)
  124.     if(reqflags[i]) {
  125.         fseek(stream,offset+getflagoff(i+1),SEEK_SET);
  126.         if(!fread(str,8,1,stream))
  127.             return(0);
  128.         str[8]=0;
  129.         truncsp(str);
  130.         if((ahtoul(str)&reqflags[i])!=reqflags[i])
  131.             return(0); }    /* doesn't have 'em all */
  132.  
  133. if(reqrest) {
  134.     fseek(stream,offset+U_REST,SEEK_SET);
  135.     if(!fread(str,8,1,stream))
  136.         return(0);
  137.     str[8]=0;
  138.     truncsp(str);
  139.     if((ahtoul(str)&reqrest)!=reqrest)
  140.         return(0); }
  141.  
  142. if(reqexempt) {
  143.     fseek(stream,offset+U_REST,SEEK_SET);
  144.     if(!fread(str,8,1,stream))
  145.         return(0);
  146.     str[8]=0;
  147.     truncsp(str);
  148.     if((ahtoul(str)&reqexempt)!=reqexempt)
  149.         return(0); }
  150.  
  151. return(1);
  152. }
  153.  
  154. int main(int argc, char **argv)
  155. {
  156.     char    dir[128],str[128];
  157.     int     i,j,k,file,set,sub,mod;
  158.     long    l,f,flags,flagoff,length,offset;
  159.     FILE    *stream;
  160.  
  161. printf("\nALLUSERS v2.10 - Bulk User Editor for Synchronet User Database\n");
  162.  
  163. if(argc<2) {
  164.     printf(usage);
  165.     exit(1); }
  166. dir[0]=0;
  167. for(i=1;i<argc;i++) {
  168.     flags=flagoff=sub=mod=0;
  169.     if(argv[i][0]=='-')
  170.         switch(toupper(argv[i][1])) {
  171.             case 'L':                       /* Set minimum sec level */
  172.                 min=atoi(argv[i]+2);
  173.                 break;
  174.             case 'M':                       /* Set maximum sec level */
  175.                 max=atoi(argv[i]+2);
  176.                 break;
  177.             case 'F':                       /* Set required flags */
  178.                 j=3;
  179.                 set=1;
  180.                 if(isdigit(argv[i][2]))
  181.                     set=argv[i][2]&0xf;
  182.                 else
  183.                     j=2;
  184.                 for(;argv[i][j];j++)
  185.                     if(isalpha(argv[i][j]))
  186.                         reqflags[set-1]|=FLAG(toupper(argv[i][j]));
  187.                 break;
  188.             case 'R':                       /* Set required restrictions */
  189.                 for(j=2;argv[i][j];j++)
  190.                     if(isalpha(argv[i][j]))
  191.                         reqrest|=FLAG(toupper(argv[i][j]));
  192.                 break;
  193.             case 'E':                       /* Set required exemptions */
  194.                 for(j=2;argv[i][j];j++)
  195.                     if(isalpha(argv[i][j]))
  196.                         reqexempt|=FLAG(toupper(argv[i][j]));
  197.                 break;
  198.             default:                        /* Unrecognized include */
  199.                 printf(usage);
  200.                 exit(1); }
  201.  
  202.     else if(argv[i][0]=='/')
  203.         switch(toupper(argv[i][1])) {
  204.             case 'F':   /* flags */
  205.                 j=3;
  206.                 set=1;
  207.                 if(isdigit(argv[i][2]))
  208.                     set=argv[i][2]&0xf;
  209.                 else
  210.                     j=2;
  211.                 if(argv[i][j]=='+')
  212.                     j++;
  213.                 else if(argv[i][j]=='-') {
  214.                     j++;
  215.                     sub=1; }
  216.                 for(;argv[i][j];j++)
  217.                     if(isalpha(argv[i][j]))
  218.                         flags|=FLAG(toupper(argv[i][j]));
  219.                 sprintf(str,"%sUSER.DAT",dir);
  220.                 if((file=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) {
  221.                     printf("Error opening %s\n",str);
  222.                     exit(1); }
  223.                 if((stream=fdopen(file,"w+b"))==NULL) {
  224.                     printf("Error opening %s\n",str);
  225.                     exit(1); }
  226.                 setvbuf(stream,NULL,_IOFBF,2048);
  227.                 length=filelength(file);
  228.                 printf("\n%s Flags %s Set #%d\n",sub ? "Removing":"Adding"
  229.                     ,sub ? "from":"to",set);
  230.                 for(offset=0;offset<length;offset+=U_LEN) {
  231.                     printf("%lu of %lu (%u modified)\r"
  232.                         ,(offset/U_LEN)+1,length/U_LEN,mod);
  233.                     if(lockuser(stream,offset)) {
  234.                         printf("Error locking offset %lu\n",offset);
  235.                         continue; }
  236.                     if(!chkuser(stream,offset)) {
  237.                         unlock(fileno(stream),offset,U_LEN);
  238.                         continue; }
  239.                     flagoff=getflagoff(set);
  240.                     fseek(stream,offset+flagoff,SEEK_SET);
  241.                     fread(str,8,1,stream);
  242.                     str[8]=0;
  243.                     truncsp(str);
  244.                     l=f=ahtoul(str);
  245.                     if(sub)
  246.                         l&=~flags;
  247.                     else
  248.                         l|=flags;
  249.                     if(l==f) {    /* no change */
  250.                         unlock(fileno(stream),offset,U_LEN);
  251.                         continue; }
  252.                     mod++;
  253.                     sprintf(str,"%lx",l);
  254.                     while(strlen(str)<8)
  255.                         strcat(str,"\3");
  256.                     fseek(stream,offset+flagoff,SEEK_SET);
  257.                     fwrite(str,8,1,stream);
  258.                     unlock(fileno(stream),offset,U_LEN); }
  259.                 fclose(stream);
  260.                 printf("\n");
  261.                 break;
  262.            case 'E':    /* Exemptions */
  263.                 flagoff=U_EXEMPT;
  264.            case 'R':    /* Restrictions */
  265.                 if(!flagoff)
  266.                     flagoff=U_REST;
  267.                 j=2;
  268.                 if(argv[i][j]=='+')
  269.                     j++;
  270.                 else if(argv[i][j]=='-') {
  271.                     j++;
  272.                     sub=1; }
  273.                 for(;argv[i][j];j++)
  274.                     if(isalpha(argv[i][j]))
  275.                         flags|=FLAG(toupper(argv[i][j]));
  276.                 sprintf(str,"%sUSER.DAT",dir);
  277.                 if((file=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) {
  278.                     printf("Error opening %s\n",str);
  279.                     exit(1); }
  280.                 if((stream=fdopen(file,"w+b"))==NULL) {
  281.                     printf("Error opening %s\n",str);
  282.                     exit(1); }
  283.                 setvbuf(stream,NULL,_IOFBF,2048);
  284.                 length=filelength(file);
  285.                 printf("\n%s %s\n"
  286.                     ,sub ? "Removing":"Adding"
  287.                     ,flagoff==U_REST ? "Restrictions":"Exemptions");
  288.                 for(offset=0;offset<length;offset+=U_LEN) {
  289.                     printf("%lu of %lu (%u modified)\r"
  290.                         ,(offset/U_LEN)+1,length/U_LEN,mod);
  291.                     if(lockuser(stream,offset)) {
  292.                         printf("Error locking offset %lu\n",offset);
  293.                         continue; }
  294.                     if(!chkuser(stream,offset)) {
  295.                         unlock(fileno(stream),offset,U_LEN);
  296.                         continue; }
  297.                     fseek(stream,offset+flagoff,SEEK_SET);
  298.                     fread(str,8,1,stream);
  299.                     str[8]=0;
  300.                     truncsp(str);
  301.                     l=f=ahtoul(str);
  302.                     if(sub)
  303.                         l&=~flags;
  304.                     else
  305.                         l|=flags;
  306.                     if(l==f) {    /* no change */
  307.                         unlock(fileno(stream),offset,U_LEN);
  308.                         continue; }
  309.                     mod++;
  310.                     sprintf(str,"%lx",l);
  311.                     while(strlen(str)<8)
  312.                         strcat(str,"\3");
  313.                     fseek(stream,offset+flagoff,SEEK_SET);
  314.                     fwrite(str,8,1,stream);
  315.                     unlock(fileno(stream),offset,U_LEN); }
  316.                 fclose(stream);
  317.                 printf("\n");
  318.                 break;
  319.            case 'L':    /* Level */
  320.                 j=atoi(argv[i]+2);
  321.                 if(j>99)
  322.                     j=99;
  323.                 if(j<0)
  324.                     j=0;
  325.                 sprintf(str,"%sUSER.DAT",dir);
  326.                 if((file=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) {
  327.                     printf("Error opening %s\n",str);
  328.                     exit(1); }
  329.                 if((stream=fdopen(file,"w+b"))==NULL) {
  330.                     printf("Error opening %s\n",str);
  331.                     exit(1); }
  332.                 setvbuf(stream,NULL,_IOFBF,2048);
  333.                 length=filelength(file);
  334.                 printf("\nChanging Levels\n");
  335.                 for(offset=0;offset<length;offset+=U_LEN) {
  336.                     printf("%lu of %lu (%u modified)\r"
  337.                         ,(offset/U_LEN)+1,length/U_LEN,mod);
  338.                     if(lockuser(stream,offset)) {
  339.                         printf("Error locking offset %lu\n",offset);
  340.                         continue; }
  341.                     if(!chkuser(stream,offset)) {
  342.                         unlock(fileno(stream),offset,U_LEN);
  343.                         continue; }
  344.                     fseek(stream,offset+U_LEVEL,SEEK_SET);
  345.                     fread(str,2,1,stream);
  346.                     str[2]=0;
  347.                     truncsp(str);
  348.                     if(atoi(str)==j) {        /* no change */
  349.                         unlock(fileno(stream),offset,U_LEN);
  350.                         continue; }
  351.                     sprintf(str,"%02u",j);
  352.                     fseek(stream,offset+U_LEVEL,SEEK_SET);
  353.                     fwrite(str,2,1,stream);
  354.                     unlock(fileno(stream),offset,U_LEN);
  355.                     mod++; }
  356.                 fclose(stream);
  357.                 printf("\n");
  358.                 break;
  359.             default:
  360.                 printf(usage);
  361.                 exit(1); }
  362.     else {
  363.         strcpy(dir,argv[i]);
  364.         if(dir[strlen(dir)-1]!='\\' && dir[strlen(dir)-1]!=':')
  365.             strcat(dir,"\\"); } }
  366. return(0);
  367. }
  368.