Gone back to explicit queue number passing as snum - removed encoding of
[garming/samba-autobuild/.git] / source3 / printing / printing.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing backend routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    Copyright (C) Jeremy Allison 2002
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 2 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 "printing.h"
24
25 /* Current printer interface */
26 static struct printif *current_printif = &generic_printif;
27
28 /* 
29    the printing backend revolves around a tdb database that stores the
30    SMB view of the print queue 
31    
32    The key for this database is a jobid - a internally generated number that
33    uniquely identifies a print job
34
35    reading the print queue involves two steps:
36      - possibly running lpq and updating the internal database from that
37      - reading entries from the database
38
39    jobids are assigned when a job starts spooling. 
40 */
41
42 /***************************************************************************
43  Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
44  bit RPC jobids.... JRA.
45 ***************************************************************************/
46
47 static TDB_CONTEXT *rap_tdb;
48 static uint16 next_rap_jobid;
49
50 uint16 pjobid_to_rap(int snum, uint32 jobid)
51 {
52         uint16 rap_jobid;
53         TDB_DATA data, key;
54         char jinfo[8];
55
56         if (!rap_tdb) {
57                 /* Create the in-memory tdb. */
58                 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
59                 if (!rap_tdb)
60                         return 0;
61         }
62
63         SIVAL(&jinfo,0,(int32)snum);
64         SIVAL(&jinfo,4,jobid);
65
66         key.dptr = (char *)&jinfo;
67         key.dsize = sizeof(jinfo);
68         data = tdb_fetch(rap_tdb, key);
69         if (data.dptr && data.dsize == sizeof(uint16)) {
70                 memcpy(&rap_jobid, data.dptr, sizeof(uint16));
71                 SAFE_FREE(data.dptr);
72                 return rap_jobid;
73         }
74         /* Not found - create and store mapping. */
75         rap_jobid = ++next_rap_jobid;
76         if (rap_jobid == 0)
77                 rap_jobid = ++next_rap_jobid;
78         data.dptr = (char *)&rap_jobid;
79         data.dsize = sizeof(rap_jobid);
80         tdb_store(rap_tdb, key, data, TDB_REPLACE);
81         tdb_store(rap_tdb, data, key, TDB_REPLACE);
82         return rap_jobid;
83 }
84
85 BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
86 {
87         TDB_DATA data, key;
88         char jinfo[8];
89
90         if (!rap_tdb)
91                 return False;
92
93         key.dptr = (char *)&rap_jobid;
94         key.dsize = sizeof(rap_jobid);
95         data = tdb_fetch(rap_tdb, key);
96         if (data.dptr && data.dsize == sizeof(jinfo)) {
97                 *psnum = IVAL(&jinfo,0);
98                 *pjobid = IVAL(&jinfo,4);
99                 SAFE_FREE(data.dptr);
100                 return True;
101         }
102         return False;
103 }
104
105 static void rap_jobid_delete(int snum, uint32 jobid)
106 {
107         TDB_DATA key, data;
108         uint16 rap_jobid;
109         char jinfo[8];
110
111         if (!rap_tdb)
112                 return;
113
114         SIVAL(&jinfo,0,(int32)snum);
115         SIVAL(&jinfo,4,jobid);
116
117         key.dptr = (char *)&jinfo;
118         key.dsize = sizeof(jinfo);
119         data = tdb_fetch(rap_tdb, key);
120         if (!data.dptr || (data.dsize != sizeof(uint16)))
121                 return;
122
123         memcpy(&rap_jobid, data.dptr, sizeof(uint16));
124         SAFE_FREE(data.dptr);
125         data.dptr = (char *)&rap_jobid;
126         data.dsize = sizeof(rap_jobid);
127         tdb_delete(rap_tdb, key);
128         tdb_delete(rap_tdb, data);
129 }
130
131 static pid_t local_pid;
132
133 static int get_queue_status(int, print_status_struct *);
134
135 #define MAX_PRINT_DBS_OPEN 1
136
137 struct tdb_print_db {
138         struct tdb_print_db *next, *prev;
139         TDB_CONTEXT *tdb;
140         fstring printer_name;
141 };
142
143 static struct tdb_print_db *print_db_head;
144
145 /****************************************************************************
146   Function to find or create the printer specific job tdb given a printername.
147   Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
148 ****************************************************************************/
149
150 static struct tdb_print_db *get_print_db_byname(const char *printername)
151 {
152         struct tdb_print_db *p, *last_entry;
153         int num_open = 0;
154         pstring printdb_path;
155
156         for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
157                 if (p->tdb && strequal(p->printer_name, printername)) {
158                         DLIST_PROMOTE(print_db_head, p);
159                         return p;
160                 }
161                 num_open++;
162                 last_entry = p;
163         }
164         /* Not found. */
165         if (num_open >= MAX_PRINT_DBS_OPEN) {
166                 /* Recycle the last entry. */
167                 DLIST_PROMOTE(print_db_head, last_entry);
168                 if (print_db_head->tdb) {
169                         if (tdb_close(print_db_head->tdb)) {
170                                 DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
171                                                         print_db_head->printer_name ));
172                                 return NULL;
173                         }
174                 }
175                 p = print_db_head;
176                 ZERO_STRUCTP(p);
177         } else {
178                 /* Create one. */
179                 p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
180                 if (!p) {
181                         DEBUG(0,("get_print_db: malloc fail !\n"));
182                         return NULL;
183                 }
184                 ZERO_STRUCTP(p);
185                 DLIST_ADD(print_db_head, p);
186         }
187
188         pstrcpy(printdb_path, lock_path("printing/"));
189         pstrcat(printdb_path, printername);
190         pstrcat(printdb_path, ".tdb");
191         p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
192         if (!p->tdb) {
193                 DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
194                                         printdb_path ));
195                 DLIST_REMOVE(print_db_head, p);
196                 SAFE_FREE(p);
197                 return NULL;
198         }
199         fstrcpy(p->printer_name, printername);
200         return p;
201 }
202
203 /****************************************************************************
204  Initialise the printing backend. Called once at startup. 
205  Does not survive a fork
206 ****************************************************************************/
207
208 BOOL print_backend_init(void)
209 {
210         char *sversion = "INFO/version";
211         pstring printing_path;
212         int services = lp_numservices();
213         int snum;
214
215         if (local_pid == sys_getpid())
216                 return True;
217
218         unlink(lock_path("printing.tdb"));
219         pstrcpy(printing_path,lock_path("printing"));
220         mkdir(printing_path,0755);
221
222         local_pid = sys_getpid();
223
224         /* handle a Samba upgrade */
225
226         for (snum = 0; snum < services; snum++) {
227                 struct tdb_print_db *pdb;
228                 if (!lp_print_ok(snum))
229                         continue;
230
231                 pdb = get_print_db_byname(lp_const_servicename(snum));
232                 if (!pdb)
233                         continue;
234                 tdb_lock_bystring(pdb->tdb, sversion);
235                 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
236                         tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
237                         tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
238                 }
239                 tdb_unlock_bystring(pdb->tdb, sversion);
240         }
241
242         /* select the appropriate printing interface... */
243 #ifdef HAVE_CUPS
244         if (strcmp(lp_printcapname(), "cups") == 0)
245                 current_printif = &cups_printif;
246 #endif /* HAVE_CUPS */
247
248         /* do NT print initialization... */
249         return nt_printing_init();
250 }
251
252 /****************************************************************************
253  Shut down printing backend. Called once at shutdown to close the tdb.
254 ****************************************************************************/
255
256 void printing_end(void)
257 {
258         struct tdb_print_db *p;
259
260         for (p = print_db_head; p; ) {
261                 struct tdb_print_db *next_p = p->next;
262                 if (p->tdb)
263                         tdb_close(p->tdb);
264                 DLIST_REMOVE(print_db_head, p);
265                 SAFE_FREE(p);
266                 p = next_p;
267         }
268 }
269
270 /****************************************************************************
271  Useful function to generate a tdb key.
272 ****************************************************************************/
273
274 static TDB_DATA print_key(uint32 jobid)
275 {
276         static uint32 j;
277         TDB_DATA ret;
278
279         j = jobid;
280         ret.dptr = (void *)&j;
281         ret.dsize = sizeof(j);
282         return ret;
283 }
284
285 /****************************************************************************
286  Useful function to find a print job in the database.
287 ****************************************************************************/
288
289 static struct printjob *print_job_find(int snum, uint32 jobid)
290 {
291         static struct printjob pjob;
292         TDB_DATA ret;
293         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
294
295         if (!pdb)
296                 return NULL;
297
298         ret = tdb_fetch(pdb->tdb, print_key(jobid));
299         if (!ret.dptr || ret.dsize != sizeof(pjob))
300                 return NULL;
301
302         memcpy(&pjob, ret.dptr, sizeof(pjob));
303         SAFE_FREE(ret.dptr);
304         return &pjob;
305 }
306
307 /* Convert a unix jobid to a smb jobid */
308
309 static uint32 sysjob_to_jobid_value;
310
311 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
312                                TDB_DATA data, void *state)
313 {
314         struct printjob *pjob = (struct printjob *)data.dptr;
315         int *sysjob = (int *)state;
316
317         if (key.dsize != sizeof(uint32))
318                 return 0;
319
320         if (*sysjob == pjob->sysjob) {
321                 uint32 *jobid = (uint32 *)key.dptr;
322
323                 sysjob_to_jobid_value = *jobid;
324                 return 1;
325         }
326
327         return 0;
328 }
329
330 /****************************************************************************
331  This is a *horribly expensive call as we have to iterate through all the
332  current printer tdb's. Don't do this often ! JRA.
333 ****************************************************************************/
334
335 uint32 sysjob_to_jobid(int unix_jobid)
336 {
337         int services = lp_numservices();
338         int snum;
339
340         sysjob_to_jobid_value = (uint32)-1;
341
342         for (snum = 0; snum < services; snum++) {
343                 struct tdb_print_db *pdb;
344                 if (!lp_print_ok(snum))
345                         continue;
346                 pdb = get_print_db_byname(lp_const_servicename(snum));
347                 if (pdb)
348                         tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
349                 if (sysjob_to_jobid_value != (uint32)-1)
350                         return sysjob_to_jobid_value;
351         }
352         return (uint32)-1;
353 }
354
355 /****************************************************************************
356  Send notifications based on what has changed after a pjob_store.
357 ****************************************************************************/
358
359 static struct {
360         uint32 lpq_status;
361         uint32 spoolss_status;
362 } lpq_to_spoolss_status_map[] = {
363         { LPQ_QUEUED, JOB_STATUS_QUEUED },
364         { LPQ_PAUSED, JOB_STATUS_PAUSED },
365         { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
366         { LPQ_PRINTING, JOB_STATUS_PRINTING },
367         { LPQ_DELETING, JOB_STATUS_DELETING },
368         { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
369         { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
370         { LPQ_PRINTED, JOB_STATUS_PRINTED },
371         { LPQ_DELETED, JOB_STATUS_DELETED },
372         { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
373         { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
374         { -1, 0 }
375 };
376
377 /* Convert a lpq status value stored in printing.tdb into the
378    appropriate win32 API constant. */
379
380 static uint32 map_to_spoolss_status(uint32 lpq_status)
381 {
382         int i = 0;
383
384         while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
385                 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
386                         return lpq_to_spoolss_status_map[i].spoolss_status;
387                 i++;
388         }
389
390         return 0;
391 }
392
393 static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
394                               struct printjob *new_data)
395 {
396         BOOL new_job = False;
397
398         if (!old_data)
399                 new_job = True;
400
401         /* Notify the job name first */
402
403         if (new_job || !strequal(old_data->jobname, new_data->jobname))
404                 notify_job_name(snum, jobid, new_data->jobname);
405
406         /* Job attributes that can't be changed.  We only send
407            notification for these on a new job. */
408
409         if (new_job) {
410                 notify_job_submitted(snum, jobid, new_data->starttime);
411                 notify_job_username(snum, jobid, new_data->user);
412         }
413
414         /* Job attributes of a new job or attributes that can be
415            modified. */
416
417         if (new_job || old_data->status != new_data->status)
418                 notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
419
420         if (new_job || old_data->size != new_data->size)
421                 notify_job_total_bytes(snum, jobid, new_data->size);
422
423         if (new_job || old_data->page_count != new_data->page_count)
424                 notify_job_total_pages(snum, jobid, new_data->page_count);
425 }
426
427 /****************************************************************************
428  Store a job structure back to the database.
429 ****************************************************************************/
430
431 static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
432 {
433         TDB_DATA old_data, new_data;
434         BOOL ret;
435         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
436
437         if (!pdb)
438                 return False;
439
440         /* Get old data */
441
442         old_data = tdb_fetch(pdb->tdb, print_key(jobid));
443
444         /* Store new data */
445
446         new_data.dptr = (void *)pjob;
447         new_data.dsize = sizeof(*pjob);
448         ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
449
450         /* Send notify updates for what has changed */
451
452         if (ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob))) {
453                 pjob_store_notify(
454                         snum, jobid, (struct printjob *)old_data.dptr,
455                         (struct printjob *)new_data.dptr);
456                 free(old_data.dptr);
457         }
458
459         return ret;
460 }
461
462 /****************************************************************************
463  Remove a job structure from the database.
464 ****************************************************************************/
465
466 static void pjob_delete(int snum, uint32 jobid)
467 {
468         struct printjob *pjob = print_job_find(snum, jobid);
469         uint32 job_status = 0;
470         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
471
472         if (!pdb)
473                 return;
474
475         if (!pjob) {
476                 DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
477                                         (unsigned int)jobid));
478                 return;
479         }
480
481         /* Send a notification that a job has been deleted */
482
483         job_status = map_to_spoolss_status(pjob->status);
484
485         /* We must cycle through JOB_STATUS_DELETING and
486            JOB_STATUS_DELETED for the port monitor to delete the job
487            properly. */
488         
489         job_status |= JOB_STATUS_DELETING;
490         notify_job_status(snum, jobid, job_status);
491         
492         job_status |= JOB_STATUS_DELETED;
493         notify_job_status(snum, jobid, job_status);
494
495         /* Remove from printing.tdb */
496
497         tdb_delete(pdb->tdb, print_key(jobid));
498         rap_jobid_delete(snum, jobid);
499 }
500
501 /****************************************************************************
502  Parse a file name from the system spooler to generate a jobid.
503 ****************************************************************************/
504
505 static uint32 print_parse_jobid(char *fname)
506 {
507         int jobid;
508
509         if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
510                 return (uint32)-1;
511         fname += strlen(PRINT_SPOOL_PREFIX);
512
513         jobid = atoi(fname);
514         if (jobid <= 0)
515                 return (uint32)-1;
516
517         return (uint32)jobid;
518 }
519
520 /****************************************************************************
521  List a unix job in the print database.
522 ****************************************************************************/
523
524 static void print_unix_job(int snum, print_queue_struct *q)
525 {
526         uint32 jobid = q->job + UNIX_JOB_START;
527         struct printjob pj, *old_pj;
528
529         /* Preserve the timestamp on an existing unix print job */
530
531         old_pj = print_job_find(snum, jobid);
532
533         ZERO_STRUCT(pj);
534
535         pj.pid = (pid_t)-1;
536         pj.sysjob = q->job;
537         pj.fd = -1;
538         pj.starttime = old_pj ? old_pj->starttime : q->time;
539         pj.status = q->status;
540         pj.size = q->size;
541         pj.spooled = True;
542         pj.smbjob = False;
543         fstrcpy(pj.filename, "");
544         fstrcpy(pj.jobname, q->fs_file);
545         fstrcpy(pj.user, q->fs_user);
546         fstrcpy(pj.queuename, lp_const_servicename(snum));
547
548         pjob_store(snum, jobid, &pj);
549 }
550
551
552 struct traverse_struct {
553         print_queue_struct *queue;
554         int qcount, snum, maxcount, total_jobs;
555 };
556
557 /****************************************************************************
558  Utility fn to delete any jobs that are no longer active.
559 ****************************************************************************/
560
561 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
562 {
563         struct traverse_struct *ts = (struct traverse_struct *)state;
564         struct printjob pjob;
565         uint32 jobid;
566         int i;
567
568         if (data.dsize != sizeof(pjob) || key.dsize != sizeof(jobid))
569                 return 0;
570         memcpy(&jobid, key.dptr, sizeof(jobid));
571         memcpy(&pjob,  data.dptr, sizeof(pjob));
572
573         if (ts->snum != lp_servicenumber(pjob.queuename)) {
574                 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
575                 return 0;
576         }
577
578         if (!pjob.smbjob) {
579                 /* remove a unix job if it isn't in the system queue any more */
580
581                 for (i=0;i<ts->qcount;i++) {
582                         uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
583                         if (jobid == u_jobid)
584                                 break;
585                 }
586                 if (i == ts->qcount)
587                         pjob_delete(ts->snum, jobid);
588                 else
589                         ts->total_jobs++;
590                 return 0;
591         }
592
593         /* maybe it hasn't been spooled yet */
594         if (!pjob.spooled) {
595                 /* if a job is not spooled and the process doesn't
596                    exist then kill it. This cleans up after smbd
597                    deaths */
598                 if (!process_exists(pjob.pid))
599                         pjob_delete(ts->snum, jobid);
600                 else
601                         ts->total_jobs++;
602                 return 0;
603         }
604
605         for (i=0;i<ts->qcount;i++) {
606                 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
607                 if (jobid == curr_jobid)
608                         break;
609         }
610         
611         /* The job isn't in the system queue - we have to assume it has
612            completed, so delete the database entry. */
613
614         if (i == ts->qcount) {
615                 time_t cur_t = time(NULL);
616
617                 /* A race can occur between the time a job is spooled and
618                    when it appears in the lpq output.  This happens when
619                    the job is added to printing.tdb when another smbd
620                    running print_queue_update() has completed a lpq and
621                    is currently traversing the printing tdb and deleting jobs.
622                    A workaround is to not delete the job if it has been 
623                    submitted less than lp_lpqcachetime() seconds ago. */
624
625                 if ((cur_t - pjob.starttime) > lp_lpqcachetime())
626                         pjob_delete(ts->snum, jobid);
627                 else
628                         ts->total_jobs++;
629         }
630         else
631                 ts->total_jobs++;
632
633         return 0;
634 }
635
636 /****************************************************************************
637  Check if the print queue has been updated recently enough.
638 ****************************************************************************/
639
640 static void print_cache_flush(int snum)
641 {
642         fstring key;
643         const char *printername = lp_const_servicename(snum);
644         struct tdb_print_db *pdb = get_print_db_byname(printername);
645
646         if (!pdb)
647                 return;
648         slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
649         tdb_store_int32(pdb->tdb, key, -1);
650 }
651
652 /****************************************************************************
653  Check if someone already thinks they are doing the update.
654 ****************************************************************************/
655
656 static pid_t get_updating_pid(fstring printer_name)
657 {
658         fstring keystr;
659         TDB_DATA data, key;
660         pid_t updating_pid;
661         struct tdb_print_db *pdb = get_print_db_byname(printer_name);
662
663         if (!pdb)
664                 return (pid_t)-1;
665         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
666         key.dptr = keystr;
667         key.dsize = strlen(keystr);
668
669         data = tdb_fetch(pdb->tdb, key);
670         if (!data.dptr || data.dsize != sizeof(pid_t))
671                 return (pid_t)-1;
672
673         memcpy(&updating_pid, data.dptr, sizeof(pid_t));
674         SAFE_FREE(data.dptr);
675
676         if (process_exists(updating_pid))
677                 return updating_pid;
678
679         return (pid_t)-1;
680 }
681
682 /****************************************************************************
683  Set the fact that we're doing the update, or have finished doing the update
684  in the tdb.
685 ****************************************************************************/
686
687 static void set_updating_pid(const fstring printer_name, BOOL delete)
688 {
689         fstring keystr;
690         TDB_DATA key;
691         TDB_DATA data;
692         pid_t updating_pid = sys_getpid();
693         struct tdb_print_db *pdb = get_print_db_byname(printer_name);
694
695         if (!pdb)
696                 return;
697
698         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
699         key.dptr = keystr;
700         key.dsize = strlen(keystr);
701
702         if (delete) {
703                 tdb_delete(pdb->tdb, key);
704                 return;
705         }
706         
707         data.dptr = (void *)&updating_pid;
708         data.dsize = sizeof(pid_t);
709
710         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
711 }
712
713 /****************************************************************************
714  Update the internal database from the system print queue for a queue.
715 ****************************************************************************/
716
717 static void print_queue_update(int snum)
718 {
719         int i, qcount;
720         print_queue_struct *queue = NULL;
721         print_status_struct status;
722         print_status_struct old_status;
723         struct printjob *pjob;
724         struct traverse_struct tstruct;
725         fstring keystr, printer_name, cachestr;
726         TDB_DATA data, key;
727         struct tdb_print_db *pdb;
728
729         fstrcpy(printer_name, lp_const_servicename(snum));
730         pdb = get_print_db_byname(printer_name);
731         if (!pdb)
732                 return;
733
734         /*
735          * Check to see if someone else is doing this update.
736          * This is essentially a mutex on the update.
737          */
738
739         if (get_updating_pid(printer_name) != -1)
740                 return;
741
742         /* Lock the queue for the database update */
743
744         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
745         tdb_lock_bystring(pdb->tdb, keystr);
746
747         /*
748          * Ensure that no one else got in here.
749          * If the updating pid is still -1 then we are
750          * the winner.
751          */
752
753         if (get_updating_pid(printer_name) != -1) {
754                 /*
755                  * Someone else is doing the update, exit.
756                  */
757                 tdb_unlock_bystring(pdb->tdb, keystr);
758                 return;
759         }
760
761         /*
762          * We're going to do the update ourselves.
763          */
764
765         /* Tell others we're doing the update. */
766         set_updating_pid(printer_name, False);
767
768         /*
769          * Allow others to enter and notice we're doing
770          * the update.
771          */
772
773         tdb_unlock_bystring(pdb->tdb, keystr);
774
775         /*
776          * Update the cache time FIRST ! Stops others even
777          * attempting to get the lock and doing this
778          * if the lpq takes a long time.
779          */
780
781         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
782         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
783
784         /* get the current queue using the appropriate interface */
785         ZERO_STRUCT(status);
786
787         qcount = (*(current_printif->queue_get))(snum, &queue, &status);
788
789         DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
790                 "s" : "", printer_name));
791
792         /*
793           any job in the internal database that is marked as spooled
794           and doesn't exist in the system queue is considered finished
795           and removed from the database
796
797           any job in the system database but not in the internal database 
798           is added as a unix job
799
800           fill in any system job numbers as we go
801         */
802         for (i=0; i<qcount; i++) {
803                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
804
805                 if (jobid == (uint32)-1) {
806                         /* assume its a unix print job */
807                         print_unix_job(snum, &queue[i]);
808                         continue;
809                 }
810
811                 /* we have an active SMB print job - update its status */
812                 pjob = print_job_find(snum, jobid);
813                 if (!pjob) {
814                         /* err, somethings wrong. Probably smbd was restarted
815                            with jobs in the queue. All we can do is treat them
816                            like unix jobs. Pity. */
817                         print_unix_job(snum, &queue[i]);
818                         continue;
819                 }
820
821                 pjob->sysjob = queue[i].job;
822                 pjob->status = queue[i].status;
823
824                 pjob_store(snum, jobid, pjob);
825         }
826
827         /* now delete any queued entries that don't appear in the
828            system queue */
829         tstruct.queue = queue;
830         tstruct.qcount = qcount;
831         tstruct.snum = snum;
832         tstruct.total_jobs = 0;
833
834         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
835
836         SAFE_FREE(tstruct.queue);
837
838         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
839
840         if( qcount != get_queue_status(snum, &old_status))
841                 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
842                                         old_status.qcount, qcount, printer_name ));
843
844         /* store the new queue status structure */
845         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
846         key.dptr = keystr;
847         key.dsize = strlen(keystr);
848
849         status.qcount = qcount;
850         data.dptr = (void *)&status;
851         data.dsize = sizeof(status);
852         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
853
854         /*
855          * Update the cache time again. We want to do this call
856          * as little as possible...
857          */
858
859         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
860         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
861
862         /* Delete our pid from the db. */
863         set_updating_pid(printer_name, True);
864 }
865
866 /****************************************************************************
867  Check if a jobid is valid. It is valid if it exists in the database.
868 ****************************************************************************/
869
870 BOOL print_job_exists(int snum, uint32 jobid)
871 {
872         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
873         if (!pdb)
874                 return False;
875         return tdb_exists(pdb->tdb, print_key(jobid));
876 }
877
878 /****************************************************************************
879  Give the fd used for a jobid.
880 ****************************************************************************/
881
882 int print_job_fd(int snum, uint32 jobid)
883 {
884         struct printjob *pjob = print_job_find(snum, jobid);
885         if (!pjob)
886                 return -1;
887         /* don't allow another process to get this info - it is meaningless */
888         if (pjob->pid != local_pid)
889                 return -1;
890         return pjob->fd;
891 }
892
893 /****************************************************************************
894  Give the filename used for a jobid.
895  Only valid for the process doing the spooling and when the job
896  has not been spooled.
897 ****************************************************************************/
898
899 char *print_job_fname(int snum, uint32 jobid)
900 {
901         struct printjob *pjob = print_job_find(snum, jobid);
902         if (!pjob || pjob->spooled || pjob->pid != local_pid)
903                 return NULL;
904         return pjob->filename;
905 }
906
907 /****************************************************************************
908  Set the place in the queue for a job.
909 ****************************************************************************/
910
911 BOOL print_job_set_place(int snum, uint32 jobid, int place)
912 {
913         DEBUG(2,("print_job_set_place not implemented yet\n"));
914         return False;
915 }
916
917 /****************************************************************************
918  Set the name of a job. Only possible for owner.
919 ****************************************************************************/
920
921 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
922 {
923         struct printjob *pjob = print_job_find(snum, jobid);
924         if (!pjob || pjob->pid != local_pid)
925                 return False;
926
927         fstrcpy(pjob->jobname, name);
928         return pjob_store(snum, jobid, pjob);
929 }
930
931 /****************************************************************************
932  Delete a print job - don't update queue.
933 ****************************************************************************/
934
935 static BOOL print_job_delete1(int snum, uint32 jobid)
936 {
937         struct printjob *pjob = print_job_find(snum, jobid);
938         int result = 0;
939
940         if (!pjob)
941                 return False;
942
943         /*
944          * If already deleting just return.
945          */
946
947         if (pjob->status == LPQ_DELETING)
948                 return True;
949
950         /* Hrm - we need to be able to cope with deleting a job before it
951            has reached the spooler. */
952
953         if (pjob->sysjob == -1) {
954                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
955         }
956
957         /* Set the tdb entry to be deleting. */
958
959         pjob->status = LPQ_DELETING;
960         pjob_store(snum, jobid, pjob);
961
962         if (pjob->spooled && pjob->sysjob != -1)
963                 result = (*(current_printif->job_delete))(snum, pjob);
964
965         /* Delete the tdb entry if the delete suceeded or the job hasn't
966            been spooled. */
967
968         if (result == 0)
969                 pjob_delete(snum, jobid);
970
971         return (result == 0);
972 }
973
974 /****************************************************************************
975  Return true if the current user owns the print job.
976 ****************************************************************************/
977
978 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
979 {
980         struct printjob *pjob = print_job_find(snum, jobid);
981         user_struct *vuser;
982
983         if (!pjob || !user)
984                 return False;
985
986         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
987                 return strequal(pjob->user, vuser->user.smb_name);
988         } else {
989                 return strequal(pjob->user, uidtoname(user->uid));
990         }
991 }
992
993 /****************************************************************************
994  Delete a print job.
995 ****************************************************************************/
996
997 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
998 {
999         BOOL owner;
1000
1001         owner = is_owner(user, snum, jobid);
1002         
1003         /* Check access against security descriptor or whether the user
1004            owns their job. */
1005
1006         if (!owner && 
1007             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1008                 DEBUG(3, ("delete denied by security descriptor\n"));
1009                 *errcode = WERR_ACCESS_DENIED;
1010                 return False;
1011         }
1012
1013         if (!print_job_delete1(snum, jobid)) 
1014                 return False;
1015
1016         /* force update the database and say the delete failed if the
1017            job still exists */
1018
1019         print_queue_update(snum);
1020
1021         return !print_job_exists(snum, jobid);
1022 }
1023
1024 /****************************************************************************
1025  Pause a job.
1026 ****************************************************************************/
1027
1028 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1029 {
1030         struct printjob *pjob = print_job_find(snum, jobid);
1031         int ret = -1;
1032         
1033         if (!pjob || !user) 
1034                 return False;
1035
1036         if (!pjob->spooled || pjob->sysjob == -1) 
1037                 return False;
1038
1039         if (!is_owner(user, snum, jobid) &&
1040             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1041                 DEBUG(3, ("pause denied by security descriptor\n"));
1042                 *errcode = WERR_ACCESS_DENIED;
1043                 return False;
1044         }
1045
1046         /* need to pause the spooled entry */
1047         ret = (*(current_printif->job_pause))(snum, pjob);
1048
1049         if (ret != 0) {
1050                 *errcode = WERR_INVALID_PARAM;
1051                 return False;
1052         }
1053
1054         /* force update the database */
1055         print_cache_flush(snum);
1056
1057         /* Send a printer notify message */
1058
1059         notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1060
1061         /* how do we tell if this succeeded? */
1062
1063         return True;
1064 }
1065
1066 /****************************************************************************
1067  Resume a job.
1068 ****************************************************************************/
1069
1070 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1071 {
1072         struct printjob *pjob = print_job_find(snum, jobid);
1073         int ret;
1074         
1075         if (!pjob || !user)
1076                 return False;
1077
1078         if (!pjob->spooled || pjob->sysjob == -1)
1079                 return False;
1080
1081         if (!is_owner(user, snum, jobid) &&
1082             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1083                 DEBUG(3, ("resume denied by security descriptor\n"));
1084                 *errcode = WERR_ACCESS_DENIED;
1085                 return False;
1086         }
1087
1088         ret = (*(current_printif->job_resume))(snum, pjob);
1089
1090         if (ret != 0) {
1091                 *errcode = WERR_INVALID_PARAM;
1092                 return False;
1093         }
1094
1095         /* force update the database */
1096         print_cache_flush(snum);
1097
1098         /* Send a printer notify message */
1099
1100         notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1101
1102         return True;
1103 }
1104
1105 /****************************************************************************
1106  Write to a print file.
1107 ****************************************************************************/
1108
1109 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1110 {
1111         int return_code;
1112         struct printjob *pjob = print_job_find(snum, jobid);
1113
1114         if (!pjob)
1115                 return -1;
1116         /* don't allow another process to get this info - it is meaningless */
1117         if (pjob->pid != local_pid)
1118                 return -1;
1119
1120         return_code = write(pjob->fd, buf, size);
1121         if (return_code>0) {
1122                 pjob->size += size;
1123                 pjob_store(snum, jobid, pjob);
1124         }
1125         return return_code;
1126 }
1127
1128 /****************************************************************************
1129  Check if the print queue has been updated recently enough.
1130 ****************************************************************************/
1131
1132 static BOOL print_cache_expired(int snum)
1133 {
1134         fstring key;
1135         time_t last_qscan_time, time_now = time(NULL);
1136         const char *printername = lp_const_servicename(snum);
1137         struct tdb_print_db *pdb = get_print_db_byname(printername);
1138
1139         if (!pdb)
1140                 return False;
1141
1142         slprintf(key, sizeof(key), "CACHE/%s", printername);
1143         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1144
1145         /*
1146          * Invalidate the queue for 3 reasons.
1147          * (1). last queue scan time == -1.
1148          * (2). Current time - last queue scan time > allowed cache time.
1149          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1150          * This last test picks up machines for which the clock has been moved
1151          * forward, an lpq scan done and then the clock moved back. Otherwise
1152          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1153          */
1154
1155         if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1156                         last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1157                 DEBUG(3, ("print cache expired for queue %s \
1158 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1159                         (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1160                 return True;
1161         }
1162         return False;
1163 }
1164
1165 /****************************************************************************
1166  Get the queue status - do not update if db is out of date.
1167 ****************************************************************************/
1168
1169 static int get_queue_status(int snum, print_status_struct *status)
1170 {
1171         fstring keystr;
1172         TDB_DATA data, key;
1173         const char *printername = lp_const_servicename(snum);
1174         struct tdb_print_db *pdb = get_print_db_byname(printername);
1175         if (!pdb)
1176                 return 0;
1177
1178         ZERO_STRUCTP(status);
1179         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1180         key.dptr = keystr;
1181         key.dsize = strlen(keystr);
1182         data = tdb_fetch(pdb->tdb, key);
1183         if (data.dptr) {
1184                 if (data.dsize == sizeof(print_status_struct)) {
1185                         memcpy(status, data.dptr, sizeof(print_status_struct));
1186                 }
1187                 SAFE_FREE(data.dptr);
1188         }
1189         return status->qcount;
1190 }
1191
1192 /****************************************************************************
1193  Determine the number of jobs in a queue.
1194 ****************************************************************************/
1195
1196 int print_queue_length(int snum, print_status_struct *pstatus)
1197 {
1198         print_status_struct status;
1199         int len;
1200  
1201         /* make sure the database is up to date */
1202         if (print_cache_expired(snum))
1203                 print_queue_update(snum);
1204  
1205         /* also fetch the queue status */
1206         memset(&status, 0, sizeof(status));
1207         len = get_queue_status(snum, &status);
1208         if (pstatus)
1209                 *pstatus = status;
1210         return len;
1211 }
1212
1213 /****************************************************************************
1214  Determine the number of jobs in all queues. This is very expensive. Don't
1215  call ! JRA.
1216 ****************************************************************************/
1217
1218 static int get_total_jobs(void)
1219 {
1220         int total_jobs;
1221         int snum;
1222         int services = lp_numservices();
1223
1224         for (snum = 0; snum < services; snum++) {
1225                 struct tdb_print_db *pdb;
1226                 int jobs;
1227
1228                 if (!lp_print_ok(snum))
1229                         continue;
1230
1231                 pdb = get_print_db_byname(lp_const_servicename(snum));
1232                 if (!pdb)
1233                         continue;
1234
1235                 /* make sure the database is up to date */
1236                 if (print_cache_expired(snum))
1237                         print_queue_update(snum);
1238
1239                 jobs = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1240                 if (jobs > 0)
1241                         total_jobs += jobs;
1242         }
1243         return total_jobs;
1244 }
1245
1246 /***************************************************************************
1247  Start spooling a job - return the jobid.
1248 ***************************************************************************/
1249
1250 uint32 print_job_start(struct current_user *user, int snum, char *jobname)
1251 {
1252         uint32 jobid;
1253         char *path;
1254         struct printjob pjob;
1255         int next_jobid;
1256         user_struct *vuser;
1257         int njobs = 0;
1258         const char *printername = lp_const_servicename(snum);
1259         struct tdb_print_db *pdb = get_print_db_byname(printername);
1260
1261         errno = 0;
1262
1263         if (!pdb)
1264                 return (uint32)-1;
1265
1266         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
1267                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1268                 return (uint32)-1;
1269         }
1270
1271         if (!print_time_access_check(snum)) {
1272                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1273                 return (uint32)-1;
1274         }
1275
1276         path = lp_pathname(snum);
1277
1278         /* see if we have sufficient disk space */
1279         if (lp_minprintspace(snum)) {
1280                 SMB_BIG_UINT dspace, dsize;
1281                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
1282                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
1283                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
1284                         errno = ENOSPC;
1285                         return (uint32)-1;
1286                 }
1287         }
1288
1289         /* for autoloaded printers, check that the printcap entry still exists */
1290         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
1291                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
1292                 errno = ENOENT;
1293                 return (uint32)-1;
1294         }
1295
1296         /* Insure the maximum queue size is not violated */
1297         if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
1298                 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n",
1299                         njobs, lp_maxprintjobs(snum) ));
1300                 errno = ENOSPC;
1301                 return (uint32)-1;
1302         }
1303
1304         /* Insure the maximum print jobs in the system is not violated */
1305         if (lp_totalprintjobs() && get_total_jobs() > lp_totalprintjobs()) {
1306                 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n",
1307                         njobs, lp_totalprintjobs() ));
1308                 errno = ENOSPC;
1309                 return (uint32)-1;
1310         }
1311
1312         /* create the database entry */
1313         ZERO_STRUCT(pjob);
1314         pjob.pid = local_pid;
1315         pjob.sysjob = -1;
1316         pjob.fd = -1;
1317         pjob.starttime = time(NULL);
1318         pjob.status = LPQ_SPOOLING;
1319         pjob.size = 0;
1320         pjob.spooled = False;
1321         pjob.smbjob = True;
1322
1323         fstrcpy(pjob.jobname, jobname);
1324
1325         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1326                 fstrcpy(pjob.user, vuser->user.smb_name);
1327         } else {
1328                 fstrcpy(pjob.user, uidtoname(user->uid));
1329         }
1330
1331         fstrcpy(pjob.queuename, lp_const_servicename(snum));
1332
1333         /* lock the database */
1334         tdb_lock_bystring(pdb->tdb, "INFO/nextjob");
1335
1336         next_jobid = tdb_fetch_int32(pdb->tdb, "INFO/nextjob");
1337         if (next_jobid == -1)
1338                 next_jobid = 1;
1339
1340         for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
1341                 if (!print_job_exists(snum, jobid))
1342                         break;
1343         }
1344         if (jobid == next_jobid || !pjob_store(snum, jobid, &pjob)) {
1345                 DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or pjob_store failed.\n",
1346                                 jobid, next_jobid ));
1347                 jobid = -1;
1348                 goto fail;
1349         }
1350
1351         if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1352                 DEBUG(3, ("print_job_start: failed to store INFO/nextjob.\n"));
1353                 jobid = -1;
1354                 goto fail;
1355         }
1356
1357         /* we have a job entry - now create the spool file */
1358         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
1359                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
1360         pjob.fd = smb_mkstemp(pjob.filename);
1361
1362         if (pjob.fd == -1) {
1363                 if (errno == EACCES) {
1364                         /* Common setup error, force a report. */
1365                         DEBUG(0, ("print_job_start: insufficient permissions \
1366 to open spool file %s.\n", pjob.filename));
1367                 } else {
1368                         /* Normal case, report at level 3 and above. */
1369                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
1370                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
1371                 }
1372                 goto fail;
1373         }
1374
1375         pjob_store(snum, jobid, &pjob);
1376
1377         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1378
1379         /*
1380          * If the printer is marked as postscript output a leading
1381          * file identifier to ensure the file is treated as a raw
1382          * postscript file.
1383          * This has a similar effect as CtrlD=0 in WIN.INI file.
1384          * tim@fsg.com 09/06/94
1385          */
1386         if (lp_postscript(snum)) {
1387                 print_job_write(snum, jobid, "%!\n",3);
1388         }
1389
1390         return jobid;
1391
1392  fail:
1393         if (jobid != -1)
1394                 pjob_delete(snum, jobid);
1395
1396         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1397
1398         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
1399         return -1;
1400 }
1401
1402 /****************************************************************************
1403  Update the number of pages spooled to jobid
1404 ****************************************************************************/
1405
1406 void print_job_endpage(int snum, uint32 jobid)
1407 {
1408         struct printjob *pjob = print_job_find(snum, jobid);
1409         if (!pjob)
1410                 return;
1411         /* don't allow another process to get this info - it is meaningless */
1412         if (pjob->pid != local_pid)
1413                 return;
1414
1415         pjob->page_count++;
1416         pjob_store(snum, jobid, pjob);
1417 }
1418
1419 /****************************************************************************
1420  Print a file - called on closing the file. This spools the job.
1421  If normal close is false then we're tearing down the jobs - treat as an
1422  error.
1423 ****************************************************************************/
1424
1425 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
1426 {
1427         struct printjob *pjob = print_job_find(snum, jobid);
1428         int ret;
1429         SMB_STRUCT_STAT sbuf;
1430
1431         if (!pjob)
1432                 return False;
1433
1434         if (pjob->spooled || pjob->pid != local_pid)
1435                 return False;
1436
1437         if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
1438                 pjob->size = sbuf.st_size;
1439                 close(pjob->fd);
1440                 pjob->fd = -1;
1441         } else {
1442
1443                 /* 
1444                  * Not a normal close or we couldn't stat the job file,
1445                  * so something has gone wrong. Cleanup.
1446                  */
1447                 close(pjob->fd);
1448                 pjob->fd = -1;
1449                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
1450                 goto fail;
1451         }
1452
1453         /* Technically, this is not quite right. If the printer has a separator
1454          * page turned on, the NT spooler prints the separator page even if the
1455          * print job is 0 bytes. 010215 JRR */
1456         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
1457                 /* don't bother spooling empty files or something being deleted. */
1458                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
1459                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
1460                 unlink(pjob->filename);
1461                 pjob_delete(snum, jobid);
1462                 return True;
1463         }
1464
1465         ret = (*(current_printif->job_submit))(snum, pjob);
1466
1467         if (ret)
1468                 goto fail;
1469
1470         /* The print job has been sucessfully handed over to the back-end */
1471         
1472         pjob->spooled = True;
1473         pjob->status = LPQ_QUEUED;
1474         pjob_store(snum, jobid, pjob);
1475         
1476         /* make sure the database is up to date */
1477         if (print_cache_expired(snum))
1478                 print_queue_update(snum);
1479         
1480         return True;
1481
1482 fail:
1483
1484         /* The print job was not succesfully started. Cleanup */
1485         /* Still need to add proper error return propagation! 010122:JRR */
1486         unlink(pjob->filename);
1487         pjob_delete(snum, jobid);
1488         return False;
1489 }
1490
1491 /****************************************************************************
1492  Utility fn to enumerate the print queue.
1493 ****************************************************************************/
1494
1495 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1496 {
1497         struct traverse_struct *ts = (struct traverse_struct *)state;
1498         struct printjob pjob;
1499         int i;
1500         uint32 jobid;
1501
1502         if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int))
1503                 return 0;
1504         memcpy(&jobid, key.dptr, sizeof(jobid));
1505         memcpy(&pjob,  data.dptr, sizeof(pjob));
1506
1507         /* maybe it isn't for this queue */
1508         if (ts->snum != lp_servicenumber(pjob.queuename))
1509                 return 0;
1510
1511         if (ts->qcount >= ts->maxcount)
1512                 return 0;
1513
1514         i = ts->qcount;
1515
1516         ts->queue[i].job = jobid;
1517         ts->queue[i].size = pjob.size;
1518         ts->queue[i].page_count = pjob.page_count;
1519         ts->queue[i].status = pjob.status;
1520         ts->queue[i].priority = 1;
1521         ts->queue[i].time = pjob.starttime;
1522         fstrcpy(ts->queue[i].fs_user, pjob.user);
1523         fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1524
1525         ts->qcount++;
1526
1527         return 0;
1528 }
1529
1530 struct traverse_count_struct {
1531         int snum, count;
1532 };
1533
1534 /****************************************************************************
1535  Utility fn to count the number of entries in the print queue.
1536 ****************************************************************************/
1537
1538 static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1539 {
1540         struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
1541         struct printjob pjob;
1542         uint32 jobid;
1543
1544         if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int))
1545                 return 0;
1546         memcpy(&jobid, key.dptr, sizeof(jobid));
1547         memcpy(&pjob,  data.dptr, sizeof(pjob));
1548
1549         /* maybe it isn't for this queue - this cannot happen with the tdb/printer code. JRA */
1550         if (ts->snum != lp_servicenumber(pjob.queuename))
1551                 return 0;
1552
1553         ts->count++;
1554
1555         return 0;
1556 }
1557
1558 /****************************************************************************
1559  Sort print jobs by submittal time.
1560 ****************************************************************************/
1561
1562 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1563 {
1564         /* Silly cases */
1565
1566         if (!j1 && !j2)
1567                 return 0;
1568         if (!j1)
1569                 return -1;
1570         if (!j2)
1571                 return 1;
1572
1573         /* Sort on job start time */
1574
1575         if (j1->time == j2->time)
1576                 return 0;
1577         return (j1->time > j2->time) ? 1 : -1;
1578 }
1579
1580 /****************************************************************************
1581  Get a printer queue listing.
1582 ****************************************************************************/
1583
1584 int print_queue_status(int snum, 
1585                        print_queue_struct **queue,
1586                        print_status_struct *status)
1587 {
1588         struct traverse_struct tstruct;
1589         struct traverse_count_struct tsc;
1590         fstring keystr;
1591         TDB_DATA data, key;
1592         const char *printername = lp_const_servicename(snum);
1593         struct tdb_print_db *pdb = get_print_db_byname(printername);
1594
1595         *queue = NULL;
1596         
1597         if (!pdb)
1598                 return 0;
1599
1600         /* make sure the database is up to date */
1601         if (print_cache_expired(snum))
1602                 print_queue_update(snum);
1603
1604         /*
1605          * Fetch the queue status.  We must do this first, as there may
1606          * be no jobs in the queue.
1607          */
1608         ZERO_STRUCTP(status);
1609         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1610         key.dptr = keystr;
1611         key.dsize = strlen(keystr);
1612         data = tdb_fetch(pdb->tdb, key);
1613         if (data.dptr) {
1614                 if (data.dsize == sizeof(*status)) {
1615                         memcpy(status, data.dptr, sizeof(*status));
1616                 }
1617                 SAFE_FREE(data.dptr);
1618         }
1619
1620         /*
1621          * Now, fetch the print queue information.  We first count the number
1622          * of entries, and then only retrieve the queue if necessary.
1623          */
1624         tsc.count = 0;
1625         tsc.snum = snum;
1626         
1627         tdb_traverse(pdb->tdb, traverse_count_fn_queue, (void *)&tsc);
1628
1629         if (tsc.count == 0)
1630                 return 0;
1631
1632         /* Allocate the queue size. */
1633         if ((tstruct.queue = (print_queue_struct *)
1634              malloc(sizeof(print_queue_struct)*tsc.count)) == NULL)
1635                 return 0;
1636
1637         /*
1638          * Fill in the queue.
1639          * We need maxcount as the queue size may have changed between
1640          * the two calls to tdb_traverse.
1641          */
1642         tstruct.qcount = 0;
1643         tstruct.maxcount = tsc.count;
1644         tstruct.snum = snum;
1645
1646         tdb_traverse(pdb->tdb, traverse_fn_queue, (void *)&tstruct);
1647
1648         /* Sort the queue by submission time otherwise they are displayed
1649            in hash order. */
1650
1651         qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
1652               QSORT_CAST(printjob_comp));
1653
1654         *queue = tstruct.queue;
1655         return tstruct.qcount;
1656 }
1657
1658 /****************************************************************************
1659  Turn a queue name into a snum.
1660 ****************************************************************************/
1661
1662 int print_queue_snum(const char *qname)
1663 {
1664         int snum = lp_servicenumber(qname);
1665         if (snum == -1 || !lp_print_ok(snum))
1666                 return -1;
1667         return snum;
1668 }
1669
1670 /****************************************************************************
1671  Pause a queue.
1672 ****************************************************************************/
1673
1674 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
1675 {
1676         int ret;
1677         
1678         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1679                 *errcode = WERR_ACCESS_DENIED;
1680                 return False;
1681         }
1682
1683         ret = (*(current_printif->queue_pause))(snum);
1684
1685         if (ret != 0) {
1686                 *errcode = WERR_INVALID_PARAM;
1687                 return False;
1688         }
1689
1690         /* force update the database */
1691         print_cache_flush(snum);
1692
1693         /* Send a printer notify message */
1694
1695         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
1696
1697         return True;
1698 }
1699
1700 /****************************************************************************
1701  Resume a queue.
1702 ****************************************************************************/
1703
1704 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
1705 {
1706         int ret;
1707
1708         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1709                 *errcode = WERR_ACCESS_DENIED;
1710                 return False;
1711         }
1712
1713         ret = (*(current_printif->queue_resume))(snum);
1714
1715         if (ret != 0) {
1716                 *errcode = WERR_INVALID_PARAM;
1717                 return False;
1718         }
1719
1720         /* make sure the database is up to date */
1721         if (print_cache_expired(snum))
1722                 print_queue_update(snum);
1723
1724         /* Send a printer notify message */
1725
1726         notify_printer_status(snum, PRINTER_STATUS_OK);
1727
1728         return True;
1729 }
1730
1731 /****************************************************************************
1732  Purge a queue - implemented by deleting all jobs that we can delete.
1733 ****************************************************************************/
1734
1735 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
1736 {
1737         print_queue_struct *queue;
1738         print_status_struct status;
1739         int njobs, i;
1740         BOOL can_job_admin;
1741
1742         /* Force and update so the count is accurate (i.e. not a cached count) */
1743         print_queue_update(snum);
1744         
1745         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
1746         njobs = print_queue_status(snum, &queue, &status);
1747
1748         for (i=0;i<njobs;i++) {
1749                 BOOL owner = is_owner(user, snum, queue[i].job);
1750
1751                 if (owner || can_job_admin) {
1752                         print_job_delete1(snum, queue[i].job);
1753                 }
1754         }
1755
1756         SAFE_FREE(queue);
1757
1758         return True;
1759 }