FreeBSD/usr.sbin/ctm/ctm_rmail/ctm_rmail.c
/*
 * Decode the data between BEGIN and END, and stash it in the staging area.
 * Multiple pieces can be present in a single file, bracketed by BEGIN/END.
 * If we have all pieces of a delta, combine them.  Returns 0 on success,
 * and 1 for any sort of failure.
 */
Decode the data between BEGIN and END, and stash it in the staging area.
Multiple pieces can be present in a single file, bracketed by BEGIN/END.
If we have all pieces of a delta, combine them.  Returns 0 on success,
and 1 for any sort of failure.
Decode the data between BEGIN and END and stash it in the staging area . Multiple pieces can be present in a single file bracketed by BEGIN / END . If we have all pieces of a delta combine them . Returns 0 on success and 1 for any sort of failure .
int
read_piece(char *input_file)
    {
    int status = 0;
    FILE *ifp, *ofp = 0;
    int decoding = 0;
    int got_one = 0;
    int line_no = 0;
    int i, n;
    int pce, npieces;
    unsigned claimed_cksum;
    unsigned short cksum = 0;
    char out_buf[200];
    char line[200];
    char delta[30];
    char pname[PATH_MAX];
    char tname[PATH_MAX];
    char junk[2];
    ifp = stdin;
    if (input_file != NULL && (ifp = fopen(input_file, "r")) == NULL)
	{
	err("cannot open '%s' for reading", input_file);
	return 1;
	}
    while (fgets(line, sizeof(line), ifp) != NULL)
	{
	line_no++;
	i = strlen(line) - 1;
	while (i > 0 && isspace(line[i]))
		line[i--] = '\0';
	if (!decoding)
	    {
	    char *s;
	    int fd = -1;
	    if (sscanf(line, "CTM_MAIL BEGIN %29s %d %d %c",
		    delta, &pce, &npieces, junk) != 3)
		continue;
	    while ((s = strchr(delta, '/')) != NULL)
		*s = '_';
	    got_one++;
	    strcpy(tname, piece_dir);
	    strcat(tname, "/p.XXXXXXXXXX");
	    if ((fd = mkstemp(tname)) == -1 ||
		(ofp = fdopen(fd, "w")) == NULL)
		{
		if (fd != -1) {
		    err("cannot open '%s' for writing", tname);
		    close(fd);
		    }
		else
		    err("*mkstemp: '%s'", tname);
		status++;
		continue;
		}
	    cksum = 0xffff;
	    decoding++;
	    continue;
	    }
	if (sscanf(line, "CTM_MAIL END %d %c", &claimed_cksum, junk) == 1)
	    {
	    int e;
	    decoding = 0;
	    fflush(ofp);
	    e = ferror(ofp);
	    fclose(ofp);
	    if (e)
		err("error writing %s", tname);
	    if (cksum != claimed_cksum)
		err("checksum: read %d, calculated %d", claimed_cksum, cksum);
	    if (e || cksum != claimed_cksum)
		{
		err("%s %d/%d discarded", delta, pce, npieces);
		unlink(tname);
		status++;
		continue;
		}
	    mk_piece_name(pname, delta, pce, npieces);
	    if (rename(tname, pname) < 0)
		{
		err("*rename: '%s' to '%s'", tname, pname);
		err("%s %d/%d lost!", delta, pce, npieces);
		unlink(tname);
		status++;
		continue;
		}
	    err("%s %d/%d stored", delta, pce, npieces);
	    if (!combine_if_complete(delta, pce, npieces))
		status++;
	    continue;
	    }
	n = decode_line(line, out_buf);
	if (n <= 0)
	    {
	    err("line %d: illegal character: '%c'", line_no, line[-n]);
	    err("%s %d/%d discarded", delta, pce, npieces);
	    fclose(ofp);
	    unlink(tname);
	    status++;
	    decoding = 0;
	    continue;
	    }
	for (i = 0; i < n; i++)
	    add_ck(cksum, out_buf[i]);
	fwrite(out_buf, sizeof(char), n, ofp);
	}
    if (decoding)
	{
	err("truncated file");
	err("%s %d/%d discarded", delta, pce, npieces);
	fclose(ofp);
	unlink(tname);
	status++;
	}
    if (ferror(ifp))
	{
	err("error reading %s", input_file == NULL ? "stdin" : input_file);
	status++;
	}
    if (input_file != NULL)
	fclose(ifp);
    if (!got_one)
	{
	err("message contains no delta");
	status++;
	}
    return (status != 0);
    }
