diff options
Diffstat (limited to 'printutils/lpr.c')
-rw-r--r-- | printutils/lpr.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/printutils/lpr.c b/printutils/lpr.c index 4f3b0247c..25cbcbc5e 100644 --- a/printutils/lpr.c +++ b/printutils/lpr.c | |||
@@ -149,6 +149,7 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) | |||
149 | 149 | ||
150 | // process files | 150 | // process files |
151 | do { | 151 | do { |
152 | unsigned cflen; | ||
152 | int dfd; | 153 | int dfd; |
153 | struct stat st; | 154 | struct stat st; |
154 | char *c; | 155 | char *c; |
@@ -194,23 +195,30 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) | |||
194 | ); | 195 | ); |
195 | // delete possible "\nX\n" patterns | 196 | // delete possible "\nX\n" patterns |
196 | c = controlfile; | 197 | c = controlfile; |
198 | cflen = (unsigned)strlen(controlfile); | ||
197 | while ((c = strchr(c, '\n')) != NULL) { | 199 | while ((c = strchr(c, '\n')) != NULL) { |
198 | c++; | 200 | if (c[1] && c[2] == '\n') { |
199 | while (c[0] && c[1] == '\n') | 201 | /* can't use strcpy, results are undefined */ |
200 | memmove(c, c+2, strlen(c+1)); /* strlen(c+1) == strlen(c+2) + 1 */ | 202 | memmove(c, c+2, cflen - (c-controlfile) - 1); |
203 | cflen -= 2; | ||
204 | } else { | ||
205 | c++; | ||
206 | } | ||
201 | } | 207 | } |
202 | 208 | ||
203 | // send control file | 209 | // send control file |
204 | if (opts & LPR_V) | 210 | if (opts & LPR_V) |
205 | bb_error_msg("sending control file"); | 211 | bb_error_msg("sending control file"); |
212 | /* "Acknowledgement processing must occur as usual | ||
213 | * after the command is sent." */ | ||
214 | fdprintf(fd, "\x2" "%u c%s\n", cflen, remote_filename); | ||
215 | get_response_or_say_and_die(fd, "sending control file"); | ||
206 | /* "Once all of the contents have | 216 | /* "Once all of the contents have |
207 | * been delivered, an octet of zero bits is sent as | 217 | * been delivered, an octet of zero bits is sent as |
208 | * an indication that the file being sent is complete. | 218 | * an indication that the file being sent is complete. |
209 | * A second level of acknowledgement processing | 219 | * A second level of acknowledgement processing |
210 | * must occur at this point." */ | 220 | * must occur at this point." */ |
211 | fdprintf(fd, "\x2" "%u c%s\n" "%s" "%c", | 221 | full_write(fd, controlfile, cflen + 1); /* writes NUL byte too */ |
212 | (unsigned)strlen(controlfile), | ||
213 | remote_filename, controlfile, '\0'); | ||
214 | get_response_or_say_and_die(fd, "sending control file"); | 222 | get_response_or_say_and_die(fd, "sending control file"); |
215 | 223 | ||
216 | // send data file, with name "dfaXXX" | 224 | // send data file, with name "dfaXXX" |
@@ -219,6 +227,7 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) | |||
219 | st.st_size = 0; /* paranoia: fstat may theoretically fail */ | 227 | st.st_size = 0; /* paranoia: fstat may theoretically fail */ |
220 | fstat(dfd, &st); | 228 | fstat(dfd, &st); |
221 | fdprintf(fd, "\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename); | 229 | fdprintf(fd, "\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename); |
230 | get_response_or_say_and_die(fd, "sending data file"); | ||
222 | if (bb_copyfd_size(dfd, fd, st.st_size) != st.st_size) { | 231 | if (bb_copyfd_size(dfd, fd, st.st_size) != st.st_size) { |
223 | // We're screwed. We sent less bytes than we advertised. | 232 | // We're screwed. We sent less bytes than we advertised. |
224 | bb_error_msg_and_die("local file changed size?!"); | 233 | bb_error_msg_and_die("local file changed size?!"); |