Annotation of sbbs/sbbs2/allusers/allusers.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.