int read_piece ( char * input_file ) { int status = 0 ; FILE * ifp , * ofp = 0 ; int decoding = 0 ; int got_one = 0 ; int line_no = 0 ; int i , n ; int pce , npieces ; unsigned claimed_cksum ; unsigned short cksum = 0 ; char out_buf [ 200 ] ; char line [ 200 ] ; char delta [ 30 ] ; char pname [ PATH_MAX ] ; char tname [ PATH_MAX ] ; char junk [ 2 ] ; ifp = stdin ; if ( input_file != NULL && ( ifp = fopen ( input_file , " " ) ) == NULL ) { err ( " " , input_file ) ; return 1 ; } while ( fgets ( line , sizeof ( line ) , ifp ) != NULL ) { line_no ++ ; i = strlen ( line ) - 1 ; while ( i > 0 && isspace ( line [ i ] ) ) line [ i -- ] = ' \0 ' ; if ( ! decoding ) { char * s ; int fd = -1 ; if ( sscanf ( line , " " , delta , & pce , & npieces , junk ) != 3 ) continue ; while ( ( s = strchr ( delta , ' ' ) ) != NULL ) * s = ' ' ; got_one ++ ; strcpy ( tname , piece_dir ) ; strcat ( tname , " " ) ; if ( ( fd = mkstemp ( tname ) ) == -1 || ( ofp = fdopen ( fd , " " ) ) == NULL ) { if ( fd != -1 ) { err ( " " , tname ) ; close ( fd ) ; } else err ( " " , tname ) ; status ++ ; continue ; } cksum = 0xffff ; decoding ++ ; continue ; } if ( sscanf ( line , " " , & claimed_cksum , junk ) == 1 ) { int e ; decoding = 0 ; fflush ( ofp ) ; e = ferror ( ofp ) ; fclose ( ofp ) ; if ( e ) err ( " " , tname ) ; if ( cksum != claimed_cksum ) err ( " " , claimed_cksum , cksum ) ; if ( e || cksum != claimed_cksum ) { err ( " " , delta , pce , npieces ) ; unlink ( tname ) ; status ++ ; continue ; } mk_piece_name ( pname , delta , pce , npieces ) ; if ( rename ( tname , pname ) < 0 ) { err ( " " , tname , pname ) ; err ( " " , delta , pce , npieces ) ; unlink ( tname ) ; status ++ ; continue ; } err ( " " , delta , pce , npieces ) ; if ( ! combine_if_complete ( delta , pce , npieces ) ) status ++ ; continue ; } n = decode_line ( line , out_buf ) ; if ( n <= 0 ) { err ( " " , line_no , line [ - n ] ) ; err ( " " , delta , pce , npieces ) ; fclose ( ofp ) ; unlink ( tname ) ; status ++ ; decoding = 0 ; continue ; } for ( i = 0 ; i < n ; i ++ ) add_ck ( cksum , out_buf [ i ] ) ; fwrite ( out_buf , sizeof ( char ) , n , ofp ) ; } if ( decoding ) { err ( " " ) ; err ( " " , delta , pce , npieces ) ; fclose ( ofp ) ; unlink ( tname ) ; status ++ ; } if ( ferror ( ifp ) ) { err ( " " , input_file == NULL ? " " : input_file ) ; status ++ ; } if ( input_file != NULL ) fclose ( ifp ) ; if ( ! got_one ) { err ( " " ) ; status ++ ; } return ( status != 0 ) ; }
Decode the data between BEGIN and END, and stash it in the staging area.
Decode the data between BEGIN and END and stash it in the staging area .
/*
	 * Remove all trailing white space.
	 */ /*
	 * Look for the beginning of an encoded piece.
	 */ /*
	 * We are decoding.  Stop if we see the end flag.
	 */ /*
	 * Must be a line of encoded data.  Decode it, sum it, and save it.
	 */