|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.