77#include "cache.h"
88#include "builtin.h"
99#include "string-list.h"
10+ #include "strbuf.h"
1011
1112static const char git_mailsplit_usage [] =
1213"git mailsplit [-d<prec>] [-f<n>] [-b] -o<directory> [<mbox>|<Maildir>...]" ;
@@ -42,26 +43,8 @@ static int is_from_line(const char *line, int len)
4243 return 1 ;
4344}
4445
45- /* Could be as small as 64, enough to hold a Unix "From " line. */
46- static char buf [4096 ];
47-
48- /* We cannot use fgets() because our lines can contain NULs */
49- int read_line_with_nul (char * buf , int size , FILE * in )
50- {
51- int len = 0 , c ;
52-
53- for (;;) {
54- c = getc (in );
55- if (c == EOF )
56- break ;
57- buf [len ++ ] = c ;
58- if (c == '\n' || len + 1 >= size )
59- break ;
60- }
61- buf [len ] = '\0' ;
62-
63- return len ;
64- }
46+ static struct strbuf buf = STRBUF_INIT ;
47+ static int keep_cr ;
6548
6649/* Called with the first line (potentially partial)
6750 * already in buf[] -- normally that should begin with
@@ -71,10 +54,9 @@ int read_line_with_nul(char *buf, int size, FILE *in)
7154static int split_one (FILE * mbox , const char * name , int allow_bare )
7255{
7356 FILE * output = NULL ;
74- int len = strlen (buf );
7557 int fd ;
7658 int status = 0 ;
77- int is_bare = !is_from_line (buf , len );
59+ int is_bare = !is_from_line (buf . buf , buf . len );
7860
7961 if (is_bare && !allow_bare )
8062 goto corrupt ;
@@ -88,20 +70,23 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
8870 * "From " and having something that looks like a date format.
8971 */
9072 for (;;) {
91- int is_partial = len && buf [len - 1 ] != '\n' ;
73+ if (!keep_cr && buf .len > 1 && buf .buf [buf .len - 1 ] == '\n' &&
74+ buf .buf [buf .len - 2 ] == '\r' ) {
75+ strbuf_setlen (& buf , buf .len - 2 );
76+ strbuf_addch (& buf , '\n' );
77+ }
9278
93- if (fwrite (buf , 1 , len , output ) != len )
79+ if (fwrite (buf . buf , 1 , buf . len , output ) != buf . len )
9480 die_errno ("cannot write output" );
9581
96- len = read_line_with_nul (buf , sizeof (buf ), mbox );
97- if (len == 0 ) {
82+ if (strbuf_getwholeline (& buf , mbox , '\n' )) {
9883 if (feof (mbox )) {
9984 status = 1 ;
10085 break ;
10186 }
10287 die_errno ("cannot read mbox" );
10388 }
104- if (!is_partial && ! is_bare && is_from_line (buf , len ))
89+ if (!is_bare && is_from_line (buf . buf , buf . len ))
10590 break ; /* done with one message */
10691 }
10792 fclose (output );
@@ -166,7 +151,7 @@ static int split_maildir(const char *maildir, const char *dir,
166151 goto out ;
167152 }
168153
169- if (fgets ( buf , sizeof ( buf ), f ) == NULL ) {
154+ if (strbuf_getwholeline ( & buf , f , '\n' ) ) {
170155 error ("cannot read mail %s (%s)" , file , strerror (errno ));
171156 goto out ;
172157 }
@@ -203,7 +188,7 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,
203188 } while (isspace (peek ));
204189 ungetc (peek , f );
205190
206- if (fgets ( buf , sizeof ( buf ), f ) == NULL ) {
191+ if (strbuf_getwholeline ( & buf , f , '\n' ) ) {
207192 /* empty stdin is OK */
208193 if (f != stdin ) {
209194 error ("cannot read mbox %s" , file );
@@ -248,6 +233,8 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix)
248233 nr = strtol (arg + 2 , NULL , 10 );
249234 } else if ( arg [1 ] == 'b' && !arg [2 ] ) {
250235 allow_bare = 1 ;
236+ } else if (!strcmp (arg , "--keep-cr" )) {
237+ keep_cr = 1 ;
251238 } else if ( arg [1 ] == 'o' && arg [2 ] ) {
252239 dir = arg + 2 ;
253240 } else if ( arg [1 ] == '-' && !arg [2 ] ) {
0 commit comments