home *** CD-ROM | disk | FTP | other *** search
- /*
- File: Join.c
-
- Contains: Join multipart postings into one
- Looks for (in order of preference)
- a) comp.binaries.mac format
- b) files generated by Unix "split"
-
- Written by: Sak Wathanasin
- 178 Wainbody Ave South
- Coventry CV3 6BX
- UK
- Phone: +44 203 419996
- E-mail: sw@network-analysis-ltd.co.uk
-
- Copyright: ⌐ 1990 by Network Analysis Ltd, all rights reserved.
-
- Change History:
-
- 24/7/92 sw "-" as file spec for stdin wasn't picked up
- 2/1/92 sw Change CopyRest to allow for more than 1 "---" in the mailnote.
- 3/12/90 sw Should look for "--- end" instead of just "---" to detect end
- of a part.
- 25/9/90 sw Handle btoa'ed files
- 24/9/90 sw Take care of blank line between (This... and the hex
- 11/8/90 sw Base version
-
- To Do:
- */
-
- #include <Types.h>
- #include <StdDef.h>
- #include <stdio.h>
- #include <Files.h>
- #include <errno.h>
- #include <StdLib.h>
- #include <String.h>
- #include <CursorCtl.h>
- #ifndef NIL
- #define NIL (0L)
- #endif
-
- #ifndef EOF
- #define EOF (-1L)
- #endif
-
- Boolean cbm = true; /* true if file is in comp.binaries.mac format */
- Boolean uu = false; /* true if file is in uuencoded format */
- int part, totalParts; /* current part no, and total no of parts */
- int binlen = 65; /* length of a line of hexed binary */
-
- /* Prototypes */
- void JoinFirst (char *fileName);
- void Join (char *fileName);
- void CopyRest (FILE *fp);
- void SkipHdr (FILE *infp);
-
- main(int argc, char *argv[])
- {
- char **filelist; /* list of files to process */
- int fileCount = 0; /* no of files to process */
-
- #ifdef MPW
- InitCursorCtl(nil);
- #endif MPW
- argc--; argv++;
- if ((filelist = (char **)calloc((size_t)argc, sizeof(Ptr))) == NULL) {
- fprintf(stderr, "### Not enough memory\n");
- exit(-1);
- }
- while (argc) {
- if (argv[0][0] == '-') {
- switch (argv[0][1]) {
- case '\0':
- filelist[fileCount++] = "-";
- break;
- case 'c':
- cbm = true;
- break;
- case 'u':
- cbm = false; /* in std Unix split format */
- break;
- default:
- fprintf(stderr, "### Usage: join [-c] [-u] [files|ñ]\n");
- exit(-1);
- }
- }
- else
- filelist[fileCount++] = argv[0];
- argc--; argv++;
- }
- /* at this point all files to process are in filelist */
- part = 1;
- totalParts = 0;
-
- JoinFirst(filelist[0]);
- for (argc = 1; argc < fileCount; argc++) {
- Join(filelist[argc]);
- }
- if (cbm && (part <= totalParts)) {
- fprintf(stderr, "### Parts %d to %d missing\n", part, totalParts);
- exit(-1);
- }
- exit(0);
- }
-
- void JoinFirst (char *fileName)
- {
- char buffer[BUFSIZ];
- char *cp, *s;
- FILE *infp;
- int curPart, noParts;
-
- if (strcmp(fileName, "-") == 0)
- infp = stdin;
- else
- infp = fopen(fileName, "r");
- if (!infp) {
- fprintf(stderr, "### Could not open file %s\n", fileName);
- exit(-1);
- }
-
- /* skip over news header lines etc. */
- SkipHdr(infp);
-
- /* now scan to see if file is of c.b.m format */
- while (cp = fgets(buffer, sizeof(buffer), infp)) {
- if (buffer[0] == '[') break;
- if (strncmp(buffer, "(This file must", 15) == 0) {
- fputs(buffer, stdout);
- /* Some binhex files have a blank line between the (This file...
- line and the start of the hex
- */
- cp = fgets(buffer, sizeof(buffer), infp);
- if (cp && buffer[0] == ':')
- fputs(buffer, stdout);
- cbm = false; /* not in c.b.m format */
- uu = false;
- break;
- }
- else if (strncmp(buffer, "begin ", 6) == 0) { /* uuencoded file */
- fputs(buffer, stdout);
- cbm = false;
- uu = true;
- break;
- }
- else if (strncmp(buffer, "xbtoa Begin", 11) == 0) { /* btoa file */
- fputs(buffer, stdout);
- cbm = false;
- uu = false;
- break;
- }
- else
- fputs(buffer, stderr);
- }
-
- /* if we have a cbm file, get the total of parts */
- if (cbm) {
- /* look for "part n of m" */
- s = strstr(buffer, "part");
- (void) sscanf(s, "part %d of %d]", &curPart, &noParts);
- fputs(buffer, stderr);
- if (part != curPart) {
- fprintf(stderr, "### Expecting part %d; got part %d\n", part, curPart);
- exit(-1);
- }
- if (part == 1)
- totalParts = noParts;
- }
- CopyRest(infp);
- fclose(infp);
- fflush(stdout);
- fflush(stderr);
- }
-
- /* process all the other files: they have no headers */
- void Join (char *fileName)
- {
- char buffer[BUFSIZ];
- char *cp;
- FILE *infp;
-
- infp = fopen(fileName, "r");
- if (!infp) {
- fprintf(stderr, "### Could not open file %s\n", fileName);
- exit(-1);
- }
-
- /* skip over news header lines etc. */
- while (cp = fgets(buffer, sizeof(buffer), infp)) {
- /* skip pass next blank line */
- if (strlen(buffer) == 1) {
- break;
- }
- }
- CopyRest(infp);
- fclose(infp);
- fflush(stdout);
- fflush(stderr);
- }
-
- /* copy the rest of the file to stdout;
- NB there may be more than 1 part contained in a single file;
- users may either select all the msgs or combine all the parts together first.
- */
- void CopyRest(FILE *infp)
- {
- char *cp;
- char buffer[BUFSIZ];
- int len;
-
-
- while (cp = fgets(buffer, sizeof(buffer), infp)) {
- /* if we have a cbm file, we skip the little header */
- if (cbm) {
- /* if this is the 1st time through, skip up to a line starting (This... */
- if (part == 1) {
- while(cp && strncmp(buffer, "(This file must", 15) != 0) {
- SpinCursor(-1);
- fputs(buffer, stderr);
- cp = fgets(buffer, sizeof(buffer), infp);
- }
- /* now buffer contains the line starting (This file...
- We need to copy all lines up to one starting with ":"
- */
-
- while (cp && buffer[0] != ':') {
- fputs(buffer, stdout);
- cp = fgets(buffer, sizeof(buffer), infp);
- }
- }
- else {
- /* otherwise skip up to a line starting --- */
- while (cp && strncmp(buffer, "---", 3) != 0) {
- SpinCursor(-1);
- if (buffer[0] == '[')
- fputs(buffer, stderr);
- cp = fgets(buffer, sizeof(buffer), infp);
- }
- /* skip the "---" line */
- cp = fgets(buffer, sizeof(buffer), infp);
- }
- }
-
- /* now copy all the binary to std output
- The following things terminate a "part"
- 1) a blank line, not followed by "end"
- 2) a line beginning "--- end"
- 3) a line beginning "Path"
- 4) a line beginning "From"
- 5) eof
- */
- while (cp &&
- (len = strlen(buffer)) != 1 &&
- strncmp(buffer, "--- end", 7) != 0 &&
- strncmp(buffer, "Path", 4) != 0 &&
- strncmp(buffer, "From", 4) != 0) {
- SpinCursor(-1);
- fputs(buffer, stdout);
- cp = fgets(buffer, sizeof(buffer), infp);
- }
-
- /* work out how we got out of the loop */
- if (len == 1 && uu) { /* a blank line */
- /* check if the next line is "end" (uuencoded file) */
- cp = fgets(buffer, sizeof(buffer), infp);
- if (cp && strncmp(buffer, "end", 3) == 0) {
- fputc('\n', stdout);
- fputs(buffer, stdout);
- cp = fgets(buffer, sizeof(buffer), infp);
- }
- else
- SkipHdr(infp);
- }
- else if (cp && strncmp(buffer, "--- end of part", 15) == 0)
- part++;
- /* any other terminator means we are at the start of another part */
- else {
- part++;
- if (cp != NULL)
- /* skip over news header lines etc. */
- SkipHdr(infp);
- }
- }
- }
-
- /* Function to skip mail/news headers
- */
-
- void SkipHdr (FILE *infp)
- {
- char *cp;
- char buffer[BUFSIZ];
-
- while (cp = fgets(buffer, sizeof(buffer), infp)) {
- /* skip pass next blank line */
- if (strlen(buffer) == 1) {
- break;
- }
- }
-
- }
-