2323#define xstr (s ) #s
2424#define str (s ) xstr(s)
2525#define MIN (a , b ) ((a) < (b) ? (a) : (b))
26+ #define CPIO_HDR_LEN 110
27+ #define padlen (_off , _align ) (((_align) - ((_off) & ((_align) - 1))) % (_align))
2628
29+ static char padding [512 ];
2730static unsigned int offset ;
2831static unsigned int ino = 721 ;
2932static time_t default_mtime ;
3033static bool do_file_mtime ;
3134static bool do_csum = false;
35+ static int outfd = STDOUT_FILENO ;
3236
3337struct file_handler {
3438 const char * type ;
3539 int (* handler )(const char * line );
3640};
3741
38- static void push_string (const char * name )
42+ static int push_string (const char * name )
3943{
4044 unsigned int name_len = strlen (name ) + 1 ;
45+ ssize_t len ;
46+
47+ len = write (outfd , name , name_len );
48+ if (len != name_len )
49+ return -1 ;
4150
42- fputs (name , stdout );
43- putchar (0 );
4451 offset += name_len ;
52+ return 0 ;
4553}
4654
47- static void push_pad ( void )
55+ static int push_pad ( size_t padlen )
4856{
49- while (offset & 3 ) {
50- putchar (0 );
51- offset ++ ;
52- }
57+ ssize_t len = 0 ;
58+
59+ if (!padlen )
60+ return 0 ;
61+
62+ if (padlen < sizeof (padding ))
63+ len = write (outfd , padding , padlen );
64+ if (len != padlen )
65+ return -1 ;
66+
67+ offset += padlen ;
68+ return 0 ;
5369}
5470
55- static void push_rest (const char * name )
71+ static int push_rest (const char * name )
5672{
5773 unsigned int name_len = strlen (name ) + 1 ;
58- unsigned int tmp_ofs ;
74+ ssize_t len ;
5975
60- fputs ( name , stdout );
61- putchar ( 0 );
62- offset += name_len ;
76+ len = write ( outfd , name , name_len );
77+ if ( len != name_len )
78+ return -1 ;
6379
64- tmp_ofs = name_len + 110 ;
65- while (tmp_ofs & 3 ) {
66- putchar (0 );
67- offset ++ ;
68- tmp_ofs ++ ;
69- }
70- }
80+ offset += name_len ;
7181
72- static void push_hdr (const char * s )
73- {
74- fputs (s , stdout );
75- offset += 110 ;
82+ return push_pad (padlen (name_len + CPIO_HDR_LEN , 4 ));
7683}
7784
78- static void cpio_trailer (void )
85+ static int cpio_trailer (void )
7986{
80- char s [256 ];
8187 const char name [] = "TRAILER!!!" ;
88+ int len ;
8289
83- sprintf ( s , "%s%08X%08X%08lX%08lX%08X%08lX"
90+ len = dprintf ( outfd , "%s%08X%08X%08lX%08lX%08X%08lX"
8491 "%08X%08X%08X%08X%08X%08X%08X" ,
8592 do_csum ? "070702" : "070701" , /* magic */
8693 0 , /* ino */
@@ -96,23 +103,24 @@ static void cpio_trailer(void)
96103 0 , /* rminor */
97104 (unsigned )strlen (name )+ 1 , /* namesize */
98105 0 ); /* chksum */
99- push_hdr (s );
100- push_rest (name );
106+ offset += len ;
101107
102- while (offset % 512 ) {
103- putchar (0 );
104- offset ++ ;
105- }
108+ if (len != CPIO_HDR_LEN ||
109+ push_rest (name ) < 0 ||
110+ push_pad (padlen (offset , 512 )) < 0 )
111+ return -1 ;
112+
113+ return 0 ;
106114}
107115
108116static int cpio_mkslink (const char * name , const char * target ,
109117 unsigned int mode , uid_t uid , gid_t gid )
110118{
111- char s [ 256 ] ;
119+ int len ;
112120
113121 if (name [0 ] == '/' )
114122 name ++ ;
115- sprintf ( s , "%s%08X%08X%08lX%08lX%08X%08lX"
123+ len = dprintf ( outfd , "%s%08X%08X%08lX%08lX%08X%08lX"
116124 "%08X%08X%08X%08X%08X%08X%08X" ,
117125 do_csum ? "070702" : "070701" , /* magic */
118126 ino ++ , /* ino */
@@ -128,12 +136,17 @@ static int cpio_mkslink(const char *name, const char *target,
128136 0 , /* rminor */
129137 (unsigned )strlen (name ) + 1 ,/* namesize */
130138 0 ); /* chksum */
131- push_hdr (s );
132- push_string (name );
133- push_pad ();
134- push_string (target );
135- push_pad ();
139+ offset += len ;
140+
141+ if (len != CPIO_HDR_LEN ||
142+ push_string (name ) < 0 ||
143+ push_pad (padlen (offset , 4 )) < 0 ||
144+ push_string (target ) < 0 ||
145+ push_pad (padlen (offset , 4 )) < 0 )
146+ return -1 ;
147+
136148 return 0 ;
149+
137150}
138151
139152static int cpio_mkslink_line (const char * line )
@@ -157,11 +170,11 @@ static int cpio_mkslink_line(const char *line)
157170static int cpio_mkgeneric (const char * name , unsigned int mode ,
158171 uid_t uid , gid_t gid )
159172{
160- char s [ 256 ] ;
173+ int len ;
161174
162175 if (name [0 ] == '/' )
163176 name ++ ;
164- sprintf ( s , "%s%08X%08X%08lX%08lX%08X%08lX"
177+ len = dprintf ( outfd , "%s%08X%08X%08lX%08lX%08X%08lX"
165178 "%08X%08X%08X%08X%08X%08X%08X" ,
166179 do_csum ? "070702" : "070701" , /* magic */
167180 ino ++ , /* ino */
@@ -177,8 +190,12 @@ static int cpio_mkgeneric(const char *name, unsigned int mode,
177190 0 , /* rminor */
178191 (unsigned )strlen (name ) + 1 ,/* namesize */
179192 0 ); /* chksum */
180- push_hdr (s );
181- push_rest (name );
193+ offset += len ;
194+
195+ if (len != CPIO_HDR_LEN ||
196+ push_rest (name ) < 0 )
197+ return -1 ;
198+
182199 return 0 ;
183200}
184201
@@ -246,7 +263,7 @@ static int cpio_mknod(const char *name, unsigned int mode,
246263 uid_t uid , gid_t gid , char dev_type ,
247264 unsigned int maj , unsigned int min )
248265{
249- char s [ 256 ] ;
266+ int len ;
250267
251268 if (dev_type == 'b' )
252269 mode |= S_IFBLK ;
@@ -255,7 +272,7 @@ static int cpio_mknod(const char *name, unsigned int mode,
255272
256273 if (name [0 ] == '/' )
257274 name ++ ;
258- sprintf ( s , "%s%08X%08X%08lX%08lX%08X%08lX"
275+ len = dprintf ( outfd , "%s%08X%08X%08lX%08lX%08X%08lX"
259276 "%08X%08X%08X%08X%08X%08X%08X" ,
260277 do_csum ? "070702" : "070701" , /* magic */
261278 ino ++ , /* ino */
@@ -271,8 +288,12 @@ static int cpio_mknod(const char *name, unsigned int mode,
271288 min , /* rminor */
272289 (unsigned )strlen (name ) + 1 ,/* namesize */
273290 0 ); /* chksum */
274- push_hdr (s );
275- push_rest (name );
291+ offset += len ;
292+
293+ if (len != CPIO_HDR_LEN ||
294+ push_rest (name ) < 0 )
295+ return -1 ;
296+
276297 return 0 ;
277298}
278299
@@ -324,11 +345,9 @@ static int cpio_mkfile(const char *name, const char *location,
324345 unsigned int mode , uid_t uid , gid_t gid ,
325346 unsigned int nlinks )
326347{
327- char s [256 ];
328348 struct stat buf ;
329349 unsigned long size ;
330- int file ;
331- int retval ;
350+ int file , retval , len ;
332351 int rc = -1 ;
333352 time_t mtime ;
334353 int namesize ;
@@ -386,7 +405,7 @@ static int cpio_mkfile(const char *name, const char *location,
386405 if (name [0 ] == '/' )
387406 name ++ ;
388407 namesize = strlen (name ) + 1 ;
389- sprintf ( s , "%s%08X%08X%08lX%08lX%08X%08lX"
408+ len = dprintf ( outfd , "%s%08X%08X%08lX%08lX%08X%08lX"
390409 "%08lX%08X%08X%08X%08X%08X%08X" ,
391410 do_csum ? "070702" : "070701" , /* magic */
392411 ino , /* ino */
@@ -402,9 +421,12 @@ static int cpio_mkfile(const char *name, const char *location,
402421 0 , /* rminor */
403422 namesize , /* namesize */
404423 size ? csum : 0 ); /* chksum */
405- push_hdr (s );
406- push_string (name );
407- push_pad ();
424+ offset += len ;
425+
426+ if (len != CPIO_HDR_LEN ||
427+ push_string (name ) < 0 ||
428+ push_pad (padlen (offset , 4 )) < 0 )
429+ goto error ;
408430
409431 while (size ) {
410432 unsigned char filebuf [65536 ];
@@ -417,14 +439,15 @@ static int cpio_mkfile(const char *name, const char *location,
417439 goto error ;
418440 }
419441
420- if (fwrite ( filebuf , this_read , 1 , stdout ) != 1 ) {
442+ if (write ( outfd , filebuf , this_read ) != this_read ) {
421443 fprintf (stderr , "writing filebuf failed\n" );
422444 goto error ;
423445 }
424446 offset += this_read ;
425447 size -= this_read ;
426448 }
427- push_pad ();
449+ if (push_pad (padlen (offset , 4 )) < 0 )
450+ goto error ;
428451
429452 name += namesize ;
430453 }
@@ -691,7 +714,7 @@ int main (int argc, char *argv[])
691714 }
692715 }
693716 if (ec == 0 )
694- cpio_trailer ();
717+ ec = cpio_trailer ();
695718
696719 exit (ec );
697720}
0 commit comments