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