|
|
1.1.1.2 ! root 1: /* $Id: allusers.c,v 1.5 2011/07/13 11:27:37 rswindell Exp $ */ 1.1 root 2: 1.1.1.2 ! root 3: /**************************************************************************** ! 4: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 5: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 6: * * ! 7: * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html * ! 8: * * ! 9: * This program is free software; you can redistribute it and/or * ! 10: * modify it under the terms of the GNU General Public License * ! 11: * as published by the Free Software Foundation; either version 2 * ! 12: * of the License, or (at your option) any later version. * ! 13: * See the GNU General Public License for more details: gpl.txt or * ! 14: * http://www.fsf.org/copyleft/gpl.html * ! 15: * * ! 16: * Anonymous FTP access to the most recent released source is available at * ! 17: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 18: * * ! 19: * Anonymous CVS access to the development source and modification history * ! 20: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 21: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 22: * (just hit return, no password is necessary) * ! 23: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 24: * * ! 25: * For Synchronet coding style and modification guidelines, see * ! 26: * http://www.synchro.net/source.html * ! 27: * * ! 28: * You are encouraged to submit any modifications (preferably in Unix diff * ! 29: * format) via e-mail to [email protected] * ! 30: * * ! 31: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 32: ****************************************************************************/ 1.1 root 33: 34: #include <stdio.h> 35: #include <fcntl.h> 36: #include <errno.h> 37: #include <stdlib.h> 38: #include <sys/stat.h> 39: 1.1.1.2 ! root 40: #include "sbbs.h" 1.1 root 41: 42: int min=0,max=99; 43: long reqflags[4]={0},reqrest=0,reqexempt=0; 44: 45: char *usage= 46: "\nusage: allusers [data\\user path] [[-require] [...]] " 47: "/modify [[/modify] [...]]\n" 48: "\nwhere require is one of:\n" 49: " L# set minimum level to # (default=0)\n" 50: " M# set maximum level to # (default=99)\n" 51: " F#<flags> set required flags from flag set #\n" 52: " E<flags> set required exemptions\n" 53: " R<flags> set required restrictions\n" 54: "\nwhere modify is one of:\n" 55: " L# change security level to #\n" 56: " F#[+|-]<flags> add or remove flags from flag set #\n" 57: " E[+|-]<flags> add or remove exemption flags\n" 58: " R[+|-]<flags> add or remove restriction flags\n" 59: "\nExamples:\n" 60: " ALLUSERS -L30 /FA add 'A' to flag set #1 for all level 30+ users\n" 61: " ALLUSERS /F3-G remove 'G' from flag set #3 for all users\n" 62: " ALLUSERS -F2B /E-P remove 'P' exemption for all users with FLAG '2B'\n" 63: " ALLUSERS /R+W add 'W' restriction for all users\n" 64: ; 65: 66: /****************************************************************************/ 67: /* Attempts to lock a user record, retries for up to 10 seconds */ 68: /* Returns 0 on success, -1 on failure */ 69: /****************************************************************************/ 70: int lockuser(FILE *stream, ulong offset) 71: { 72: time_t start; 73: 74: if(lock(fileno(stream),offset,U_LEN)==0) 75: return(0); 1.1.1.2 ! root 76: start=time(NULL); ! 77: while(1) { ! 78: if(lock(fileno(stream),offset,U_LEN)==0) ! 79: return(0); ! 80: if(time(NULL)-start>=10L) ! 81: break; ! 82: } ! 83: return(-1); 1.1 root 84: } 85: 86: /****************************************************************************/ 87: /* Returns bytes offset into user record for flag set # 'set' */ 88: /****************************************************************************/ 89: long getflagoff(int set) 90: { 1.1.1.2 ! root 91: switch(set) { ! 92: default: ! 93: return(U_FLAGS1); ! 94: case 2: ! 95: return(U_FLAGS2); ! 96: case 3: ! 97: return(U_FLAGS3); ! 98: case 4: ! 99: return(U_FLAGS4); ! 100: } 1.1 root 101: } 102: 103: /****************************************************************************/ 104: /* Checks a user record against the requirements set on the command line */ 105: /* Returns 1 if the user meets the requirements (or no requirements were */ 106: /* specified) or 0 if the user does not meet any of the requirements. */ 107: /****************************************************************************/ 108: int chkuser(FILE *stream, long offset) 109: { 110: char str[128]; 111: int i; 112: 1.1.1.2 ! root 113: if(min || max!=99) { /* Check security level */ ! 114: fseek(stream,offset+U_LEVEL,SEEK_SET); ! 115: if(!fread(str,2,1,stream)) ! 116: return(0); ! 117: str[2]=0; ! 118: i=atoi(str); ! 119: if(i<min || i>max) /* not within range */ ! 120: return(0); /* so skip this user */ ! 121: } ! 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: } ! 134: ! 135: if(reqrest) { ! 136: fseek(stream,offset+U_REST,SEEK_SET); 1.1 root 137: if(!fread(str,8,1,stream)) 138: return(0); 139: str[8]=0; 140: truncsp(str); 1.1.1.2 ! root 141: if((ahtoul(str)&reqrest)!=reqrest) ! 142: return(0); ! 143: } 1.1 root 144: 1.1.1.2 ! root 145: if(reqexempt) { ! 146: fseek(stream,offset+U_REST,SEEK_SET); ! 147: if(!fread(str,8,1,stream)) ! 148: return(0); ! 149: str[8]=0; ! 150: truncsp(str); ! 151: if((ahtoul(str)&reqexempt)!=reqexempt) ! 152: return(0); ! 153: } 1.1 root 154: 1.1.1.2 ! root 155: return(1); 1.1 root 156: } 157: 158: int main(int argc, char **argv) 159: { 160: char dir[128],str[128]; 1.1.1.2 ! root 161: int i,j,file,set,sub,mod; 1.1 root 162: long l,f,flags,flagoff,length,offset; 163: FILE *stream; 164: 1.1.1.2 ! root 165: printf("\nALLUSERS v2.10 - Bulk User Editor for Synchronet User Database\n"); 1.1 root 166: 1.1.1.2 ! root 167: if(argc<2) { ! 168: printf(usage); ! 169: exit(1); ! 170: } ! 171: dir[0]=0; ! 172: for(i=1;i<argc;i++) { ! 173: flags=flagoff=sub=mod=0; ! 174: if(argv[i][0]=='-') ! 175: switch(toupper(argv[i][1])) { ! 176: case 'L': /* Set minimum sec level */ ! 177: min=atoi(argv[i]+2); ! 178: break; ! 179: case 'M': /* Set maximum sec level */ ! 180: max=atoi(argv[i]+2); ! 181: break; ! 182: case 'F': /* Set required flags */ ! 183: j=3; ! 184: set=1; ! 185: if(isdigit(argv[i][2])) ! 186: set=argv[i][2]&0xf; 1.1 root 187: else 1.1.1.2 ! root 188: j=2; ! 189: for(;argv[i][j];j++) ! 190: if(isalpha(argv[i][j])) ! 191: reqflags[set-1]|=FLAG(toupper(argv[i][j])); ! 192: break; ! 193: case 'R': /* Set required restrictions */ ! 194: for(j=2;argv[i][j];j++) ! 195: if(isalpha(argv[i][j])) ! 196: reqrest|=FLAG(toupper(argv[i][j])); ! 197: break; ! 198: case 'E': /* Set required exemptions */ ! 199: for(j=2;argv[i][j];j++) ! 200: if(isalpha(argv[i][j])) ! 201: reqexempt|=FLAG(toupper(argv[i][j])); ! 202: break; ! 203: default: /* Unrecognized include */ ! 204: printf(usage); ! 205: exit(1); ! 206: } ! 207: ! 208: else if(argv[i][0]=='/') ! 209: switch(toupper(argv[i][1])) { ! 210: case 'F': /* flags */ ! 211: j=3; ! 212: set=1; ! 213: if(isdigit(argv[i][2])) ! 214: set=argv[i][2]&0xf; 1.1 root 215: else 1.1.1.2 ! root 216: j=2; ! 217: if(argv[i][j]=='+') ! 218: j++; ! 219: else if(argv[i][j]=='-') { ! 220: j++; ! 221: sub=1; ! 222: } ! 223: for(;argv[i][j];j++) ! 224: if(isalpha(argv[i][j])) ! 225: flags|=FLAG(toupper(argv[i][j])); ! 226: sprintf(str,"%suser.dat",dir); ! 227: if(!fexistcase(str) || (file=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) { ! 228: printf("Error opening %s\n",str); ! 229: exit(1); ! 230: } ! 231: if((stream=fdopen(file,"w+b"))==NULL) { ! 232: printf("Error opening %s\n",str); ! 233: exit(1); ! 234: } ! 235: setvbuf(stream,NULL,_IOFBF,2048); ! 236: length=filelength(file); ! 237: printf("\n%s Flags %s Set #%d\n",sub ? "Removing":"Adding" ! 238: ,sub ? "from":"to",set); ! 239: for(offset=0;offset<length;offset+=U_LEN) { ! 240: printf("%lu of %lu (%u modified)\r" ! 241: ,(offset/U_LEN)+1,length/U_LEN,mod); ! 242: if(lockuser(stream,offset)) { ! 243: printf("Error locking offset %lu\n",offset); ! 244: continue; ! 245: } ! 246: if(!chkuser(stream,offset)) { ! 247: unlock(fileno(stream),offset,U_LEN); ! 248: continue; ! 249: } ! 250: flagoff=getflagoff(set); ! 251: fseek(stream,offset+flagoff,SEEK_SET); ! 252: fread(str,8,1,stream); ! 253: str[8]=0; ! 254: truncsp(str); ! 255: l=f=ahtoul(str); ! 256: if(sub) ! 257: l&=~flags; ! 258: else ! 259: l|=flags; ! 260: if(l==f) { /* no change */ ! 261: unlock(fileno(stream),offset,U_LEN); ! 262: continue; ! 263: } ! 264: mod++; ! 265: sprintf(str,"%lx",l); ! 266: while(strlen(str)<8) ! 267: strcat(str,"\3"); ! 268: fseek(stream,offset+flagoff,SEEK_SET); ! 269: fwrite(str,8,1,stream); ! 270: unlock(fileno(stream),offset,U_LEN); ! 271: } ! 272: fclose(stream); ! 273: printf("\n"); ! 274: break; ! 275: case 'E': /* Exemptions */ ! 276: flagoff=U_EXEMPT; ! 277: case 'R': /* Restrictions */ ! 278: if(!flagoff) ! 279: flagoff=U_REST; ! 280: j=2; ! 281: if(argv[i][j]=='+') ! 282: j++; ! 283: else if(argv[i][j]=='-') { ! 284: j++; ! 285: sub=1; ! 286: } ! 287: for(;argv[i][j];j++) ! 288: if(isalpha(argv[i][j])) ! 289: flags|=FLAG(toupper(argv[i][j])); ! 290: sprintf(str,"%suser.dat",dir); ! 291: if(!fexistcase(str) || (file=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) { ! 292: printf("Error opening %s\n",str); ! 293: exit(1); ! 294: } ! 295: if((stream=fdopen(file,"w+b"))==NULL) { ! 296: printf("Error opening %s\n",str); ! 297: exit(1); ! 298: } ! 299: setvbuf(stream,NULL,_IOFBF,2048); ! 300: length=filelength(file); ! 301: printf("\n%s %s\n" ! 302: ,sub ? "Removing":"Adding" ! 303: ,flagoff==U_REST ? "Restrictions":"Exemptions"); ! 304: for(offset=0;offset<length;offset+=U_LEN) { ! 305: printf("%lu of %lu (%u modified)\r" ! 306: ,(offset/U_LEN)+1,length/U_LEN,mod); ! 307: if(lockuser(stream,offset)) { ! 308: printf("Error locking offset %lu\n",offset); ! 309: continue; ! 310: } ! 311: if(!chkuser(stream,offset)) { ! 312: unlock(fileno(stream),offset,U_LEN); ! 313: continue; ! 314: } ! 315: fseek(stream,offset+flagoff,SEEK_SET); ! 316: fread(str,8,1,stream); ! 317: str[8]=0; ! 318: truncsp(str); ! 319: l=f=ahtoul(str); ! 320: if(sub) ! 321: l&=~flags; ! 322: else ! 323: l|=flags; ! 324: if(l==f) { /* no change */ ! 325: unlock(fileno(stream),offset,U_LEN); ! 326: continue; ! 327: } ! 328: mod++; ! 329: sprintf(str,"%lx",l); ! 330: while(strlen(str)<8) ! 331: strcat(str,"\3"); ! 332: fseek(stream,offset+flagoff,SEEK_SET); ! 333: fwrite(str,8,1,stream); ! 334: unlock(fileno(stream),offset,U_LEN); ! 335: } ! 336: fclose(stream); ! 337: printf("\n"); ! 338: break; ! 339: case 'L': /* Level */ ! 340: j=atoi(argv[i]+2); ! 341: if(j>99) ! 342: j=99; ! 343: if(j<0) ! 344: j=0; ! 345: sprintf(str,"%suser.dat",dir); ! 346: if(!fexistcase(str) || (file=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) { ! 347: printf("Error opening %s\n",str); ! 348: exit(1); ! 349: } ! 350: if((stream=fdopen(file,"w+b"))==NULL) { ! 351: printf("Error opening %s\n",str); ! 352: exit(1); ! 353: } ! 354: setvbuf(stream,NULL,_IOFBF,2048); ! 355: length=filelength(file); ! 356: printf("\nChanging Levels\n"); ! 357: for(offset=0;offset<length;offset+=U_LEN) { ! 358: printf("%lu of %lu (%u modified)\r" ! 359: ,(offset/U_LEN)+1,length/U_LEN,mod); ! 360: if(lockuser(stream,offset)) { ! 361: printf("Error locking offset %lu\n",offset); ! 362: continue; ! 363: } ! 364: if(!chkuser(stream,offset)) { ! 365: unlock(fileno(stream),offset,U_LEN); ! 366: continue; ! 367: } ! 368: fseek(stream,offset+U_LEVEL,SEEK_SET); ! 369: fread(str,2,1,stream); ! 370: str[2]=0; ! 371: truncsp(str); ! 372: if(atoi(str)==j) { /* no change */ ! 373: unlock(fileno(stream),offset,U_LEN); ! 374: continue; ! 375: } ! 376: sprintf(str,"%02u",j); ! 377: fseek(stream,offset+U_LEVEL,SEEK_SET); ! 378: fwrite(str,2,1,stream); 1.1 root 379: unlock(fileno(stream),offset,U_LEN); 1.1.1.2 ! root 380: mod++; ! 381: } ! 382: fclose(stream); ! 383: printf("\n"); ! 384: break; ! 385: default: ! 386: printf(usage); ! 387: exit(1); ! 388: } ! 389: else { ! 390: strcpy(dir,argv[i]); ! 391: backslash(dir); ! 392: } ! 393: } ! 394: return(0); 1.1 root 395: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.