diff options
-rw-r--r-- | printutils/lpr.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/printutils/lpr.c b/printutils/lpr.c index 913da6f0f..153e6ab96 100644 --- a/printutils/lpr.c +++ b/printutils/lpr.c | |||
@@ -17,20 +17,18 @@ | |||
17 | * LPD returns binary 0 on success. | 17 | * LPD returns binary 0 on success. |
18 | * Otherwise it returns error message. | 18 | * Otherwise it returns error message. |
19 | */ | 19 | */ |
20 | static void get_response_or_say_and_die(const char *errmsg) | 20 | static void get_response_or_say_and_die(int fd, const char *errmsg) |
21 | { | 21 | { |
22 | ssize_t sz; | 22 | ssize_t sz; |
23 | char buf[128]; | 23 | char buf[128]; |
24 | 24 | ||
25 | fflush(stdout); | ||
26 | |||
27 | buf[0] = ' '; | 25 | buf[0] = ' '; |
28 | sz = safe_read(STDOUT_FILENO, buf, 1); | 26 | sz = safe_read(fd, buf, 1); |
29 | if ('\0' != buf[0]) { | 27 | if ('\0' != buf[0]) { |
30 | // request has failed | 28 | // request has failed |
31 | // try to make sure last char is '\n', but do not add | 29 | // try to make sure last char is '\n', but do not add |
32 | // superfluous one | 30 | // superfluous one |
33 | sz = full_read(STDOUT_FILENO, buf + 1, 126); | 31 | sz = full_read(fd, buf + 1, 126); |
34 | bb_error_msg("error while %s%s", errmsg, | 32 | bb_error_msg("error while %s%s", errmsg, |
35 | (sz > 0 ? ". Server said:" : "")); | 33 | (sz > 0 ? ". Server said:" : "")); |
36 | if (sz > 0) { | 34 | if (sz > 0) { |
@@ -70,7 +68,7 @@ int lpqr_main(int argc, char *argv[]) | |||
70 | const char *user = bb_getpwuid(NULL, -1, getuid()); | 68 | const char *user = bb_getpwuid(NULL, -1, getuid()); |
71 | unsigned job; | 69 | unsigned job; |
72 | unsigned opts; | 70 | unsigned opts; |
73 | int old_stdout, fd; | 71 | int fd; |
74 | 72 | ||
75 | // parse options | 73 | // parse options |
76 | // TODO: set opt_complementary: s,d,f are mutually exclusive | 74 | // TODO: set opt_complementary: s,d,f are mutually exclusive |
@@ -102,9 +100,6 @@ int lpqr_main(int argc, char *argv[]) | |||
102 | 100 | ||
103 | // do connect | 101 | // do connect |
104 | fd = create_and_connect_stream_or_die(server, 515); | 102 | fd = create_and_connect_stream_or_die(server, 515); |
105 | // play with descriptors to save space: fdprintf > printf | ||
106 | old_stdout = dup(STDOUT_FILENO); | ||
107 | xmove_fd(fd, STDOUT_FILENO); | ||
108 | 103 | ||
109 | // | 104 | // |
110 | // LPQ ------------------------ | 105 | // LPQ ------------------------ |
@@ -117,9 +112,9 @@ int lpqr_main(int argc, char *argv[]) | |||
117 | goto command; | 112 | goto command; |
118 | // delete job(s) | 113 | // delete job(s) |
119 | } else if (opts & LPQ_DELETE) { | 114 | } else if (opts & LPQ_DELETE) { |
120 | printf("\x5" "%s %s", queue, user); | 115 | fdprintf(fd, "\x5" "%s %s", queue, user); |
121 | while (*argv) { | 116 | while (*argv) { |
122 | printf(" %s", *argv++); | 117 | fdprintf(fd, " %s", *argv++); |
123 | } | 118 | } |
124 | bb_putchar('\n'); | 119 | bb_putchar('\n'); |
125 | // dump current jobs status | 120 | // dump current jobs status |
@@ -129,9 +124,8 @@ int lpqr_main(int argc, char *argv[]) | |||
129 | } else { | 124 | } else { |
130 | cmd = (opts & LPQ_SHORT_FMT) ? 3 : 4; | 125 | cmd = (opts & LPQ_SHORT_FMT) ? 3 : 4; |
131 | command: | 126 | command: |
132 | printf("%c" "%s\n", cmd, queue); | 127 | fdprintf(fd, "%c" "%s\n", cmd, queue); |
133 | fflush(stdout); | 128 | bb_copyfd_eof(fd, STDOUT_FILENO); |
134 | bb_copyfd_eof(STDOUT_FILENO, old_stdout); | ||
135 | } | 129 | } |
136 | 130 | ||
137 | return EXIT_SUCCESS; | 131 | return EXIT_SUCCESS; |
@@ -144,19 +138,18 @@ int lpqr_main(int argc, char *argv[]) | |||
144 | bb_error_msg("connected to server"); | 138 | bb_error_msg("connected to server"); |
145 | 139 | ||
146 | job = getpid() % 1000; | 140 | job = getpid() % 1000; |
147 | // TODO: when do finally we invent char *xgethostname()?!! | 141 | hostname = safe_gethostname(); |
148 | hostname = xzalloc(MAXHOSTNAMELEN+1); | ||
149 | gethostname(hostname, MAXHOSTNAMELEN); | ||
150 | 142 | ||
151 | // no files given on command line? -> use stdin | 143 | // no files given on command line? -> use stdin |
152 | if (!*argv) | 144 | if (!*argv) |
153 | *--argv = (char *)"-"; | 145 | *--argv = (char *)"-"; |
154 | 146 | ||
155 | printf("\x2" "%s\n", queue); | 147 | fdprintf(fd, "\x2" "%s\n", queue); |
156 | get_response_or_say_and_die("setting queue"); | 148 | get_response_or_say_and_die(fd, "setting queue"); |
157 | 149 | ||
158 | // process files | 150 | // process files |
159 | do { | 151 | do { |
152 | int dfd; | ||
160 | struct stat st; | 153 | struct stat st; |
161 | char *c; | 154 | char *c; |
162 | char *remote_filename; | 155 | char *remote_filename; |
@@ -165,14 +158,14 @@ int lpqr_main(int argc, char *argv[]) | |||
165 | // if data file is stdin, we need to dump it first | 158 | // if data file is stdin, we need to dump it first |
166 | if (LONE_DASH(*argv)) { | 159 | if (LONE_DASH(*argv)) { |
167 | strcpy(tempfile, "/tmp/lprXXXXXX"); | 160 | strcpy(tempfile, "/tmp/lprXXXXXX"); |
168 | fd = mkstemp(tempfile); | 161 | dfd = mkstemp(tempfile); |
169 | if (fd < 0) | 162 | if (dfd < 0) |
170 | bb_perror_msg_and_die("mkstemp"); | 163 | bb_perror_msg_and_die("mkstemp"); |
171 | bb_copyfd_eof(STDIN_FILENO, fd); | 164 | bb_copyfd_eof(STDIN_FILENO, dfd); |
172 | xlseek(fd, 0, SEEK_SET); | 165 | xlseek(dfd, 0, SEEK_SET); |
173 | *argv = (char*)bb_msg_standard_input; | 166 | *argv = (char*)bb_msg_standard_input; |
174 | } else { | 167 | } else { |
175 | fd = xopen(*argv, O_RDONLY); | 168 | dfd = xopen(*argv, O_RDONLY); |
176 | } | 169 | } |
177 | 170 | ||
178 | /* "The name ... should start with ASCII "cfA", | 171 | /* "The name ... should start with ASCII "cfA", |
@@ -215,24 +208,23 @@ int lpqr_main(int argc, char *argv[]) | |||
215 | * an indication that the file being sent is complete. | 208 | * an indication that the file being sent is complete. |
216 | * A second level of acknowledgement processing | 209 | * A second level of acknowledgement processing |
217 | * must occur at this point." */ | 210 | * must occur at this point." */ |
218 | printf("\x2" "%u c%s\n" "%s" "%c", | 211 | fdprintf(fd, "\x2" "%u c%s\n" "%s" "%c", |
219 | (unsigned)strlen(controlfile), | 212 | (unsigned)strlen(controlfile), |
220 | remote_filename, controlfile, '\0'); | 213 | remote_filename, controlfile, '\0'); |
221 | get_response_or_say_and_die("sending control file"); | 214 | get_response_or_say_and_die(fd, "sending control file"); |
222 | 215 | ||
223 | // send data file, with name "dfaXXX" | 216 | // send data file, with name "dfaXXX" |
224 | if (opts & LPR_V) | 217 | if (opts & LPR_V) |
225 | bb_error_msg("sending data file"); | 218 | bb_error_msg("sending data file"); |
226 | st.st_size = 0; /* paranoia: fstat may theoretically fail */ | 219 | st.st_size = 0; /* paranoia: fstat may theoretically fail */ |
227 | fstat(fd, &st); | 220 | fstat(dfd, &st); |
228 | printf("\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename); | 221 | fdprintf(fd, "\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename); |
229 | fflush(stdout); | 222 | if (bb_copyfd_size(dfd, fd, st.st_size) != st.st_size) { |
230 | if (bb_copyfd_size(fd, STDOUT_FILENO, st.st_size) != st.st_size) { | ||
231 | // We're screwed. We sent less bytes than we advertised. | 223 | // We're screwed. We sent less bytes than we advertised. |
232 | bb_error_msg_and_die("local file changed size?!"); | 224 | bb_error_msg_and_die("local file changed size?!"); |
233 | } | 225 | } |
234 | bb_putchar('\0'); | 226 | write(fd, "", 1); // send ACK |
235 | get_response_or_say_and_die("sending data file"); | 227 | get_response_or_say_and_die(fd, "sending data file"); |
236 | 228 | ||
237 | // delete temporary file if we dumped stdin | 229 | // delete temporary file if we dumped stdin |
238 | if (*argv == (char*)bb_msg_standard_input) | 230 | if (*argv == (char*)bb_msg_standard_input) |
@@ -243,6 +235,10 @@ int lpqr_main(int argc, char *argv[]) | |||
243 | free(remote_filename); | 235 | free(remote_filename); |
244 | free(controlfile); | 236 | free(controlfile); |
245 | 237 | ||
238 | // say job accepted | ||
239 | if (opts & LPR_V) | ||
240 | bb_error_msg("job accepted"); | ||
241 | |||
246 | // next, please! | 242 | // next, please! |
247 | job = (job + 1) % 1000; | 243 | job = (job + 1) % 1000; |
248 | } while (*++argv); | 244 | } while (*++argv); |