|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.