aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--printutils/lpr.c60
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 */
20static void get_response_or_say_and_die(const char *errmsg) 20static 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);