First cut of fix for changenotify on a print server handle. Use the connections tdb
[kai/samba.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 /* There can be this many printing tdb's open, plus any locked ones. */
136 #define MAX_PRINT_DBS_OPEN 1
137
138 struct tdb_print_db {
139         struct tdb_print_db *next, *prev;
140         TDB_CONTEXT *tdb;
141         int ref_count;
142         fstring printer_name;
143 };
144
145 static struct tdb_print_db *print_db_head;
146
147 /****************************************************************************
148   Function to find or create the printer specific job tdb given a printername.
149   Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
150 ****************************************************************************/
151
152 static struct tdb_print_db *get_print_db_byname(const char *printername)
153 {
154         struct tdb_print_db *p = NULL, *last_entry = NULL;
155         int num_open = 0;
156         pstring printdb_path;
157         BOOL done_become_root = False;
158
159         for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
160                 /* Ensure the list terminates... JRA. */
161                 SMB_ASSERT(p->next != print_db_head);
162
163                 if (p->tdb && strequal(p->printer_name, printername)) {
164                         DLIST_PROMOTE(print_db_head, p);
165                         p->ref_count++;
166                         return p;
167                 }
168                 num_open++;
169                 last_entry = p;
170         }
171
172         /* Not found. */
173         if (num_open >= MAX_PRINT_DBS_OPEN) {
174                 /* Try and recycle the last entry. */
175                 DLIST_PROMOTE(print_db_head, last_entry);
176
177                 for (p = print_db_head; p; p = p->next) {
178                         if (p->ref_count)
179                                 continue;
180                         if (p->tdb) {
181                                 if (tdb_close(print_db_head->tdb)) {
182                                         DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
183                                                                 print_db_head->printer_name ));
184                                         return NULL;
185                                 }
186                         }
187                         p->tdb = NULL;
188                         p->ref_count = 0;
189                         memset(p->printer_name, '\0', sizeof(p->printer_name));
190                         break;
191                 }
192                 if (p) {
193                         DLIST_PROMOTE(print_db_head, p);
194                         p = print_db_head;
195                 }
196         }
197        
198         if (!p) {
199                 /* Create one. */
200                 p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
201                 if (!p) {
202                         DEBUG(0,("get_print_db: malloc fail !\n"));
203                         return NULL;
204                 }
205                 ZERO_STRUCTP(p);
206                 DLIST_ADD(print_db_head, p);
207         }
208
209         pstrcpy(printdb_path, lock_path("printing/"));
210         pstrcat(printdb_path, printername);
211         pstrcat(printdb_path, ".tdb");
212
213         if (geteuid() != 0) {
214                 become_root();
215                 done_become_root = True;
216         }
217
218         p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
219
220         if (done_become_root)
221                 unbecome_root();
222
223         if (!p->tdb) {
224                 DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
225                                         printdb_path ));
226                 DLIST_REMOVE(print_db_head, p);
227                 SAFE_FREE(p);
228                 return NULL;
229         }
230         fstrcpy(p->printer_name, printername);
231         p->ref_count++;
232         return p;
233 }
234
235 /***************************************************************************
236  Remove a reference count.
237 ****************************************************************************/
238
239 static void release_print_db( struct tdb_print_db *pdb)
240 {
241         pdb->ref_count--;
242         SMB_ASSERT(pdb->ref_count >= 0);
243 }
244
245 /***************************************************************************
246  Close all open print db entries.
247 ****************************************************************************/
248
249 static void close_all_print_db(void)
250 {
251         struct tdb_print_db *p = NULL, *next_p = NULL;
252
253         for (p = print_db_head; p; p = next_p) {
254                 next_p = p->next;
255
256                 if (p->tdb)
257                         tdb_close(p->tdb);
258                 DLIST_REMOVE(print_db_head, p);
259                 ZERO_STRUCTP(p);
260                 SAFE_FREE(p);
261         }
262 }
263
264 /****************************************************************************
265  Initialise the printing backend. Called once at startup before the fork().
266 ****************************************************************************/
267
268 BOOL print_backend_init(void)
269 {
270         char *sversion = "INFO/version";
271         pstring printing_path;
272         int services = lp_numservices();
273         int snum;
274
275         if (local_pid == sys_getpid())
276                 return True;
277
278         unlink(lock_path("printing.tdb"));
279         pstrcpy(printing_path,lock_path("printing"));
280         mkdir(printing_path,0755);
281
282         local_pid = sys_getpid();
283
284         /* handle a Samba upgrade */
285
286         for (snum = 0; snum < services; snum++) {
287                 struct tdb_print_db *pdb;
288                 if (!lp_print_ok(snum))
289                         continue;
290
291                 pdb = get_print_db_byname(lp_const_servicename(snum));
292                 if (!pdb)
293                         continue;
294                 if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
295                         DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
296                         release_print_db(pdb);
297                         return False;
298                 }
299                 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
300                         tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
301                         tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
302                 }
303                 tdb_unlock_bystring(pdb->tdb, sversion);
304                 release_print_db(pdb);
305         }
306
307         close_all_print_db(); /* Don't leave any open. */
308
309         /* select the appropriate printing interface... */
310 #ifdef HAVE_CUPS
311         if (strcmp(lp_printcapname(), "cups") == 0)
312                 current_printif = &cups_printif;
313 #endif /* HAVE_CUPS */
314
315         /* do NT print initialization... */
316         return nt_printing_init();
317 }
318
319 /****************************************************************************
320  Shut down printing backend. Called once at shutdown to close the tdb.
321 ****************************************************************************/
322
323 void printing_end(void)
324 {
325         close_all_print_db(); /* Don't leave any open. */
326 }
327
328 /****************************************************************************
329  Useful function to generate a tdb key.
330 ****************************************************************************/
331
332 static TDB_DATA print_key(uint32 jobid)
333 {
334         static uint32 j;
335         TDB_DATA ret;
336
337         j = jobid;
338         ret.dptr = (void *)&j;
339         ret.dsize = sizeof(j);
340         return ret;
341 }
342
343 /***********************************************************************
344  unpack a pjob from a tdb buffer 
345 ***********************************************************************/
346  
347 int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
348 {
349         int     len = 0;
350         int     used;
351         
352         if ( !buf || !pjob )
353                 return -1;
354                 
355         len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
356                                 &pjob->pid,
357                                 &pjob->sysjob,
358                                 &pjob->fd,
359                                 &pjob->starttime,
360                                 &pjob->status,
361                                 &pjob->size,
362                                 &pjob->page_count,
363                                 &pjob->spooled,
364                                 &pjob->smbjob,
365                                 pjob->filename,
366                                 pjob->jobname,
367                                 pjob->user,
368                                 pjob->queuename);
369                                 
370         if ( len == -1 )
371                 return -1;
372                 
373         if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
374                 return -1;
375         
376         len += used;
377         
378         return len;
379
380 }
381
382 /****************************************************************************
383  Useful function to find a print job in the database.
384 ****************************************************************************/
385
386 static struct printjob *print_job_find(int snum, uint32 jobid)
387 {
388         static struct printjob  pjob;
389         TDB_DATA                ret;
390         struct tdb_print_db     *pdb = get_print_db_byname(lp_const_servicename(snum));
391         
392
393         if (!pdb)
394                 return NULL;
395
396         ret = tdb_fetch(pdb->tdb, print_key(jobid));
397         release_print_db(pdb);
398
399         if (!ret.dptr)
400                 return NULL;
401         
402         if ( pjob.nt_devmode )
403                 free_nt_devicemode( &pjob.nt_devmode );
404                 
405         ZERO_STRUCT( pjob );
406         
407         if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 )
408                 return NULL;
409         
410         SAFE_FREE(ret.dptr);    
411         return &pjob;
412 }
413
414 /* Convert a unix jobid to a smb jobid */
415
416 static uint32 sysjob_to_jobid_value;
417
418 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
419                                TDB_DATA data, void *state)
420 {
421         struct printjob *pjob;
422         int *sysjob = (int *)state;
423
424         if (!data.dptr || data.dsize == 0)
425                 return 0;
426
427         pjob = (struct printjob *)data.dptr;
428         if (key.dsize != sizeof(uint32))
429                 return 0;
430
431         if (*sysjob == pjob->sysjob) {
432                 uint32 *jobid = (uint32 *)key.dptr;
433
434                 sysjob_to_jobid_value = *jobid;
435                 return 1;
436         }
437
438         return 0;
439 }
440
441 /****************************************************************************
442  This is a *horribly expensive call as we have to iterate through all the
443  current printer tdb's. Don't do this often ! JRA.
444 ****************************************************************************/
445
446 uint32 sysjob_to_jobid(int unix_jobid)
447 {
448         int services = lp_numservices();
449         int snum;
450
451         sysjob_to_jobid_value = (uint32)-1;
452
453         for (snum = 0; snum < services; snum++) {
454                 struct tdb_print_db *pdb;
455                 if (!lp_print_ok(snum))
456                         continue;
457                 pdb = get_print_db_byname(lp_const_servicename(snum));
458                 if (pdb)
459                         tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
460                 release_print_db(pdb);
461                 if (sysjob_to_jobid_value != (uint32)-1)
462                         return sysjob_to_jobid_value;
463         }
464         return (uint32)-1;
465 }
466
467 /****************************************************************************
468  Send notifications based on what has changed after a pjob_store.
469 ****************************************************************************/
470
471 static struct {
472         uint32 lpq_status;
473         uint32 spoolss_status;
474 } lpq_to_spoolss_status_map[] = {
475         { LPQ_QUEUED, JOB_STATUS_QUEUED },
476         { LPQ_PAUSED, JOB_STATUS_PAUSED },
477         { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
478         { LPQ_PRINTING, JOB_STATUS_PRINTING },
479         { LPQ_DELETING, JOB_STATUS_DELETING },
480         { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
481         { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
482         { LPQ_PRINTED, JOB_STATUS_PRINTED },
483         { LPQ_DELETED, JOB_STATUS_DELETED },
484         { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
485         { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
486         { -1, 0 }
487 };
488
489 /* Convert a lpq status value stored in printing.tdb into the
490    appropriate win32 API constant. */
491
492 static uint32 map_to_spoolss_status(uint32 lpq_status)
493 {
494         int i = 0;
495
496         while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
497                 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
498                         return lpq_to_spoolss_status_map[i].spoolss_status;
499                 i++;
500         }
501
502         return 0;
503 }
504
505 static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
506                               struct printjob *new_data)
507 {
508         BOOL new_job = False;
509
510         if (!old_data)
511                 new_job = True;
512
513         /* Notify the job name first */
514
515         if (new_job || !strequal(old_data->jobname, new_data->jobname))
516                 notify_job_name(snum, jobid, new_data->jobname);
517
518         /* Job attributes that can't be changed.  We only send
519            notification for these on a new job. */
520
521         if (new_job) {
522                 notify_job_submitted(snum, jobid, new_data->starttime);
523                 notify_job_username(snum, jobid, new_data->user);
524         }
525
526         /* Job attributes of a new job or attributes that can be
527            modified. */
528
529         if (new_job || old_data->status != new_data->status)
530                 notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
531
532         if (new_job || old_data->size != new_data->size)
533                 notify_job_total_bytes(snum, jobid, new_data->size);
534
535         if (new_job || old_data->page_count != new_data->page_count)
536                 notify_job_total_pages(snum, jobid, new_data->page_count);
537 }
538
539 /****************************************************************************
540  Store a job structure back to the database.
541 ****************************************************************************/
542
543 static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
544 {
545         TDB_DATA                old_data, new_data;
546         BOOL                    ret = False;
547         struct tdb_print_db     *pdb = get_print_db_byname(lp_const_servicename(snum));
548         char                    *buf = NULL;
549         int                     len, newlen, buflen;
550         
551
552         if (!pdb)
553                 return False;
554
555         /* Get old data */
556
557         old_data = tdb_fetch(pdb->tdb, print_key(jobid));
558
559         /* Doh!  Now we have to pack/unpack data since the NT_DEVICEMODE was added */
560
561         newlen = 0;
562         
563         do {
564                 len = 0;
565                 buflen = newlen;
566                 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
567                                 pjob->pid,
568                                 pjob->sysjob,
569                                 pjob->fd,
570                                 pjob->starttime,
571                                 pjob->status,
572                                 pjob->size,
573                                 pjob->page_count,
574                                 pjob->spooled,
575                                 pjob->smbjob,
576                                 pjob->filename,
577                                 pjob->jobname,
578                                 pjob->user,
579                                 pjob->queuename);
580
581                 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
582         
583                 if (buflen != len) 
584                 {
585                         char *tb;
586
587                         tb = (char *)Realloc(buf, len);
588                         if (!tb) {
589                                 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
590                                 goto done;
591                         }
592                         else 
593                                 buf = tb;
594                         newlen = len;
595                 }
596         }
597         while ( buflen != len );
598                 
599         
600         /* Store new data */
601
602         new_data.dptr = buf;
603         new_data.dsize = len;
604         ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
605
606         release_print_db(pdb);
607
608         /* Send notify updates for what has changed */
609
610         if ( ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) )
611                 pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob );
612
613 done:
614         SAFE_FREE( old_data.dptr );
615         SAFE_FREE( buf );
616
617         return ret;
618 }
619
620 /****************************************************************************
621  Remove a job structure from the database.
622 ****************************************************************************/
623
624 static void pjob_delete(int snum, uint32 jobid)
625 {
626         struct printjob *pjob = print_job_find(snum, jobid);
627         uint32 job_status = 0;
628         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
629
630         if (!pdb)
631                 return;
632
633         if (!pjob) {
634                 DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
635                                         (unsigned int)jobid));
636                 release_print_db(pdb);
637                 return;
638         }
639
640         /* Send a notification that a job has been deleted */
641
642         job_status = map_to_spoolss_status(pjob->status);
643
644         /* We must cycle through JOB_STATUS_DELETING and
645            JOB_STATUS_DELETED for the port monitor to delete the job
646            properly. */
647         
648         job_status |= JOB_STATUS_DELETING;
649         notify_job_status(snum, jobid, job_status);
650         
651         job_status |= JOB_STATUS_DELETED;
652         notify_job_status(snum, jobid, job_status);
653
654         /* Remove from printing.tdb */
655
656         tdb_delete(pdb->tdb, print_key(jobid));
657         release_print_db(pdb);
658         rap_jobid_delete(snum, jobid);
659 }
660
661 /****************************************************************************
662  Parse a file name from the system spooler to generate a jobid.
663 ****************************************************************************/
664
665 static uint32 print_parse_jobid(char *fname)
666 {
667         int jobid;
668
669         if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
670                 return (uint32)-1;
671         fname += strlen(PRINT_SPOOL_PREFIX);
672
673         jobid = atoi(fname);
674         if (jobid <= 0)
675                 return (uint32)-1;
676
677         return (uint32)jobid;
678 }
679
680 /****************************************************************************
681  List a unix job in the print database.
682 ****************************************************************************/
683
684 static void print_unix_job(int snum, print_queue_struct *q)
685 {
686         uint32 jobid = q->job + UNIX_JOB_START;
687         struct printjob pj, *old_pj;
688
689         /* Preserve the timestamp on an existing unix print job */
690
691         old_pj = print_job_find(snum, jobid);
692
693         ZERO_STRUCT(pj);
694
695         pj.pid = (pid_t)-1;
696         pj.sysjob = q->job;
697         pj.fd = -1;
698         pj.starttime = old_pj ? old_pj->starttime : q->time;
699         pj.status = q->status;
700         pj.size = q->size;
701         pj.spooled = True;
702         pj.smbjob = False;
703         fstrcpy(pj.filename, "");
704         fstrcpy(pj.jobname, q->fs_file);
705         fstrcpy(pj.user, q->fs_user);
706         fstrcpy(pj.queuename, lp_const_servicename(snum));
707
708         pjob_store(snum, jobid, &pj);
709 }
710
711
712 struct traverse_struct {
713         print_queue_struct *queue;
714         int qcount, snum, maxcount, total_jobs;
715 };
716
717 /****************************************************************************
718  Utility fn to delete any jobs that are no longer active.
719 ****************************************************************************/
720
721 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
722 {
723         struct traverse_struct *ts = (struct traverse_struct *)state;
724         struct printjob pjob;
725         uint32 jobid;
726         int i;
727
728         if (  key.dsize != sizeof(jobid) )
729                 return 0;
730                 
731         memcpy(&jobid, key.dptr, sizeof(jobid));
732         if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
733                 return 0;
734         free_nt_devicemode( &pjob.nt_devmode );
735
736
737         if (ts->snum != lp_servicenumber(pjob.queuename)) {
738                 /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
739                 return 0;
740         }
741
742         if (!pjob.smbjob) {
743                 /* remove a unix job if it isn't in the system queue any more */
744
745                 for (i=0;i<ts->qcount;i++) {
746                         uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
747                         if (jobid == u_jobid)
748                                 break;
749                 }
750                 if (i == ts->qcount)
751                         pjob_delete(ts->snum, jobid);
752                 else
753                         ts->total_jobs++;
754                 return 0;
755         }
756
757         /* maybe it hasn't been spooled yet */
758         if (!pjob.spooled) {
759                 /* if a job is not spooled and the process doesn't
760                    exist then kill it. This cleans up after smbd
761                    deaths */
762                 if (!process_exists(pjob.pid))
763                         pjob_delete(ts->snum, jobid);
764                 else
765                         ts->total_jobs++;
766                 return 0;
767         }
768
769         for (i=0;i<ts->qcount;i++) {
770                 uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
771                 if (jobid == curr_jobid)
772                         break;
773         }
774         
775         /* The job isn't in the system queue - we have to assume it has
776            completed, so delete the database entry. */
777
778         if (i == ts->qcount) {
779                 time_t cur_t = time(NULL);
780
781                 /* A race can occur between the time a job is spooled and
782                    when it appears in the lpq output.  This happens when
783                    the job is added to printing.tdb when another smbd
784                    running print_queue_update() has completed a lpq and
785                    is currently traversing the printing tdb and deleting jobs.
786                    A workaround is to not delete the job if it has been 
787                    submitted less than lp_lpqcachetime() seconds ago. */
788
789                 if ((cur_t - pjob.starttime) > lp_lpqcachetime())
790                         pjob_delete(ts->snum, jobid);
791                 else
792                         ts->total_jobs++;
793         }
794         else
795                 ts->total_jobs++;
796
797         return 0;
798 }
799
800 /****************************************************************************
801  Check if the print queue has been updated recently enough.
802 ****************************************************************************/
803
804 static void print_cache_flush(int snum)
805 {
806         fstring key;
807         const char *printername = lp_const_servicename(snum);
808         struct tdb_print_db *pdb = get_print_db_byname(printername);
809
810         if (!pdb)
811                 return;
812         slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
813         tdb_store_int32(pdb->tdb, key, -1);
814         release_print_db(pdb);
815 }
816
817 /****************************************************************************
818  Check if someone already thinks they are doing the update.
819 ****************************************************************************/
820
821 static pid_t get_updating_pid(fstring printer_name)
822 {
823         fstring keystr;
824         TDB_DATA data, key;
825         pid_t updating_pid;
826         struct tdb_print_db *pdb = get_print_db_byname(printer_name);
827
828         if (!pdb)
829                 return (pid_t)-1;
830         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
831         key.dptr = keystr;
832         key.dsize = strlen(keystr);
833
834         data = tdb_fetch(pdb->tdb, key);
835         release_print_db(pdb);
836         if (!data.dptr || data.dsize != sizeof(pid_t))
837                 return (pid_t)-1;
838
839         memcpy(&updating_pid, data.dptr, sizeof(pid_t));
840         SAFE_FREE(data.dptr);
841
842         if (process_exists(updating_pid))
843                 return updating_pid;
844
845         return (pid_t)-1;
846 }
847
848 /****************************************************************************
849  Set the fact that we're doing the update, or have finished doing the update
850  in the tdb.
851 ****************************************************************************/
852
853 static void set_updating_pid(const fstring printer_name, BOOL delete)
854 {
855         fstring keystr;
856         TDB_DATA key;
857         TDB_DATA data;
858         pid_t updating_pid = sys_getpid();
859         struct tdb_print_db *pdb = get_print_db_byname(printer_name);
860
861         if (!pdb)
862                 return;
863
864         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
865         key.dptr = keystr;
866         key.dsize = strlen(keystr);
867
868         if (delete) {
869                 tdb_delete(pdb->tdb, key);
870                 release_print_db(pdb);
871                 return;
872         }
873         
874         data.dptr = (void *)&updating_pid;
875         data.dsize = sizeof(pid_t);
876
877         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
878         release_print_db(pdb);
879 }
880
881 /****************************************************************************
882  Update the internal database from the system print queue for a queue.
883 ****************************************************************************/
884
885 static void print_queue_update(int snum)
886 {
887         int i, qcount;
888         print_queue_struct *queue = NULL;
889         print_status_struct status;
890         print_status_struct old_status;
891         struct printjob *pjob;
892         struct traverse_struct tstruct;
893         fstring keystr, printer_name, cachestr;
894         TDB_DATA data, key;
895         struct tdb_print_db *pdb;
896
897         fstrcpy(printer_name, lp_const_servicename(snum));
898         pdb = get_print_db_byname(printer_name);
899         if (!pdb)
900                 return;
901
902         /*
903          * Check to see if someone else is doing this update.
904          * This is essentially a mutex on the update.
905          */
906
907         if (get_updating_pid(printer_name) != -1) {
908                 release_print_db(pdb);
909                 return;
910         }
911
912         /* Lock the queue for the database update */
913
914         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
915         /* Only wait 10 seconds for this. */
916         if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
917                 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
918                 release_print_db(pdb);
919                 return;
920         }
921
922         /*
923          * Ensure that no one else got in here.
924          * If the updating pid is still -1 then we are
925          * the winner.
926          */
927
928         if (get_updating_pid(printer_name) != -1) {
929                 /*
930                  * Someone else is doing the update, exit.
931                  */
932                 tdb_unlock_bystring(pdb->tdb, keystr);
933                 release_print_db(pdb);
934                 return;
935         }
936
937         /*
938          * We're going to do the update ourselves.
939          */
940
941         /* Tell others we're doing the update. */
942         set_updating_pid(printer_name, False);
943
944         /*
945          * Allow others to enter and notice we're doing
946          * the update.
947          */
948
949         tdb_unlock_bystring(pdb->tdb, keystr);
950
951         /*
952          * Update the cache time FIRST ! Stops others even
953          * attempting to get the lock and doing this
954          * if the lpq takes a long time.
955          */
956
957         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
958         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
959
960         /* get the current queue using the appropriate interface */
961         ZERO_STRUCT(status);
962
963         qcount = (*(current_printif->queue_get))(snum, &queue, &status);
964
965         DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
966                 "s" : "", printer_name));
967
968         /*
969           any job in the internal database that is marked as spooled
970           and doesn't exist in the system queue is considered finished
971           and removed from the database
972
973           any job in the system database but not in the internal database 
974           is added as a unix job
975
976           fill in any system job numbers as we go
977         */
978         for (i=0; i<qcount; i++) {
979                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
980
981                 if (jobid == (uint32)-1) {
982                         /* assume its a unix print job */
983                         print_unix_job(snum, &queue[i]);
984                         continue;
985                 }
986
987                 /* we have an active SMB print job - update its status */
988                 pjob = print_job_find(snum, jobid);
989                 if (!pjob) {
990                         /* err, somethings wrong. Probably smbd was restarted
991                            with jobs in the queue. All we can do is treat them
992                            like unix jobs. Pity. */
993                         print_unix_job(snum, &queue[i]);
994                         continue;
995                 }
996
997                 pjob->sysjob = queue[i].job;
998                 pjob->status = queue[i].status;
999
1000                 pjob_store(snum, jobid, pjob);
1001         }
1002
1003         /* now delete any queued entries that don't appear in the
1004            system queue */
1005         tstruct.queue = queue;
1006         tstruct.qcount = qcount;
1007         tstruct.snum = snum;
1008         tstruct.total_jobs = 0;
1009
1010         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1011
1012         SAFE_FREE(tstruct.queue);
1013
1014         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1015
1016         if( qcount != get_queue_status(snum, &old_status))
1017                 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1018                                         old_status.qcount, qcount, printer_name ));
1019
1020         /* store the new queue status structure */
1021         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
1022         key.dptr = keystr;
1023         key.dsize = strlen(keystr);
1024
1025         status.qcount = qcount;
1026         data.dptr = (void *)&status;
1027         data.dsize = sizeof(status);
1028         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
1029
1030         /*
1031          * Update the cache time again. We want to do this call
1032          * as little as possible...
1033          */
1034
1035         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
1036         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1037
1038         /* Delete our pid from the db. */
1039         set_updating_pid(printer_name, True);
1040         release_print_db(pdb);
1041 }
1042
1043 /****************************************************************************
1044  Fetch and clean the pid_t record list for all pids interested in notify
1045  messages. data needs freeing on exit.
1046 ****************************************************************************/
1047
1048 #define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST"
1049 #define PRINT_SERVER_ENTRY_NAME "___PRINT_SERVER_ENTRY___"
1050
1051 static TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
1052 {
1053         TDB_DATA data;
1054         size_t i;
1055
1056         ZERO_STRUCT(data);
1057
1058         data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY );
1059
1060         if (!data.dptr) {
1061                 ZERO_STRUCT(data);
1062                 return data;
1063         }
1064
1065         if (data.dsize % 8) {
1066                 DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
1067                 tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY );
1068                 ZERO_STRUCT(data);
1069                 return data;
1070         }
1071
1072         if (!cleanlist)
1073                 return data;
1074
1075         /*
1076          * Weed out all dead entries.
1077          */
1078
1079         for( i = 0; i < data.dsize; i += 8) {
1080                 pid_t pid = (pid_t)IVAL(data.dptr, i);
1081
1082                 if (pid == sys_getpid())
1083                         continue;
1084
1085                 /* Entry is dead if process doesn't exist or refcount is zero. */
1086
1087                 while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) {
1088
1089                         /* Refcount == zero is a logic error and should never happen. */
1090                         if (IVAL(data.dptr, i + 4) == 0) {
1091                                 DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
1092                                                         (unsigned int)pid, printer_name ));
1093                         }
1094
1095                         if (data.dsize - i > 8)
1096                                 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1097                         data.dsize -= 8;
1098                 }
1099         }
1100
1101         return data;
1102 }
1103
1104 /****************************************************************************
1105  Return a malloced list of pid_t's that are interested in getting update
1106  messages on this print queue. Used in printing/notify to send the messages.
1107 ****************************************************************************/
1108
1109 BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list)
1110 {
1111         struct tdb_print_db *pdb = NULL;
1112         TDB_CONTEXT *tdb = NULL;
1113         TDB_DATA data;
1114         BOOL ret = True;
1115         size_t i, num_pids, offset;
1116         pid_t *pid_list;
1117
1118         *p_num_pids = 0;
1119         *pp_pid_list = NULL;
1120
1121         if (strequal(printername, PRINT_SERVER_ENTRY_NAME)) {
1122                 pdb = NULL;
1123                 tdb = conn_tdb_ctx();
1124         } else {
1125                 pdb = get_print_db_byname(printername);
1126                 if (!pdb)
1127                         return False;
1128                 tdb = pdb->tdb;
1129         }
1130
1131         if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1132                 DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n",
1133                                         printername));
1134                 if (pdb)
1135                         release_print_db(pdb);
1136                 return False;
1137         }
1138
1139         data = get_printer_notify_pid_list( tdb, printername, True );
1140
1141         if (!data.dptr) {
1142                 ret = True;
1143                 goto done;
1144         }
1145
1146         num_pids = data.dsize / 8;
1147
1148         if ((pid_list = (pid_t *)talloc(mem_ctx, sizeof(pid_t) * num_pids)) == NULL) {
1149                 ret = False;
1150                 goto done;
1151         }
1152
1153         for( i = 0, offset = 0; offset < data.dsize; offset += 8, i++)
1154                 pid_list[i] = (pid_t)IVAL(data.dptr, offset);
1155
1156         *pp_pid_list = pid_list;
1157         *p_num_pids = num_pids;
1158
1159         ret = True;
1160
1161   done:
1162
1163         tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1164         if (pdb)
1165                 release_print_db(pdb);
1166         SAFE_FREE(data.dptr);
1167         return ret;
1168 }
1169
1170 /****************************************************************************
1171  Create/Update an entry in the print tdb that will allow us to send notify
1172  updates only to interested smbd's. 
1173 ****************************************************************************/
1174
1175 BOOL print_notify_register_pid(int snum)
1176 {
1177         TDB_DATA data;
1178         struct tdb_print_db *pdb = NULL;
1179         TDB_CONTEXT *tdb = NULL;
1180         const char *printername;
1181         uint32 mypid = (uint32)sys_getpid();
1182         BOOL ret = False;
1183         size_t i;
1184
1185         if (snum != -1) {
1186                 printername = lp_const_servicename(snum);
1187                 pdb = get_print_db_byname(printername);
1188                 if (!pdb)
1189                         return False;
1190                 tdb = pdb->tdb;
1191         } else {
1192                 printername = PRINT_SERVER_ENTRY_NAME;
1193                 pdb = NULL;
1194                 tdb = conn_tdb_ctx();
1195         }
1196
1197         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1198                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1199                                         printername));
1200                 if (pdb)
1201                         release_print_db(pdb);
1202                 return False;
1203         }
1204
1205         data = get_printer_notify_pid_list( tdb, printername, True );
1206
1207         /* Add ourselves and increase the refcount. */
1208
1209         for (i = 0; i < data.dsize; i += 8) {
1210                 if (IVAL(data.dptr,i) == mypid) {
1211                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1212                         SIVAL(data.dptr, i+4, new_refcount);
1213                         break;
1214                 }
1215         }
1216
1217         if (i == data.dsize) {
1218                 /* We weren't in the list. Realloc. */
1219                 data.dptr = Realloc(data.dptr, data.dsize + 8);
1220                 if (!data.dptr) {
1221                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1222                                                 printername));
1223                         goto done;
1224                 }
1225                 data.dsize += 8;
1226                 SIVAL(data.dptr,data.dsize - 8,mypid);
1227                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1228         }
1229
1230         /* Store back the record. */
1231         if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1232                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1233 list for printer %s\n", printername));
1234                 goto done;
1235         }
1236
1237         ret = True;
1238
1239  done:
1240
1241         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1242         if (pdb)
1243                 release_print_db(pdb);
1244         SAFE_FREE(data.dptr);
1245         return ret;
1246 }
1247
1248 /****************************************************************************
1249  Update an entry in the print tdb that will allow us to send notify
1250  updates only to interested smbd's. 
1251 ****************************************************************************/
1252
1253 BOOL print_notify_deregister_pid(int snum)
1254 {
1255         TDB_DATA data;
1256         struct tdb_print_db *pdb = NULL;
1257         TDB_CONTEXT *tdb = NULL;
1258         const char *printername;
1259         uint32 mypid = (uint32)sys_getpid();
1260         size_t i;
1261         BOOL ret = False;
1262
1263         if (snum != -1) {
1264                 printername = lp_const_servicename(snum);
1265                 pdb = get_print_db_byname(printername);
1266                 if (!pdb)
1267                         return False;
1268                 tdb = pdb->tdb;
1269         } else {
1270                 printername = PRINT_SERVER_ENTRY_NAME;
1271                 pdb = NULL;
1272                 tdb = conn_tdb_ctx();
1273         }
1274
1275         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1276                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1277 printer %s database\n", printername));
1278                 if (pdb)
1279                         release_print_db(pdb);
1280                 return False;
1281         }
1282
1283         data = get_printer_notify_pid_list( tdb, printername, True );
1284
1285         /* Reduce refcount. Remove ourselves if zero. */
1286
1287         for (i = 0; i < data.dsize; ) {
1288                 if (IVAL(data.dptr,i) == mypid) {
1289                         uint32 refcount = IVAL(data.dptr, i+4);
1290
1291                         refcount--;
1292
1293                         if (refcount == 0) {
1294                                 if (data.dsize - i > 8)
1295                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1296                                 data.dsize -= 8;
1297                                 continue;
1298                         }
1299                         SIVAL(data.dptr, i+4, refcount);
1300                 }
1301
1302                 i += 8;
1303         }
1304
1305         if (data.dsize == 0)
1306                 SAFE_FREE(data.dptr);
1307
1308         /* Store back the record. */
1309         if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1310                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1311 list for printer %s\n", printername));
1312                 goto done;
1313         }
1314
1315         ret = True;
1316
1317   done:
1318
1319         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1320         if (pdb)
1321                 release_print_db(pdb);
1322         SAFE_FREE(data.dptr);
1323         return ret;
1324 }
1325
1326 /****************************************************************************
1327  Check if a jobid is valid. It is valid if it exists in the database.
1328 ****************************************************************************/
1329
1330 BOOL print_job_exists(int snum, uint32 jobid)
1331 {
1332         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1333         BOOL ret;
1334
1335         if (!pdb)
1336                 return False;
1337         ret = tdb_exists(pdb->tdb, print_key(jobid));
1338         release_print_db(pdb);
1339         return ret;
1340 }
1341
1342 /****************************************************************************
1343  Give the fd used for a jobid.
1344 ****************************************************************************/
1345
1346 int print_job_fd(int snum, uint32 jobid)
1347 {
1348         struct printjob *pjob = print_job_find(snum, jobid);
1349         if (!pjob)
1350                 return -1;
1351         /* don't allow another process to get this info - it is meaningless */
1352         if (pjob->pid != local_pid)
1353                 return -1;
1354         return pjob->fd;
1355 }
1356
1357 /****************************************************************************
1358  Give the filename used for a jobid.
1359  Only valid for the process doing the spooling and when the job
1360  has not been spooled.
1361 ****************************************************************************/
1362
1363 char *print_job_fname(int snum, uint32 jobid)
1364 {
1365         struct printjob *pjob = print_job_find(snum, jobid);
1366         if (!pjob || pjob->spooled || pjob->pid != local_pid)
1367                 return NULL;
1368         return pjob->filename;
1369 }
1370
1371
1372 /****************************************************************************
1373  Give the filename used for a jobid.
1374  Only valid for the process doing the spooling and when the job
1375  has not been spooled.
1376 ****************************************************************************/
1377
1378 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1379 {
1380         struct printjob *pjob = print_job_find(snum, jobid);
1381         
1382         if ( !pjob )
1383                 return NULL;
1384                 
1385         return pjob->nt_devmode;
1386 }
1387
1388 /****************************************************************************
1389  Set the place in the queue for a job.
1390 ****************************************************************************/
1391
1392 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1393 {
1394         DEBUG(2,("print_job_set_place not implemented yet\n"));
1395         return False;
1396 }
1397
1398 /****************************************************************************
1399  Set the name of a job. Only possible for owner.
1400 ****************************************************************************/
1401
1402 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1403 {
1404         struct printjob *pjob = print_job_find(snum, jobid);
1405         if (!pjob || pjob->pid != local_pid)
1406                 return False;
1407
1408         fstrcpy(pjob->jobname, name);
1409         return pjob_store(snum, jobid, pjob);
1410 }
1411
1412 /****************************************************************************
1413  Delete a print job - don't update queue.
1414 ****************************************************************************/
1415
1416 static BOOL print_job_delete1(int snum, uint32 jobid)
1417 {
1418         struct printjob *pjob = print_job_find(snum, jobid);
1419         int result = 0;
1420
1421         if (!pjob)
1422                 return False;
1423
1424         /*
1425          * If already deleting just return.
1426          */
1427
1428         if (pjob->status == LPQ_DELETING)
1429                 return True;
1430
1431         /* Hrm - we need to be able to cope with deleting a job before it
1432            has reached the spooler. */
1433
1434         if (pjob->sysjob == -1) {
1435                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1436         }
1437
1438         /* Set the tdb entry to be deleting. */
1439
1440         pjob->status = LPQ_DELETING;
1441         pjob_store(snum, jobid, pjob);
1442
1443         if (pjob->spooled && pjob->sysjob != -1)
1444                 result = (*(current_printif->job_delete))(snum, pjob);
1445
1446         /* Delete the tdb entry if the delete suceeded or the job hasn't
1447            been spooled. */
1448
1449         if (result == 0)
1450                 pjob_delete(snum, jobid);
1451
1452         return (result == 0);
1453 }
1454
1455 /****************************************************************************
1456  Return true if the current user owns the print job.
1457 ****************************************************************************/
1458
1459 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1460 {
1461         struct printjob *pjob = print_job_find(snum, jobid);
1462         user_struct *vuser;
1463
1464         if (!pjob || !user)
1465                 return False;
1466
1467         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1468                 return strequal(pjob->user, vuser->user.smb_name);
1469         } else {
1470                 return strequal(pjob->user, uidtoname(user->uid));
1471         }
1472 }
1473
1474 /****************************************************************************
1475  Delete a print job.
1476 ****************************************************************************/
1477
1478 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1479 {
1480         BOOL    owner, deleted;
1481         char    *fname;
1482
1483         *errcode = WERR_OK;
1484                 
1485         owner = is_owner(user, snum, jobid);
1486         
1487         /* Check access against security descriptor or whether the user
1488            owns their job. */
1489
1490         if (!owner && 
1491             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1492                 DEBUG(3, ("delete denied by security descriptor\n"));
1493                 *errcode = WERR_ACCESS_DENIED;
1494
1495                 /* BEGIN_ADMIN_LOG */
1496                 sys_adminlog( LOG_ERR, (char *)
1497                          "Permission denied-- user not allowed to delete, \
1498 pause, or resume print job. User name: %s. Printer name: %s.",
1499                                 uidtoname(user->uid), PRINTERNAME(snum) );
1500                 /* END_ADMIN_LOG */
1501
1502                 return False;
1503         }
1504
1505         /* 
1506          * get the spooled filename of the print job
1507          * if this works, then the file has not been spooled
1508          * to the underlying print system.  Just delete the 
1509          * spool file & return.
1510          */
1511          
1512         if ( (fname = print_job_fname( snum, jobid )) != NULL )
1513         {
1514                 /* remove the spool file */
1515                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1516                 if ( unlink( fname ) == -1 ) {
1517                         *errcode = map_werror_from_unix(errno);
1518                         return False;
1519                 }
1520                 
1521                 return True;
1522         }
1523         
1524         if (!print_job_delete1(snum, jobid)) {
1525                 *errcode = WERR_ACCESS_DENIED;
1526                 return False;
1527         }
1528
1529         /* force update the database and say the delete failed if the
1530            job still exists */
1531
1532         print_queue_update(snum);
1533         
1534         deleted = !print_job_exists(snum, jobid);
1535         if ( !deleted )
1536                 *errcode = WERR_ACCESS_DENIED;
1537
1538         return deleted;
1539 }
1540
1541 /****************************************************************************
1542  Pause a job.
1543 ****************************************************************************/
1544
1545 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1546 {
1547         struct printjob *pjob = print_job_find(snum, jobid);
1548         int ret = -1;
1549         
1550         if (!pjob || !user) 
1551                 return False;
1552
1553         if (!pjob->spooled || pjob->sysjob == -1) 
1554                 return False;
1555
1556         if (!is_owner(user, snum, jobid) &&
1557             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1558                 DEBUG(3, ("pause denied by security descriptor\n"));
1559
1560                 /* BEGIN_ADMIN_LOG */
1561                 sys_adminlog( LOG_ERR, (char *)
1562                         "Permission denied-- user not allowed to delete, \
1563 pause, or resume print job. User name: %s. Printer name: %s.",
1564                                 uidtoname(user->uid), PRINTERNAME(snum) );
1565                 /* END_ADMIN_LOG */
1566
1567                 *errcode = WERR_ACCESS_DENIED;
1568                 return False;
1569         }
1570
1571         /* need to pause the spooled entry */
1572         ret = (*(current_printif->job_pause))(snum, pjob);
1573
1574         if (ret != 0) {
1575                 *errcode = WERR_INVALID_PARAM;
1576                 return False;
1577         }
1578
1579         /* force update the database */
1580         print_cache_flush(snum);
1581
1582         /* Send a printer notify message */
1583
1584         notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1585
1586         /* how do we tell if this succeeded? */
1587
1588         return True;
1589 }
1590
1591 /****************************************************************************
1592  Resume a job.
1593 ****************************************************************************/
1594
1595 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1596 {
1597         struct printjob *pjob = print_job_find(snum, jobid);
1598         int ret;
1599         
1600         if (!pjob || !user)
1601                 return False;
1602
1603         if (!pjob->spooled || pjob->sysjob == -1)
1604                 return False;
1605
1606         if (!is_owner(user, snum, jobid) &&
1607             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1608                 DEBUG(3, ("resume denied by security descriptor\n"));
1609                 *errcode = WERR_ACCESS_DENIED;
1610
1611                 /* BEGIN_ADMIN_LOG */
1612                 sys_adminlog( LOG_ERR, (char *)
1613                          "Permission denied-- user not allowed to delete, \
1614 pause, or resume print job. User name: %s. Printer name: %s.",
1615                         uidtoname(user->uid), PRINTERNAME(snum) );
1616                 /* END_ADMIN_LOG */
1617                 return False;
1618         }
1619
1620         ret = (*(current_printif->job_resume))(snum, pjob);
1621
1622         if (ret != 0) {
1623                 *errcode = WERR_INVALID_PARAM;
1624                 return False;
1625         }
1626
1627         /* force update the database */
1628         print_cache_flush(snum);
1629
1630         /* Send a printer notify message */
1631
1632         notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1633
1634         return True;
1635 }
1636
1637 /****************************************************************************
1638  Write to a print file.
1639 ****************************************************************************/
1640
1641 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1642 {
1643         int return_code;
1644         struct printjob *pjob = print_job_find(snum, jobid);
1645
1646         if (!pjob)
1647                 return -1;
1648         /* don't allow another process to get this info - it is meaningless */
1649         if (pjob->pid != local_pid)
1650                 return -1;
1651
1652         return_code = write(pjob->fd, buf, size);
1653         if (return_code>0) {
1654                 pjob->size += size;
1655                 pjob_store(snum, jobid, pjob);
1656         }
1657         return return_code;
1658 }
1659
1660 /****************************************************************************
1661  Check if the print queue has been updated recently enough.
1662 ****************************************************************************/
1663
1664 static BOOL print_cache_expired(int snum)
1665 {
1666         fstring key;
1667         time_t last_qscan_time, time_now = time(NULL);
1668         const char *printername = lp_const_servicename(snum);
1669         struct tdb_print_db *pdb = get_print_db_byname(printername);
1670
1671         if (!pdb)
1672                 return False;
1673
1674         slprintf(key, sizeof(key), "CACHE/%s", printername);
1675         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1676
1677         /*
1678          * Invalidate the queue for 3 reasons.
1679          * (1). last queue scan time == -1.
1680          * (2). Current time - last queue scan time > allowed cache time.
1681          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1682          * This last test picks up machines for which the clock has been moved
1683          * forward, an lpq scan done and then the clock moved back. Otherwise
1684          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1685          */
1686
1687         if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1688                         last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1689                 DEBUG(3, ("print cache expired for queue %s \
1690 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1691                         (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1692                 release_print_db(pdb);
1693                 return True;
1694         }
1695         release_print_db(pdb);
1696         return False;
1697 }
1698
1699 /****************************************************************************
1700  Get the queue status - do not update if db is out of date.
1701 ****************************************************************************/
1702
1703 static int get_queue_status(int snum, print_status_struct *status)
1704 {
1705         fstring keystr;
1706         TDB_DATA data, key;
1707         const char *printername = lp_const_servicename(snum);
1708         struct tdb_print_db *pdb = get_print_db_byname(printername);
1709         if (!pdb)
1710                 return 0;
1711
1712         ZERO_STRUCTP(status);
1713         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1714         key.dptr = keystr;
1715         key.dsize = strlen(keystr);
1716         data = tdb_fetch(pdb->tdb, key);
1717         release_print_db(pdb);
1718         if (data.dptr) {
1719                 if (data.dsize == sizeof(print_status_struct))
1720                         memcpy(status, data.dptr, sizeof(print_status_struct));
1721                 SAFE_FREE(data.dptr);
1722         }
1723         return status->qcount;
1724 }
1725
1726 /****************************************************************************
1727  Determine the number of jobs in a queue.
1728 ****************************************************************************/
1729
1730 int print_queue_length(int snum, print_status_struct *pstatus)
1731 {
1732         print_status_struct status;
1733         int len;
1734  
1735         /* make sure the database is up to date */
1736         if (print_cache_expired(snum))
1737                 print_queue_update(snum);
1738  
1739         /* also fetch the queue status */
1740         memset(&status, 0, sizeof(status));
1741         len = get_queue_status(snum, &status);
1742         if (pstatus)
1743                 *pstatus = status;
1744         return len;
1745 }
1746
1747 /***************************************************************************
1748  Start spooling a job - return the jobid.
1749 ***************************************************************************/
1750
1751 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
1752 {
1753         uint32 jobid;
1754         char *path;
1755         struct printjob pjob;
1756         int next_jobid;
1757         user_struct *vuser;
1758         int njobs = 0;
1759         const char *printername = lp_const_servicename(snum);
1760         struct tdb_print_db *pdb = get_print_db_byname(printername);
1761         BOOL pdb_locked = False;
1762
1763         errno = 0;
1764
1765         if (!pdb)
1766                 return (uint32)-1;
1767
1768         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
1769                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1770                 release_print_db(pdb);
1771                 return (uint32)-1;
1772         }
1773
1774         if (!print_time_access_check(snum)) {
1775                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1776                 release_print_db(pdb);
1777                 return (uint32)-1;
1778         }
1779
1780         path = lp_pathname(snum);
1781
1782         /* see if we have sufficient disk space */
1783         if (lp_minprintspace(snum)) {
1784                 SMB_BIG_UINT dspace, dsize;
1785                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
1786                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
1787                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
1788                         release_print_db(pdb);
1789                         errno = ENOSPC;
1790                         return (uint32)-1;
1791                 }
1792         }
1793
1794         /* for autoloaded printers, check that the printcap entry still exists */
1795         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
1796                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
1797                 release_print_db(pdb);
1798                 errno = ENOENT;
1799                 return (uint32)-1;
1800         }
1801
1802         /* Insure the maximum queue size is not violated */
1803         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
1804                 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n",
1805                         njobs, lp_maxprintjobs(snum) ));
1806                 release_print_db(pdb);
1807                 errno = ENOSPC;
1808                 return (uint32)-1;
1809         }
1810
1811         /* Lock the database - only wait 20 seconds. */
1812         if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1813                 DEBUG(0,("print_job_start: failed to lock printing database %s\n", printername ));
1814                 release_print_db(pdb);
1815                 return (uint32)-1;
1816         }
1817
1818         pdb_locked = True;
1819
1820         next_jobid = tdb_fetch_int32(pdb->tdb, "INFO/nextjob");
1821         if (next_jobid == -1)
1822                 next_jobid = 1;
1823
1824         for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
1825                 if (!print_job_exists(snum, jobid))
1826                         break;
1827         }
1828                                 
1829         if (jobid == next_jobid) {
1830                 DEBUG(3, ("print_job_start: jobid (%d)==next_jobid(%d).\n",
1831                                 jobid, next_jobid ));
1832                 jobid = -1;
1833                 goto fail;
1834         }
1835
1836         /* Store a dummy placeholder. This must be quick as we have the lock. */
1837         {
1838                 TDB_DATA dum;
1839                 dum.dptr = NULL;
1840                 dum.dsize = 0;
1841                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1842                         DEBUG(3, ("print_job_start: jobid (%d) failed to store placeholder.\n",
1843                                 jobid ));
1844                         jobid = -1;
1845                         goto fail;
1846                 }
1847         }
1848
1849         if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1850                 DEBUG(3, ("print_job_start: failed to store INFO/nextjob.\n"));
1851                 jobid = -1;
1852                 goto fail;
1853         }
1854
1855         /* We've finished with the INFO/nextjob lock. */
1856         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1857         pdb_locked = False;
1858
1859         /* create the database entry */
1860         
1861         ZERO_STRUCT(pjob);
1862         
1863         pjob.pid = local_pid;
1864         pjob.sysjob = -1;
1865         pjob.fd = -1;
1866         pjob.starttime = time(NULL);
1867         pjob.status = LPQ_SPOOLING;
1868         pjob.size = 0;
1869         pjob.spooled = False;
1870         pjob.smbjob = True;
1871         pjob.nt_devmode = nt_devmode;
1872         
1873         fstrcpy(pjob.jobname, jobname);
1874
1875         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1876                 fstrcpy(pjob.user, vuser->user.smb_name);
1877         } else {
1878                 fstrcpy(pjob.user, uidtoname(user->uid));
1879         }
1880
1881         fstrcpy(pjob.queuename, lp_const_servicename(snum));
1882
1883         /* we have a job entry - now create the spool file */
1884         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
1885                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
1886         pjob.fd = smb_mkstemp(pjob.filename);
1887
1888         if (pjob.fd == -1) {
1889                 if (errno == EACCES) {
1890                         /* Common setup error, force a report. */
1891                         DEBUG(0, ("print_job_start: insufficient permissions \
1892 to open spool file %s.\n", pjob.filename));
1893                 } else {
1894                         /* Normal case, report at level 3 and above. */
1895                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
1896                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
1897                 }
1898                 goto fail;
1899         }
1900
1901         pjob_store(snum, jobid, &pjob);
1902
1903         release_print_db(pdb);
1904
1905         return jobid;
1906
1907  fail:
1908         if (jobid != -1)
1909                 pjob_delete(snum, jobid);
1910
1911         if (pdb_locked)
1912                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1913         release_print_db(pdb);
1914
1915         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
1916         return -1;
1917 }
1918
1919 /****************************************************************************
1920  Update the number of pages spooled to jobid
1921 ****************************************************************************/
1922
1923 void print_job_endpage(int snum, uint32 jobid)
1924 {
1925         struct printjob *pjob = print_job_find(snum, jobid);
1926         if (!pjob)
1927                 return;
1928         /* don't allow another process to get this info - it is meaningless */
1929         if (pjob->pid != local_pid)
1930                 return;
1931
1932         pjob->page_count++;
1933         pjob_store(snum, jobid, pjob);
1934 }
1935
1936 /****************************************************************************
1937  Print a file - called on closing the file. This spools the job.
1938  If normal close is false then we're tearing down the jobs - treat as an
1939  error.
1940 ****************************************************************************/
1941
1942 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
1943 {
1944         struct printjob *pjob = print_job_find(snum, jobid);
1945         int ret;
1946         SMB_STRUCT_STAT sbuf;
1947
1948         if (!pjob)
1949                 return False;
1950
1951         if (pjob->spooled || pjob->pid != local_pid)
1952                 return False;
1953
1954         if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
1955                 pjob->size = sbuf.st_size;
1956                 close(pjob->fd);
1957                 pjob->fd = -1;
1958         } else {
1959
1960                 /* 
1961                  * Not a normal close or we couldn't stat the job file,
1962                  * so something has gone wrong. Cleanup.
1963                  */
1964                 close(pjob->fd);
1965                 pjob->fd = -1;
1966                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
1967                 goto fail;
1968         }
1969
1970         /* Technically, this is not quite right. If the printer has a separator
1971          * page turned on, the NT spooler prints the separator page even if the
1972          * print job is 0 bytes. 010215 JRR */
1973         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
1974                 /* don't bother spooling empty files or something being deleted. */
1975                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
1976                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
1977                 unlink(pjob->filename);
1978                 pjob_delete(snum, jobid);
1979                 return True;
1980         }
1981
1982         ret = (*(current_printif->job_submit))(snum, pjob);
1983
1984         if (ret)
1985                 goto fail;
1986
1987         /* The print job has been sucessfully handed over to the back-end */
1988         
1989         pjob->spooled = True;
1990         pjob->status = LPQ_QUEUED;
1991         pjob_store(snum, jobid, pjob);
1992         
1993         /* make sure the database is up to date */
1994         if (print_cache_expired(snum))
1995                 print_queue_update(snum);
1996         
1997         return True;
1998
1999 fail:
2000
2001         /* The print job was not succesfully started. Cleanup */
2002         /* Still need to add proper error return propagation! 010122:JRR */
2003         unlink(pjob->filename);
2004         pjob_delete(snum, jobid);
2005         return False;
2006 }
2007
2008 /****************************************************************************
2009  Utility fn to enumerate the print queue.
2010 ****************************************************************************/
2011
2012 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
2013 {
2014         struct traverse_struct *ts = (struct traverse_struct *)state;
2015         struct printjob pjob;
2016         int i;
2017         uint32 jobid;
2018
2019         /* sanity checks */
2020         
2021         if ( key.dsize != sizeof(jobid) )
2022                 return 0;
2023                 
2024         memcpy(&jobid, key.dptr, sizeof(jobid));
2025         
2026         if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
2027                 return 0;
2028         free_nt_devicemode( &pjob.nt_devmode );
2029
2030         /* maybe it isn't for this queue */
2031         if (ts->snum != lp_servicenumber(pjob.queuename))
2032                 return 0;
2033
2034         if (ts->qcount >= ts->maxcount)
2035                 return 0;
2036
2037         i = ts->qcount;
2038
2039         ts->queue[i].job = jobid;
2040         ts->queue[i].size = pjob.size;
2041         ts->queue[i].page_count = pjob.page_count;
2042         ts->queue[i].status = pjob.status;
2043         ts->queue[i].priority = 1;
2044         ts->queue[i].time = pjob.starttime;
2045         fstrcpy(ts->queue[i].fs_user, pjob.user);
2046         fstrcpy(ts->queue[i].fs_file, pjob.jobname);
2047
2048         ts->qcount++;
2049
2050         return 0;
2051 }
2052
2053 struct traverse_count_struct {
2054         int snum, count;
2055 };
2056
2057 /****************************************************************************
2058  Utility fn to count the number of entries in the print queue.
2059 ****************************************************************************/
2060
2061 static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
2062 {
2063         struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
2064         struct printjob pjob;
2065         uint32 jobid;
2066
2067         /* sanity checks */
2068         
2069         if (  key.dsize != sizeof(jobid) )
2070                 return 0;
2071                 
2072         memcpy(&jobid, key.dptr, sizeof(jobid));
2073         
2074         if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
2075                 return 0;
2076                 
2077         free_nt_devicemode( &pjob.nt_devmode );
2078
2079         /* maybe it isn't for this queue - this cannot happen with the tdb/printer code. JRA */
2080         if (ts->snum != lp_servicenumber(pjob.queuename))
2081                 return 0;
2082
2083         ts->count++;
2084
2085         return 0;
2086 }
2087
2088 /****************************************************************************
2089  Sort print jobs by submittal time.
2090 ****************************************************************************/
2091
2092 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
2093 {
2094         /* Silly cases */
2095
2096         if (!j1 && !j2)
2097                 return 0;
2098         if (!j1)
2099                 return -1;
2100         if (!j2)
2101                 return 1;
2102
2103         /* Sort on job start time */
2104
2105         if (j1->time == j2->time)
2106                 return 0;
2107         return (j1->time > j2->time) ? 1 : -1;
2108 }
2109
2110 /****************************************************************************
2111  Get a printer queue listing.
2112 ****************************************************************************/
2113
2114 int print_queue_status(int snum, 
2115                        print_queue_struct **queue,
2116                        print_status_struct *status)
2117 {
2118         struct traverse_struct tstruct;
2119         struct traverse_count_struct tsc;
2120         fstring keystr;
2121         TDB_DATA data, key;
2122         const char *printername = lp_const_servicename(snum);
2123         struct tdb_print_db *pdb = get_print_db_byname(printername);
2124
2125         *queue = NULL;
2126         
2127         if (!pdb)
2128                 return 0;
2129
2130         /* make sure the database is up to date */
2131         if (print_cache_expired(snum))
2132                 print_queue_update(snum);
2133
2134         /*
2135          * Fetch the queue status.  We must do this first, as there may
2136          * be no jobs in the queue.
2137          */
2138         ZERO_STRUCTP(status);
2139         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2140         key.dptr = keystr;
2141         key.dsize = strlen(keystr);
2142         data = tdb_fetch(pdb->tdb, key);
2143         if (data.dptr) {
2144                 if (data.dsize == sizeof(*status)) {
2145                         memcpy(status, data.dptr, sizeof(*status));
2146                 }
2147                 SAFE_FREE(data.dptr);
2148         }
2149
2150         /*
2151          * Now, fetch the print queue information.  We first count the number
2152          * of entries, and then only retrieve the queue if necessary.
2153          */
2154         tsc.count = 0;
2155         tsc.snum = snum;
2156         
2157         tdb_traverse(pdb->tdb, traverse_count_fn_queue, (void *)&tsc);
2158
2159         if (tsc.count == 0) {
2160                 release_print_db(pdb);
2161                 return 0;
2162         }
2163
2164         /* Allocate the queue size. */
2165         if ((tstruct.queue = (print_queue_struct *)
2166              malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) {
2167                 release_print_db(pdb);
2168                 return 0;
2169         }
2170
2171         /*
2172          * Fill in the queue.
2173          * We need maxcount as the queue size may have changed between
2174          * the two calls to tdb_traverse.
2175          */
2176         tstruct.qcount = 0;
2177         tstruct.maxcount = tsc.count;
2178         tstruct.snum = snum;
2179
2180         tdb_traverse(pdb->tdb, traverse_fn_queue, (void *)&tstruct);
2181         release_print_db(pdb);
2182
2183         /* Sort the queue by submission time otherwise they are displayed
2184            in hash order. */
2185
2186         qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
2187               QSORT_CAST(printjob_comp));
2188
2189         *queue = tstruct.queue;
2190         return tstruct.qcount;
2191 }
2192
2193 /****************************************************************************
2194  Turn a queue name into a snum.
2195 ****************************************************************************/
2196
2197 int print_queue_snum(const char *qname)
2198 {
2199         int snum = lp_servicenumber(qname);
2200         if (snum == -1 || !lp_print_ok(snum))
2201                 return -1;
2202         return snum;
2203 }
2204
2205 /****************************************************************************
2206  Pause a queue.
2207 ****************************************************************************/
2208
2209 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2210 {
2211         int ret;
2212         
2213         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2214                 *errcode = WERR_ACCESS_DENIED;
2215                 return False;
2216         }
2217
2218         ret = (*(current_printif->queue_pause))(snum);
2219
2220         if (ret != 0) {
2221                 *errcode = WERR_INVALID_PARAM;
2222                 return False;
2223         }
2224
2225         /* force update the database */
2226         print_cache_flush(snum);
2227
2228         /* Send a printer notify message */
2229
2230         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2231
2232         return True;
2233 }
2234
2235 /****************************************************************************
2236  Resume a queue.
2237 ****************************************************************************/
2238
2239 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2240 {
2241         int ret;
2242
2243         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2244                 *errcode = WERR_ACCESS_DENIED;
2245                 return False;
2246         }
2247
2248         ret = (*(current_printif->queue_resume))(snum);
2249
2250         if (ret != 0) {
2251                 *errcode = WERR_INVALID_PARAM;
2252                 return False;
2253         }
2254
2255         /* make sure the database is up to date */
2256         if (print_cache_expired(snum))
2257                 print_queue_update(snum);
2258
2259         /* Send a printer notify message */
2260
2261         notify_printer_status(snum, PRINTER_STATUS_OK);
2262
2263         return True;
2264 }
2265
2266 /****************************************************************************
2267  Purge a queue - implemented by deleting all jobs that we can delete.
2268 ****************************************************************************/
2269
2270 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2271 {
2272         print_queue_struct *queue;
2273         print_status_struct status;
2274         int njobs, i;
2275         BOOL can_job_admin;
2276
2277         /* Force and update so the count is accurate (i.e. not a cached count) */
2278         print_queue_update(snum);
2279         
2280         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2281         njobs = print_queue_status(snum, &queue, &status);
2282
2283         for (i=0;i<njobs;i++) {
2284                 BOOL owner = is_owner(user, snum, queue[i].job);
2285
2286                 if (owner || can_job_admin) {
2287                         print_job_delete1(snum, queue[i].job);
2288                 }
2289         }
2290
2291         SAFE_FREE(queue);
2292
2293         return True;
2294 }