Line data Source code
1 : /*
2 : Unix SMB/Netbios implementation.
3 :
4 : Virtual lp system for printer testing
5 :
6 : Copyright (C) Tim Potter 2000
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "includes.h"
23 : #include "system/passwd.h"
24 : #include "system/filesys.h"
25 : #include "printing.h"
26 : #include "util_tdb.h"
27 :
28 : #ifdef malloc
29 : #undef malloc
30 : #endif
31 :
32 : #define PRINT_FIRSTJOB 100
33 :
34 : static TDB_CONTEXT *tdb;
35 :
36 : struct vlp_job {
37 : fstring owner;
38 : int jobid;
39 : fstring jobname;
40 : int size;
41 : int status;
42 : time_t submit_time;
43 : int deleted;
44 : };
45 :
46 : /* Print usage */
47 :
48 0 : static void usage(void)
49 : {
50 0 : printf("Usage: vlp tdbfile=/tmp/vlp.tdb lpq|lprm|print|queuepause|queueresume|"
51 : "lppause|lpresume [args]\n");
52 0 : }
53 :
54 : /* Return an array of vlp jobs that is the printer queue */
55 :
56 2429 : static void get_job_list(char *printer, struct vlp_job **job_list,
57 : int *num_jobs)
58 : {
59 : fstring keystr;
60 : TDB_DATA data;
61 :
62 2429 : slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
63 2429 : data = tdb_fetch_bystring(tdb, keystr);
64 :
65 2429 : *job_list = (struct vlp_job *)data.dptr;
66 2429 : *num_jobs = data.dsize / sizeof(struct vlp_job);
67 2429 : }
68 :
69 : /* Store an array of vl jobs for the queue */
70 :
71 398 : static void set_job_list(char *printer, struct vlp_job *job_list,
72 : int num_jobs)
73 : {
74 : fstring keystr;
75 : TDB_DATA data;
76 :
77 398 : slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
78 :
79 398 : data.dptr = (unsigned char *)job_list;
80 398 : data.dsize = num_jobs * sizeof(struct vlp_job);
81 398 : tdb_store_bystring(tdb, keystr, data, TDB_REPLACE);
82 398 : }
83 :
84 : /* Return the next job number for a printer */
85 :
86 340 : static int next_jobnum(char *printer)
87 : {
88 : fstring keystr;
89 : int jobnum;
90 :
91 340 : slprintf(keystr, sizeof(keystr) - 1, "JOBNUM/%s", printer);
92 :
93 340 : tdb_lock_bystring(tdb, keystr);
94 :
95 340 : jobnum = tdb_fetch_int32(tdb, keystr);
96 :
97 : /* Create next job index if none exists */
98 :
99 340 : if (jobnum == -1) {
100 18 : jobnum = PRINT_FIRSTJOB;
101 : } else {
102 322 : jobnum++;
103 : }
104 :
105 340 : tdb_store_int32(tdb, keystr, jobnum);
106 :
107 340 : tdb_unlock_bystring(tdb, keystr);
108 :
109 340 : return jobnum;
110 : }
111 :
112 148 : static void set_printer_status(char *printer, int status)
113 : {
114 : fstring keystr;
115 :
116 148 : slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
117 148 : tdb_store_int32(tdb, keystr, status);
118 148 : }
119 :
120 2022 : static int get_printer_status(char *printer)
121 : {
122 : fstring keystr;
123 : TDB_DATA data;
124 :
125 2022 : slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
126 :
127 2022 : data.dptr = (unsigned char *)keystr;
128 2022 : data.dsize = strlen(keystr) + 1;
129 :
130 2022 : if (!tdb_exists(tdb, data)) {
131 56 : set_printer_status(printer, LPSTAT_OK);
132 56 : return LPSTAT_OK;
133 : }
134 :
135 1966 : return tdb_fetch_int32(tdb, keystr);
136 : }
137 :
138 : /* Display printer queue */
139 :
140 2022 : static int lpq_command(int argc, char **argv)
141 : {
142 : char *printer;
143 2022 : struct vlp_job *job_list = NULL;
144 : int i, num_jobs;
145 :
146 2022 : if (argc != 2) {
147 0 : printf("Usage: lpq <printername>\n");
148 0 : return 1;
149 : }
150 :
151 2022 : printer = argv[1];
152 :
153 : /* Display printer status */
154 :
155 2022 : switch (get_printer_status(printer)) {
156 615 : case LPSTAT_OK:
157 615 : printf("enabled\n");
158 615 : break;
159 1407 : case LPSTAT_STOPPED:
160 1407 : printf("disabled\n");
161 1407 : break;
162 0 : case LPSTAT_ERROR:
163 : default:
164 0 : printf("error\n");
165 0 : break;
166 : }
167 :
168 : /* Print queued documents */
169 :
170 2022 : get_job_list(printer, &job_list, &num_jobs);
171 :
172 21181 : for (i = 0; i < num_jobs; i++) {
173 19159 : if (job_list[i].deleted) continue;
174 226 : printf("%d\t%d\t%d\t%ld\t%s\t%s\n", job_list[i].jobid,
175 3876 : job_list[i].size,
176 226 : (i == 0 && job_list[i].status == LPQ_QUEUED) ?
177 3650 : LPQ_SPOOLING : job_list[i].status,
178 3876 : (long int)job_list[i].submit_time, job_list[i].owner,
179 3876 : job_list[i].jobname);
180 : }
181 :
182 2022 : free(job_list);
183 :
184 2022 : return 0;
185 : }
186 :
187 : /* Remove a job */
188 :
189 343 : static int lprm_command(int argc, char **argv)
190 : {
191 : char *printer;
192 : int jobid, num_jobs, i;
193 : struct vlp_job *job_list;
194 :
195 343 : if (argc < 3) {
196 0 : printf("Usage: lprm <printername> <jobid>\n");
197 0 : return 1;
198 : }
199 :
200 343 : printer = argv[1];
201 343 : jobid = atoi(argv[2]);
202 :
203 343 : get_job_list(printer, &job_list, &num_jobs);
204 :
205 4969 : for (i = 0; i < num_jobs; i++) {
206 4960 : if (job_list[i].jobid == jobid) {
207 334 : job_list[i].deleted = 1;
208 334 : set_job_list(printer, job_list, num_jobs);
209 334 : break;
210 : }
211 : }
212 :
213 343 : return 0;
214 : }
215 :
216 : /* print command = print-test %p %s */
217 :
218 632 : static int print_command(int argc, char **argv)
219 : {
220 : char *printer;
221 : fstring keystr;
222 : struct passwd *pw;
223 : TDB_DATA value, queue;
224 : struct vlp_job job;
225 :
226 632 : if (argc < 3) {
227 0 : printf("Usage: print <printername> <jobname>\n");
228 0 : return 1;
229 : }
230 :
231 632 : printer = argv[1];
232 :
233 632 : ZERO_STRUCT(job);
234 :
235 : /* Create a job record */
236 :
237 632 : slprintf(job.jobname, sizeof(job.jobname) - 1, "%s", argv[2]);
238 :
239 632 : if (!(pw = getpwuid(geteuid()))) {
240 292 : printf("getpwuid failed\n");
241 292 : return 1;
242 : }
243 :
244 340 : slprintf(job.owner, sizeof(job.owner) - 1, "%s", pw->pw_name);
245 :
246 340 : job.jobid = next_jobnum(printer);
247 340 : job.size = 666;
248 340 : job.submit_time = time(NULL);
249 :
250 : /* Store job entry in queue */
251 :
252 340 : slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
253 :
254 340 : value = tdb_fetch_bystring(tdb, keystr);
255 :
256 340 : if (value.dptr) {
257 :
258 : /* Add job to end of queue */
259 :
260 322 : queue.dptr = (unsigned char *)malloc(value.dsize + sizeof(struct vlp_job));
261 322 : if (!queue.dptr) return 1;
262 :
263 322 : memcpy(queue.dptr, value.dptr, value.dsize);
264 322 : memcpy(queue.dptr + value.dsize, &job, sizeof(struct vlp_job));
265 :
266 322 : queue.dsize = value.dsize + sizeof(struct vlp_job);
267 :
268 322 : tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
269 :
270 322 : free(queue.dptr);
271 :
272 : } else {
273 :
274 : /* Create new queue */
275 18 : queue.dptr = (unsigned char *)&job;
276 18 : queue.dsize = sizeof(struct vlp_job);
277 :
278 18 : tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
279 : }
280 :
281 340 : return 0;
282 : }
283 :
284 : /* Pause the queue */
285 :
286 52 : static int queuepause_command(int argc, char **argv)
287 : {
288 : char *printer;
289 :
290 52 : if (argc != 2) {
291 0 : printf("Usage: queuepause <printername>\n");
292 0 : return 1;
293 : }
294 :
295 52 : printer = argv[1];
296 52 : set_printer_status(printer, LPSTAT_STOPPED);
297 :
298 52 : return 0;
299 : }
300 :
301 : /* Resume the queue */
302 :
303 40 : static int queueresume_command(int argc, char **argv)
304 : {
305 : char *printer;
306 :
307 40 : if (argc != 2) {
308 0 : printf("Usage: queueresume <printername>\n");
309 0 : return 1;
310 : }
311 :
312 40 : printer = argv[1];
313 40 : set_printer_status(printer, LPSTAT_OK);
314 :
315 40 : return 0;
316 : }
317 :
318 : /* Pause a job */
319 :
320 32 : static int lppause_command(int argc, char **argv)
321 : {
322 : struct vlp_job *job_list;
323 : char *printer;
324 : int jobid, num_jobs, i;
325 :
326 32 : if (argc != 3) {
327 0 : printf("Usage: lppause <printername> <jobid>\n");
328 0 : return 1;
329 : }
330 :
331 32 : printer = argv[1];
332 32 : jobid = atoi(argv[2]);
333 :
334 32 : get_job_list(printer, &job_list, &num_jobs);
335 :
336 656 : for (i = 0; i < num_jobs; i++) {
337 656 : if (job_list[i].jobid == jobid) {
338 32 : job_list[i].status = LPQ_PAUSED;
339 32 : set_job_list(printer, job_list, num_jobs);
340 32 : return 0;
341 : }
342 : }
343 :
344 0 : return 1;
345 : }
346 :
347 : /* Resume a job */
348 :
349 32 : static int lpresume_command(int argc, char **argv)
350 : {
351 : struct vlp_job *job_list;
352 : char *printer;
353 : int jobid, num_jobs, i;
354 :
355 32 : if (argc != 3) {
356 0 : printf("Usage: lpresume <printername> <jobid>\n");
357 0 : return 1;
358 : }
359 :
360 32 : printer = argv[1];
361 32 : jobid = atoi(argv[2]);
362 :
363 32 : get_job_list(printer, &job_list, &num_jobs);
364 :
365 656 : for (i = 0; i < num_jobs; i++) {
366 656 : if (job_list[i].jobid == jobid) {
367 32 : job_list[i].status = LPQ_QUEUED;
368 32 : set_job_list(printer, job_list, num_jobs);
369 32 : return 0;
370 : }
371 : }
372 :
373 0 : return 1;
374 : }
375 :
376 3153 : int main(int argc, char **argv)
377 : {
378 : /* Parameter check */
379 3153 : const char *printdb_path = NULL;
380 :
381 3153 : if (argc < 2) {
382 0 : usage();
383 0 : return 1;
384 : }
385 :
386 3153 : if (strncmp(argv[1], "tdbfile", strlen("tdbfile")) != 0) {
387 0 : usage();
388 0 : return 1;
389 : }
390 :
391 3153 : printdb_path = get_string_param(argv[1]);
392 3153 : if (!printdb_path) {
393 0 : return 1;
394 : }
395 :
396 : /* FIXME: We should *never* open a tdb without logging! */
397 3153 : if (!(tdb = tdb_open(printdb_path, 0, 0, O_RDWR | O_CREAT,
398 : 0666))) {
399 0 : printf("%s: unable to open %s\n", argv[0], printdb_path);
400 0 : return 1;
401 : }
402 :
403 : /* Ensure we are modes 666 */
404 :
405 3153 : chmod(printdb_path, 0666);
406 :
407 : /* Do commands */
408 3153 : if (argc < 3) {
409 0 : usage();
410 0 : return 1;
411 : }
412 :
413 3153 : if (strcmp(argv[2], "lpq") == 0) {
414 2022 : return lpq_command(argc - 2, &argv[2]);
415 : }
416 :
417 1131 : if (strcmp(argv[2], "lprm") == 0) {
418 343 : return lprm_command(argc - 2, &argv[2]);
419 : }
420 :
421 788 : if (strcmp(argv[2], "print") == 0) {
422 632 : return print_command(argc - 2, &argv[2]);
423 : }
424 :
425 156 : if (strcmp(argv[2], "queuepause") == 0) {
426 52 : return queuepause_command(argc - 2, &argv[2]);
427 : }
428 :
429 104 : if (strcmp(argv[2], "queueresume") == 0) {
430 40 : return queueresume_command(argc - 2, &argv[2]);
431 : }
432 :
433 64 : if (strcmp(argv[2], "lppause") == 0) {
434 32 : return lppause_command(argc - 2, &argv[2]);
435 : }
436 :
437 32 : if (strcmp(argv[2], "lpresume") == 0) {
438 32 : return lpresume_command(argc - 2, &argv[2]);
439 : }
440 :
441 : /* Unknown command */
442 :
443 0 : printf("%s: invalid command %s\n", argv[0], argv[1]);
444 0 : return 1;
445 : }
|