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

1.1       root        1: /* MLABELS.C */
                      2: 
                      3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
                      4: 
                      5: /* Make mailing labels from Synchronet BBS user database                                       */
                      6: /* Digital Dynamics - 03/16/93 v1.00                                                                           */
                      7: /* Digital Dynamics - 03/03/94 v2.00                                                                           */
                      8: /* Digital Dynamics - 04/13/95 v2.10                                                                           */
                      9: /* Digital Dynamics - 07/17/95 v2.20                                                                           */
                     10: 
                     11: /* For compilation under Borland/Turbo C(++)                                                           */
                     12: 
                     13: /* Set tabstops to 4 for viewing/printing                                                                      */
                     14: 
                     15: /* This program and source code are public domain. Modified versions may       */
                     16: /* note be distributed without consent from Digital Dynamics.                          */
                     17: 
                     18: #include <io.h>
                     19: #include <share.h>
                     20: #include <fcntl.h>
                     21: #include <errno.h>
                     22: #include <stdio.h>
                     23: #include <stdlib.h>
                     24: #include <sys\stat.h>
                     25: #include "sbbsdefs.h"           /* Synchronet typedefs and macros header */
                     26: 
                     27: #define DOUBLE_COLUMN  (1<<0)          /* Print double column labels */
                     28: #define ATTN_ALIAS             (1<<1)          /* Print ATTN: Alias/Real Name */
                     29: 
                     30: char *nulstr="";
                     31: int  min=0,max=99;
                     32: long reqflags[4]={0},reqrest=0,reqexempt=0;
                     33: 
                     34: char *usage=
                     35: "\nusage: mlabels <data\\user path> [[-require] [...]] [/options] <outfile>\n"
                     36: "\nwhere require is one of:\n"
                     37: "       L#                  set minimum level to # (default=0)\n"
                     38: "       M#                  set maximum level to # (default=99)\n"
                     39: "       F#<flags>           set required flags from flag set #\n"
                     40: "       E<flags>            set required exemptions\n"
                     41: "       R<flags>            set required restrictions\n"
                     42: "\nwhere options is one or more of:\n"
                     43: "       D                   double column labels\n"
                     44: "       A                   include ATTN: alias/name on label\n"
                     45: "\nexample:\n"
                     46: "\nMLABELS \\SBBS\\DATA\\USER -L50 /D PRN\n";
                     47: 
                     48: 
                     49: /****************************************************************************/
                     50: /* Converts an ASCII Hex string into an ulong                       */
                     51: /****************************************************************************/
                     52: ulong ahtoul(char *str)
                     53: {
                     54:        ulong l,val=0;
                     55: 
                     56: while((l=(*str++)|0x20)!=0x20)
                     57:        val=(l&0xf)+(l>>6&1)*9+val*16;
                     58: return(val);
                     59: }
                     60: 
                     61: /****************************************************************************/
                     62: /* Truncates white-space chars off end of 'str' and terminates at first tab */
                     63: /****************************************************************************/
                     64: void truncsp(char *str)
                     65: {
                     66:        char c;
                     67: 
                     68: str[strcspn(str,"\t")]=0;
                     69: c=strlen(str);
                     70: while(c && (uchar)str[c-1]<=SP) c--;
                     71: str[c]=0;
                     72: }
                     73: 
                     74: /****************************************************************************/
                     75: /* Returns bytes offset into user record for flag set # 'set'               */
                     76: /****************************************************************************/
                     77: long getflagoff(int set)
                     78: {
                     79: switch(set) {
                     80:        default:
                     81:                return(U_FLAGS1);
                     82:        case 2:
                     83:                return(U_FLAGS2);
                     84:        case 3:
                     85:                return(U_FLAGS3);
                     86:        case 4:
                     87:                return(U_FLAGS4); }
                     88: }
                     89: 
                     90: /****************************************************************************/
                     91: /* Checks a user record against the requirements set on the command line       */
                     92: /* Returns 1 if the user meets the requirements (or no requirements were       */
                     93: /* specified) or 0 if the user does not meet any of the requirements.          */
                     94: /****************************************************************************/
                     95: int chkuser(FILE *stream, long offset)
                     96: {
                     97:        char str[128];
                     98:        int i;
                     99: 
                    100: if(min || max!=99) {                   /* Check security level */
                    101:        fseek(stream,offset+U_LEVEL,SEEK_SET);
                    102:        fread(str,2,1,stream);
                    103:        str[2]=0;
                    104:        i=atoi(str);
                    105:        if(i<min || i>max)                      /* not within range */
                    106:                return(0); }                    /* so skip this user */
                    107: 
                    108: for(i=0;i<4;i++)
                    109:        if(reqflags[i]) {
                    110:                fseek(stream,offset+getflagoff(i+1),SEEK_SET);
                    111:                fread(str,8,1,stream);
                    112:                str[8]=0;
                    113:                truncsp(str);
                    114:                if((ahtoul(str)&reqflags[i])!=reqflags[i])
                    115:                        return(0); }    /* doesn't have 'em all */
                    116: 
                    117: if(reqrest) {
                    118:        fseek(stream,offset+U_REST,SEEK_SET);
                    119:        fread(str,8,1,stream);
                    120:        str[8]=0;
                    121:        truncsp(str);
                    122:        if((ahtoul(str)&reqrest)!=reqrest)
                    123:                return(0); }
                    124: 
                    125: if(reqexempt) {
                    126:        fseek(stream,offset+U_REST,SEEK_SET);
                    127:        fread(str,8,1,stream);
                    128:        str[8]=0;
                    129:        truncsp(str);
                    130:        if((ahtoul(str)&reqexempt)!=reqexempt)
                    131:         return(0); }
                    132: 
                    133: return(1);
                    134: }
                    135: 
                    136: /****************************************************************************/
                    137: /* Attempts to lock a user record, retries for up to 10 seconds                        */
                    138: /* Returns 0 on success, -1 on failure                                                                         */
                    139: /****************************************************************************/
                    140: int lockuser(FILE *stream, ulong offset)
                    141: {
                    142:        time_t start;
                    143: 
                    144: if(lock(fileno(stream),offset,U_LEN)==0)
                    145:        return(0);
                    146: start=time(NULL);
                    147: while(1) {
                    148:        if(lock(fileno(stream),offset,U_LEN)==0)
                    149:                return(0);
                    150:        if(time(NULL)-start>=10L)
                    151:                break; }
                    152: return(-1);
                    153: }
                    154: 
                    155: /***************/
                    156: /* Entry point *
                    157: /***************/
                    158: int main(int argc, char **argv)
                    159: {
                    160:        char    str[256],buf1[U_LEN],buf2[U_LEN],infile[128]="",outfile[128]=""
                    161:                        ,mode=0;        /* optional modes bits */
                    162:        int     i,j,k,file,printed=0;
                    163:        long    l,length,offset;
                    164:        FILE    *in,*out;
                    165: 
                    166: printf("\nSynchronet Mailing Labels v2.10\n");
                    167: for(i=1;i<argc;i++) {
                    168:        if(argv[i][0]=='-')
                    169:                switch(toupper(argv[i][1])) {
                    170:                        case 'L':                       /* Set minimum sec level */
                    171:                                min=atoi(argv[i]+2);
                    172:                                break;
                    173:                        case 'M':                       /* Set maximum sec level */
                    174:                                max=atoi(argv[i]+2);
                    175:                                break;
                    176:                        case 'F':                       /* Set required flags */
                    177:                                j=3;
                    178:                                k=1;
                    179:                                if(isdigit(argv[i][2]))
                    180:                                        k=argv[i][2]&0xf;
                    181:                                else
                    182:                                        j=2;
                    183:                                for(;argv[i][j];j++)
                    184:                     if(isalpha(argv[i][j]))
                    185:                                                reqflags[k-1]|=FLAG(toupper(argv[i][j]));
                    186:                                break;
                    187:                        case 'R':                       /* Set required restrictions */
                    188:                                for(j=2;argv[i][j];j++)
                    189:                     if(isalpha(argv[i][j]))
                    190:                                                reqrest|=FLAG(toupper(argv[i][j]));
                    191:                                break;
                    192:                        case 'E':                       /* Set required exemptions */
                    193:                                for(j=2;argv[i][j];j++)
                    194:                     if(isalpha(argv[i][j]))
                    195:                                                reqexempt|=FLAG(toupper(argv[i][j]));
                    196:                 break;
                    197:                        default:                                                /* Unrecognized include */
                    198:                                printf(usage);
                    199:                 exit(1); }
                    200: 
                    201:        else if(argv[i][0]=='/') {
                    202:                k=strlen(argv[i]);
                    203:                for(j=1;j<k;j++)
                    204:                        switch(toupper(argv[i][j])) {
                    205:                                case 'D':   /* Double column labels */
                    206:                                        mode|=DOUBLE_COLUMN;
                    207:                                        break;
                    208:                                case 'A':   /* Attention Alias/Real Name */
                    209:                                        mode|=ATTN_ALIAS;
                    210:                                        break;
                    211:                                default:
                    212:                                        printf("\nUnknown option\n");
                    213:                                case '?':
                    214:                                        printf(usage);
                    215:                                        exit(1); } }
                    216:        else if(infile[0])                              /* in filename already given */
                    217:                strcpy(outfile,argv[i]);
                    218:        else
                    219:                strcpy(infile,argv[i]); }
                    220: 
                    221: if(!infile[0] || !outfile[0]) {
                    222:        printf("\nFilename not specified\n");
                    223:        printf(usage);
                    224:        exit(1); }
                    225: 
                    226: if(infile[strlen(infile)-1]!='\\' && infile[strlen(infile)-1]!=':')
                    227:        strcat(infile,"\\");
                    228: strcat(infile,"USER.DAT");
                    229: if((file=sopen(infile,O_RDONLY|O_BINARY,SH_DENYNO))==-1) {
                    230:        printf("\nError opening %s\n",infile);
                    231:        exit(1); }
                    232: if((in=fdopen(file,"rb"))==NULL) {
                    233:        printf("\nError opening %s\n",infile);
                    234:        exit(1); }
                    235: setvbuf(in,NULL,_IOFBF,2048);
                    236: length=filelength(file);
                    237: 
                    238: if((file=open(outfile,O_WRONLY|O_TRUNC|O_CREAT|O_BINARY
                    239:        ,S_IWRITE|S_IREAD))==-1) {
                    240:        printf("\nError opening/creating %s\n",outfile);
                    241:        exit(1); }
                    242: if((out=fdopen(file,"wb"))==NULL) {
                    243:        printf("\nError opening %s\n",outfile);
                    244:        exit(1); }
                    245: setvbuf(out,NULL,_IOFBF,2048);
                    246: 
                    247: printf("\n");
                    248: for(offset=0;offset<length;offset+=U_LEN) {
                    249:        printf("%lu of %lu (%u labels)\r"
                    250:                ,(offset/U_LEN)+1,length/U_LEN,printed);
                    251:        if(lockuser(in,offset)) {
                    252:                printf("Error locking offset %lu\n",offset);
                    253:                continue; }
                    254: 
                    255:        if(!chkuser(in,offset)) {
                    256:                unlock(fileno(in),offset,U_LEN);
                    257:                continue; }
                    258: 
                    259:        fseek(in,offset,SEEK_SET);
                    260:        if(!fread(buf1,U_LEN,1,in)) {
                    261:                printf("Couldn't read %lu bytes at %lu\n",U_LEN,offset);
                    262:                break; }
                    263:        unlock(fileno(in),offset,U_LEN);
                    264:        for(i=0;i<U_LEN;i++) {                          /* Convert ETX (3) to NULL (0) */
                    265:                if(buf1[i]==ETX)
                    266:                        buf1[i]=NULL; }
                    267: 
                    268:        buf1[U_MISC+8]=0;
                    269:        l=ahtoul(buf1+U_MISC);
                    270:        if(l&(DELETED|INACTIVE))                         /* skip if deleted or inactive */
                    271:                continue;
                    272: 
                    273:        while(mode&DOUBLE_COLUMN) {              /* double wide - right column */
                    274:                offset+=U_LEN;
                    275:                printf("%lu of %lu (%u labels)\r"
                    276:                        ,(offset/U_LEN)+1,length/U_LEN,printed);
                    277:                if(lockuser(in,offset)) {
                    278:                        printf("Error locking offset %lu\n",offset);
                    279:                        continue; }
                    280:                fseek(in,offset,SEEK_SET);
                    281:                if(!fread(buf2,U_LEN,1,in)) {
                    282:                        mode&=~DOUBLE_COLUMN;
                    283:                        unlock(fileno(in),offset,U_LEN); }
                    284:                else {
                    285:                        if(!chkuser(in,offset)) {
                    286:                                unlock(fileno(in),offset,U_LEN);
                    287:                                continue; }
                    288:                        unlock(fileno(in),offset,U_LEN);
                    289:                        for(i=0;i<U_LEN;i++) {          /* Convert ETX (3) to NULL (0) */
                    290:                                if(buf2[i]==ETX)
                    291:                                        buf2[i]=NULL; }
                    292:                        buf2[U_MISC+8]=0;
                    293:                        l=ahtoul(buf2+U_MISC);
                    294:                        if(l&(DELETED|INACTIVE))        /* skip if deleted or inactive */
                    295:                                continue;
                    296:                        else
                    297:                                break; } }
                    298: 
                    299:        if(mode&DOUBLE_COLUMN) {                        /* print two columns */
                    300:                fprintf(out,"    %-*.*s%*s%.*s\r\n"
                    301:                        ,LEN_NAME,LEN_NAME
                    302:                        ,buf1+U_NAME
                    303:                        ,41-LEN_NAME,nulstr
                    304:                        ,LEN_NAME
                    305:                        ,buf2+U_NAME);
                    306: 
                    307:                fprintf(out,"    %-*.*s%*s%.*s\r\n"
                    308:                        ,LEN_ADDRESS,LEN_ADDRESS
                    309:                        ,buf1+U_ADDRESS
                    310:                        ,41-LEN_ADDRESS,nulstr
                    311:                        ,LEN_ADDRESS
                    312:                        ,buf2+U_ADDRESS);
                    313: 
                    314:                sprintf(str,"%.*s %.*s"
                    315:                        ,LEN_LOCATION,buf1+U_LOCATION
                    316:                        ,LEN_ZIPCODE,buf1+U_ZIPCODE);
                    317: 
                    318:                fprintf(out,"    %-41s%.*s %.*s\r\n"
                    319:                        ,str
                    320:                        ,LEN_LOCATION,buf2+U_LOCATION
                    321:                        ,LEN_ZIPCODE,buf2+U_ZIPCODE);
                    322: 
                    323:                sprintf(str,"ATTN: %.*s",LEN_ALIAS,buf1+U_ALIAS);
                    324: 
                    325:         if(mode&ATTN_ALIAS)
                    326:                        fprintf(out,"    %-41sATTN: %.*s\r\n\r\n\r\n"
                    327:                 ,str,LEN_ALIAS,buf2+U_ALIAS);
                    328:         else
                    329:                        fprintf(out,"\r\n\r\n\r\n");
                    330: 
                    331:                printed+=2; }
                    332: 
                    333:        else {                                                          /* single column labels */
                    334:                fprintf(out,"    %.*s\r\n"
                    335:                        ,LEN_NAME
                    336:                        ,buf1+U_NAME);
                    337: 
                    338:                fprintf(out,"    %.*s\r\n"
                    339:                        ,LEN_ADDRESS
                    340:                        ,buf1+U_ADDRESS);
                    341: 
                    342:                fprintf(out,"    %.*s %.*s\r\n"
                    343:                        ,LEN_LOCATION
                    344:                        ,buf1+U_LOCATION
                    345:                        ,LEN_ZIPCODE
                    346:                        ,buf1+U_ZIPCODE);
                    347: 
                    348:                if(mode&ATTN_ALIAS)
                    349:                        fprintf(out,"    ATTN: %.*s\r\n\r\n\r\n"
                    350:                                ,LEN_ALIAS,buf1+U_ALIAS);
                    351:         else
                    352:                        fprintf(out,"\r\n\r\n\r\n");
                    353: 
                    354:                printed++; } }
                    355: printf("\nDone.\n");
                    356: fclose(in);
                    357: fclose(out);
                    358: return(0);
                    359: }
                    360: 
                    361: /* end of mlabels.c */

unix.superglobalmegacorp.com

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