#ifdef ournix #include "ournix.h" #endif char sccsID[] = "@(#) mailsplit.c V1.3 Copyright Julian H. Stacey, Munich, 10th April 1991 .\n"; /* Separate manual exists,program & source can be tabbed */ #include #include #include #include typedef char FLAG; #define LINE_LN 30000 char *cut_str = "From "; /* what will cause a new file (when found at the beginning of a file) */ FILE *fp_out; char **ARGV; #undef USE_STRCHR #ifdef vax /* { */ #define USE_STRCHR #endif /* } */ #ifdef MSDOS /* { */ #define USE_STRCHR #endif /* } */ #ifdef USE_STRCHR /* { */ extern char *strchr(); #define index(s,c) strchr(s,c) #define rindex(s,c) strrchr(s,c) #else /* } { */ extern char *index(); extern char *rindex(); #endif /* } */ char *in_name; char out_name[LINE_LN]; int exit_count = 0; int rslt; long line_no ; FLAG over_write_f = 0; FLAG verbose_f = 0; FLAG pipe_f = 0; int file_number ; extern long getpid(); #define strnequ(s1,s2,ln) (0==strncmp(s1,s2,ln)) #define strequ(s1,s2) (0==strcmp(s1,s2)) int get_line(fp,where,max_length) FILE *fp; register char *where; register int max_length; /* max. size of array including null */ { register int ch; char *orig; orig = where; max_length--; /* allow for \n */ while (((ch = getc(fp)) != EOF) && ((char)ch != '\n')) { if (--max_length <= 0 ) { fprintf(stderr, "%s: Warning in %s\t - Line %ld longer than %d.\n", *ARGV,in_name,line_no, LINE_LN ); exit_count++; /* Return a line terminated with a '\0', with no preceeding '\n' (a very long input line gets split into a number of shorter lines, that each have a \n (appended elswhere in this program) */ /* un-necessary: *where = '\0'; */ ch = '\n' + 1 ; /* ie not '\n' */ break; } *where++ = (char)ch; } if ((char)ch == '\n') { *where++ = '\n'; line_no++ ; } *where = '\0'; return(where - orig); } syntax(ex) int ex; { fprintf(stdout, "Syntax: %s [-c cut_str] [-r] [-o] [-v] [-?] [-- or files]\n", *ARGV); exit(ex); } mk_file() { struct stat stat_buf; sprintf(out_name,"ms_%ld_%d",getpid(),file_number++); if (verbose_f) printf("%s%s%sWriting %s\n", (pipe_f) ? "\0" : "Reading ", (pipe_f) ? "\0" : in_name, (pipe_f) ? "\0" : ", ", out_name); if (!over_write_f && ( (rslt = stat(out_name,&stat_buf)) == 0)) { /* stat has detected a pre existing target file */ fprintf(stderr, "%s: Error: Pre existant %s.\n", *ARGV,out_name); exit(++exit_count); } if ( ( fp_out = fopen(out_name,"w")) == (FILE *)0 ) { fprintf(stderr, "%s: Error: %s\t- Cannot create to write.\n", *ARGV,out_name); exit(++exit_count); } } main(argc,argv) int argc; char **argv; { struct stat stat_buf; char line_in[LINE_LN]; char *p; FLAG remove_f = 0; int len ; FILE *fp_in; FLAG extant_f ; /* 1 if an output file is open */ len = strlen(cut_str) ; ARGV = argv; #ifdef VSL /* { */ #include "../../include/vsl.h" #endif /* } */ for (argc--,argv++; argc > 0; argv++ ) { if(**argv != '-') break /* no more parameters */; argc--; switch(*++*argv) { /* option detect */ case '-': /* stdin mode */ pipe_f = 1; break; case 'r': /* zap input file mode */ remove_f = 1; break; case 'c': /* cut string */ if (!--argc) syntax(1); cut_str = *++argv; break; case 'v': /* verbose mode */ verbose_f = 1; break; case 'o': /* overwrite ouput files if they exist */ over_write_f = 1; break; case '?': syntax(0) ; break ; default: fprintf(stderr, "%s: `%c' - Unavailable option.\n", *ARGV,**argv); syntax(1); break ; } } /* finished taking parameters */ if (remove_f && pipe_f ) syntax(1); if (pipe_f && argc) /* pipe input or file input, not both */ syntax(1); if (pipe_f) argc = 1; while (argc--) { line_no = 1L ; if (!pipe_f) { in_name = *argv++; if ( ( fp_in = fopen(in_name,"r")) == (FILE *)0 ) { fprintf(stderr, "%s: Error: %s\t- Cannot read.\n", *ARGV,out_name); ++exit_count; continue; } } else { in_name = "" ; fp_in = stdin ; } extant_f = 0 ; while ( get_line(fp_in,line_in,LINE_LN) ) { if (strnequ(line_in,cut_str,len)) { if (extant_f) (void) fclose(fp_out); extant_f=0 ; } if (!extant_f) { mk_file() ; extant_f = 1 ; } fprintf(fp_out,"%s",line_in); } if ( fp_out != (FILE *)0) /* If we've read a zero size file, there's no output, so don't close, otherwise close */ (void) fclose(fp_out); (void) fclose(fp_in); if (remove_f) (void) unlink(in_name); } exit(exit_count); }