source: trunk/server/source3/printing/tests/vlp.c

Last change on this file was 751, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.9

File size: 8.9 KB
Line 
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
34static TDB_CONTEXT *tdb;
35
36struct 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
48static void usage(void)
49{
50 printf("Usage: vlp tdbfile=/tmp/vlp.tdb lpq|lprm|print|queuepause|queueresume|"
51 "lppause|lpresume [args]\n");
52}
53
54/* Return an array of vlp jobs that is the printer queue */
55
56static 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 slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
63 data = tdb_fetch_bystring(tdb, keystr);
64
65 *job_list = (struct vlp_job *)data.dptr;
66 *num_jobs = data.dsize / sizeof(struct vlp_job);
67}
68
69/* Store an array of vl jobs for the queue */
70
71static 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 slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
78
79 data.dptr = (unsigned char *)job_list;
80 data.dsize = num_jobs * sizeof(struct vlp_job);
81 tdb_store_bystring(tdb, keystr, data, TDB_REPLACE);
82}
83
84/* Return the next job number for a printer */
85
86static int next_jobnum(char *printer)
87{
88 fstring keystr;
89 int jobnum;
90
91 slprintf(keystr, sizeof(keystr) - 1, "JOBNUM/%s", printer);
92
93 tdb_lock_bystring(tdb, keystr);
94
95 jobnum = tdb_fetch_int32(tdb, keystr);
96
97 /* Create next job index if none exists */
98
99 if (jobnum == -1) {
100 jobnum = atoi(PRINT_FIRSTJOB);
101 }
102
103 jobnum++;
104 tdb_store_int32(tdb, keystr, jobnum);
105
106 tdb_unlock_bystring(tdb, keystr);
107
108 return jobnum;
109}
110
111static void set_printer_status(char *printer, int status)
112{
113 fstring keystr;
114 int result;
115
116 slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
117 result = tdb_store_int32(tdb, keystr, status);
118}
119
120static int get_printer_status(char *printer)
121{
122 fstring keystr;
123 TDB_DATA data;
124
125 slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
126
127 data.dptr = (unsigned char *)keystr;
128 data.dsize = strlen(keystr) + 1;
129
130 if (!tdb_exists(tdb, data)) {
131 set_printer_status(printer, LPSTAT_OK);
132 return LPSTAT_OK;
133 }
134
135 return tdb_fetch_int32(tdb, keystr);
136}
137
138/* Display printer queue */
139
140static int lpq_command(int argc, char **argv)
141{
142 char *printer;
143 struct vlp_job *job_list = NULL;
144 int i, num_jobs, job_count = 0;
145
146 if (argc != 2) {
147 printf("Usage: lpq <printername>\n");
148 return 1;
149 }
150
151 printer = argv[1];
152
153 /* Display printer status */
154
155 switch (get_printer_status(printer)) {
156 case LPSTAT_OK:
157 printf("enabled\n");
158 break;
159 case LPSTAT_STOPPED:
160 printf("disabled\n");
161 break;
162 case LPSTAT_ERROR:
163 default:
164 printf("error\n");
165 break;
166 }
167
168 /* Print queued documents */
169
170 get_job_list(printer, &job_list, &num_jobs);
171
172 for (i = 0; i < num_jobs; i++) {
173 if (job_list[i].deleted) continue;
174 printf("%d\t%d\t%d\t%ld\t%s\t%s\n", job_list[i].jobid,
175 job_list[i].size,
176 (i == 0 && job_list[i].status == LPQ_QUEUED) ?
177 LPQ_SPOOLING : job_list[i].status,
178 (long int)job_list[i].submit_time, job_list[i].owner,
179 job_list[i].jobname);
180 job_count++;
181 }
182
183 free(job_list);
184
185 return 0;
186}
187
188/* Remove a job */
189
190static int lprm_command(int argc, char **argv)
191{
192 char *printer;
193 int jobid, num_jobs, i;
194 struct vlp_job *job_list;
195
196 if (argc < 3) {
197 printf("Usage: lprm <printername> <jobid>\n");
198 return 1;
199 }
200
201 printer = argv[1];
202 jobid = atoi(argv[2]);
203
204 get_job_list(printer, &job_list, &num_jobs);
205
206 for (i = 0; i < num_jobs; i++) {
207 if (job_list[i].jobid == jobid) {
208 job_list[i].deleted = 1;
209 set_job_list(printer, job_list, num_jobs);
210 break;
211 }
212 }
213
214 return 0;
215}
216
217/* print command = print-test %p %s */
218
219static int print_command(int argc, char **argv)
220{
221 char *printer;
222 fstring keystr;
223 struct passwd *pw;
224 TDB_DATA value, queue;
225 struct vlp_job job;
226
227 if (argc < 3) {
228 printf("Usage: print <printername> <jobname>\n");
229 return 1;
230 }
231
232 printer = argv[1];
233
234 ZERO_STRUCT(job);
235
236 /* Create a job record */
237
238 slprintf(job.jobname, sizeof(job.jobname) - 1, "%s", argv[2]);
239
240 if (!(pw = getpwuid(geteuid()))) {
241 printf("getpwuid failed\n");
242 return 1;
243 }
244
245 slprintf(job.owner, sizeof(job.owner) - 1, "%s", pw->pw_name);
246
247 job.jobid = next_jobnum(printer);
248 job.size = 666;
249 job.submit_time = time(NULL);
250
251 /* Store job entry in queue */
252
253 slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
254
255 value = tdb_fetch_bystring(tdb, keystr);
256
257 if (value.dptr) {
258
259 /* Add job to end of queue */
260
261 queue.dptr = (unsigned char *)malloc(value.dsize + sizeof(struct vlp_job));
262 if (!queue.dptr) return 1;
263
264 memcpy(queue.dptr, value.dptr, value.dsize);
265 memcpy(queue.dptr + value.dsize, &job, sizeof(struct vlp_job));
266
267 queue.dsize = value.dsize + sizeof(struct vlp_job);
268
269 tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
270
271 free(queue.dptr);
272
273 } else {
274
275 /* Create new queue */
276 queue.dptr = (unsigned char *)&job;
277 queue.dsize = sizeof(struct vlp_job);
278
279 tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
280 }
281
282 return 0;
283}
284
285/* Pause the queue */
286
287static int queuepause_command(int argc, char **argv)
288{
289 char *printer;
290
291 if (argc != 2) {
292 printf("Usage: queuepause <printername>\n");
293 return 1;
294 }
295
296 printer = argv[1];
297 set_printer_status(printer, LPSTAT_STOPPED);
298
299 return 0;
300}
301
302/* Resume the queue */
303
304static int queueresume_command(int argc, char **argv)
305{
306 char *printer;
307
308 if (argc != 2) {
309 printf("Usage: queueresume <printername>\n");
310 return 1;
311 }
312
313 printer = argv[1];
314 set_printer_status(printer, LPSTAT_OK);
315
316 return 0;
317}
318
319/* Pause a job */
320
321static int lppause_command(int argc, char **argv)
322{
323 struct vlp_job *job_list;
324 char *printer;
325 int jobid, num_jobs, i;
326
327 if (argc != 3) {
328 printf("Usage: lppause <printername> <jobid>\n");
329 return 1;
330 }
331
332 printer = argv[1];
333 jobid = atoi(argv[2]);
334
335 get_job_list(printer, &job_list, &num_jobs);
336
337 for (i = 0; i < num_jobs; i++) {
338 if (job_list[i].jobid == jobid) {
339 job_list[i].status = LPQ_PAUSED;
340 set_job_list(printer, job_list, num_jobs);
341 return 0;
342 }
343 }
344
345 return 1;
346}
347
348/* Resume a job */
349
350static int lpresume_command(int argc, char **argv)
351{
352 struct vlp_job *job_list;
353 char *printer;
354 int jobid, num_jobs, i;
355
356 if (argc != 3) {
357 printf("Usage: lpresume <printername> <jobid>\n");
358 return 1;
359 }
360
361 printer = argv[1];
362 jobid = atoi(argv[2]);
363
364 get_job_list(printer, &job_list, &num_jobs);
365
366 for (i = 0; i < num_jobs; i++) {
367 if (job_list[i].jobid == jobid) {
368 job_list[i].status = LPQ_QUEUED;
369 set_job_list(printer, job_list, num_jobs);
370 return 0;
371 }
372 }
373
374 return 1;
375}
376
377int main(int argc, char **argv)
378{
379 /* Parameter check */
380 const char *printdb_path = NULL;
381
382 if (argc < 2) {
383 usage();
384 return 1;
385 }
386
387 if (strncmp(argv[1], "tdbfile", strlen("tdbfile")) != 0) {
388 usage();
389 return 1;
390 }
391
392 printdb_path = get_string_param(argv[1]);
393 if (!printdb_path) {
394 return 1;
395 }
396
397 if (!(tdb = tdb_open(printdb_path, 0, 0, O_RDWR | O_CREAT,
398 0666))) {
399 printf("%s: unable to open %s\n", argv[0], printdb_path);
400 return 1;
401 }
402
403 /* Ensure we are modes 666 */
404
405 chmod(printdb_path, 0666);
406
407 /* Do commands */
408
409 if (strcmp(argv[2], "lpq") == 0) {
410 return lpq_command(argc - 2, &argv[2]);
411 }
412
413 if (strcmp(argv[2], "lprm") == 0) {
414 return lprm_command(argc - 2, &argv[2]);
415 }
416
417 if (strcmp(argv[2], "print") == 0) {
418 return print_command(argc - 2, &argv[2]);
419 }
420
421 if (strcmp(argv[2], "queuepause") == 0) {
422 return queuepause_command(argc - 2, &argv[2]);
423 }
424
425 if (strcmp(argv[2], "queueresume") == 0) {
426 return queueresume_command(argc - 2, &argv[2]);
427 }
428
429 if (strcmp(argv[2], "lppause") == 0) {
430 return lppause_command(argc - 2, &argv[2]);
431 }
432
433 if (strcmp(argv[2], "lpresume") == 0) {
434 return lpresume_command(argc - 2, &argv[2]);
435 }
436
437 /* Unknown command */
438
439 printf("%s: invalid command %s\n", argv[0], argv[1]);
440 return 1;
441}
Note: See TracBrowser for help on using the repository browser.