r25117: The mega-patch Jerry was waiting for. Remove all pstrings from
[amitay/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 3 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "printing.h"
24
25 extern SIG_ATOMIC_T got_sig_term;
26 extern SIG_ATOMIC_T reload_after_sighup;
27 extern struct current_user current_user;
28 extern userdom_struct current_user_info;
29
30 /* Current printer interface */
31 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
32
33 /* 
34    the printing backend revolves around a tdb database that stores the
35    SMB view of the print queue 
36    
37    The key for this database is a jobid - a internally generated number that
38    uniquely identifies a print job
39
40    reading the print queue involves two steps:
41      - possibly running lpq and updating the internal database from that
42      - reading entries from the database
43
44    jobids are assigned when a job starts spooling. 
45 */
46
47 static TDB_CONTEXT *rap_tdb;
48 static uint16 next_rap_jobid;
49 struct rap_jobid_key {
50         fstring sharename;
51         uint32  jobid;
52 };
53
54 /***************************************************************************
55  Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
56  bit RPC jobids.... JRA.
57 ***************************************************************************/
58
59 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
60 {
61         uint16 rap_jobid;
62         TDB_DATA data, key;
63         struct rap_jobid_key jinfo;
64         uint8 buf[2];
65
66         DEBUG(10,("pjobid_to_rap: called.\n"));
67
68         if (!rap_tdb) {
69                 /* Create the in-memory tdb. */
70                 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
71                 if (!rap_tdb)
72                         return 0;
73         }
74
75         ZERO_STRUCT( jinfo );
76         fstrcpy( jinfo.sharename, sharename );
77         jinfo.jobid = jobid;
78         key.dptr = (uint8 *)&jinfo;
79         key.dsize = sizeof(jinfo);
80
81         data = tdb_fetch(rap_tdb, key);
82         if (data.dptr && data.dsize == sizeof(uint16)) {
83                 rap_jobid = SVAL(data.dptr, 0);
84                 SAFE_FREE(data.dptr);
85                 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
86                         (unsigned int)jobid, (unsigned int)rap_jobid));
87                 return rap_jobid;
88         }
89         SAFE_FREE(data.dptr);
90         /* Not found - create and store mapping. */
91         rap_jobid = ++next_rap_jobid;
92         if (rap_jobid == 0)
93                 rap_jobid = ++next_rap_jobid;
94         SSVAL(buf,0,rap_jobid);
95         data.dptr = buf;
96         data.dsize = sizeof(rap_jobid);
97         tdb_store(rap_tdb, key, data, TDB_REPLACE);
98         tdb_store(rap_tdb, data, key, TDB_REPLACE);
99
100         DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
101                 (unsigned int)jobid, (unsigned int)rap_jobid));
102         return rap_jobid;
103 }
104
105 BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
106 {
107         TDB_DATA data, key;
108         uint8 buf[2];
109
110         DEBUG(10,("rap_to_pjobid called.\n"));
111
112         if (!rap_tdb)
113                 return False;
114
115         SSVAL(buf,0,rap_jobid);
116         key.dptr = buf;
117         key.dsize = sizeof(rap_jobid);
118         data = tdb_fetch(rap_tdb, key);
119         if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) 
120         {
121                 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
122                 fstrcpy( sharename, jinfo->sharename );
123                 *pjobid = jinfo->jobid;
124                 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
125                         (unsigned int)*pjobid, (unsigned int)rap_jobid));
126                 SAFE_FREE(data.dptr);
127                 return True;
128         }
129
130         DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
131                 (unsigned int)rap_jobid));
132         SAFE_FREE(data.dptr);
133         return False;
134 }
135
136 static void rap_jobid_delete(const char* sharename, uint32 jobid)
137 {
138         TDB_DATA key, data;
139         uint16 rap_jobid;
140         struct rap_jobid_key jinfo;
141         uint8 buf[2];
142
143         DEBUG(10,("rap_jobid_delete: called.\n"));
144
145         if (!rap_tdb)
146                 return;
147
148         ZERO_STRUCT( jinfo );
149         fstrcpy( jinfo.sharename, sharename );
150         jinfo.jobid = jobid;
151         key.dptr = (uint8 *)&jinfo;
152         key.dsize = sizeof(jinfo);
153
154         data = tdb_fetch(rap_tdb, key);
155         if (!data.dptr || (data.dsize != sizeof(uint16))) {
156                 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
157                         (unsigned int)jobid ));
158                 SAFE_FREE(data.dptr);
159                 return;
160         }
161
162         DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
163                 (unsigned int)jobid ));
164
165         rap_jobid = SVAL(data.dptr, 0);
166         SAFE_FREE(data.dptr);
167         SSVAL(buf,0,rap_jobid);
168         data.dptr = buf;
169         data.dsize = sizeof(rap_jobid);
170         tdb_delete(rap_tdb, key);
171         tdb_delete(rap_tdb, data);
172 }
173
174 static int get_queue_status(const char* sharename, print_status_struct *);
175
176 /****************************************************************************
177  Initialise the printing backend. Called once at startup before the fork().
178 ****************************************************************************/
179
180 BOOL print_backend_init(struct messaging_context *msg_ctx)
181 {
182         const char *sversion = "INFO/version";
183         pstring printing_path;
184         int services = lp_numservices();
185         int snum;
186
187         unlink(lock_path("printing.tdb"));
188         pstrcpy(printing_path,lock_path("printing"));
189         mkdir(printing_path,0755);
190
191         /* handle a Samba upgrade */
192
193         for (snum = 0; snum < services; snum++) {
194                 struct tdb_print_db *pdb;
195                 if (!lp_print_ok(snum))
196                         continue;
197
198                 pdb = get_print_db_byname(lp_const_servicename(snum));
199                 if (!pdb)
200                         continue;
201                 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
202                         DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
203                         release_print_db(pdb);
204                         return False;
205                 }
206                 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
207                         tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
208                         tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
209                 }
210                 tdb_unlock_bystring(pdb->tdb, sversion);
211                 release_print_db(pdb);
212         }
213
214         close_all_print_db(); /* Don't leave any open. */
215
216         /* do NT print initialization... */
217         return nt_printing_init(msg_ctx);
218 }
219
220 /****************************************************************************
221  Shut down printing backend. Called once at shutdown to close the tdb.
222 ****************************************************************************/
223
224 void printing_end(void)
225 {
226         close_all_print_db(); /* Don't leave any open. */
227 }
228
229 /****************************************************************************
230  Retrieve the set of printing functions for a given service.  This allows 
231  us to set the printer function table based on the value of the 'printing'
232  service parameter.
233  
234  Use the generic interface as the default and only use cups interface only
235  when asked for (and only when supported)
236 ****************************************************************************/
237
238 static struct printif *get_printer_fns_from_type( enum printing_types type )
239 {
240         struct printif *printer_fns = &generic_printif;
241
242 #ifdef HAVE_CUPS
243         if ( type == PRINT_CUPS ) {
244                 printer_fns = &cups_printif;
245         }
246 #endif /* HAVE_CUPS */
247
248 #ifdef HAVE_IPRINT
249         if ( type == PRINT_IPRINT ) {
250                 printer_fns = &iprint_printif;
251         }
252 #endif /* HAVE_IPRINT */
253
254         printer_fns->type = type;
255         
256         return printer_fns;
257 }
258
259 static struct printif *get_printer_fns( int snum )
260 {
261         return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
262 }
263
264
265 /****************************************************************************
266  Useful function to generate a tdb key.
267 ****************************************************************************/
268
269 static TDB_DATA print_key(uint32 jobid)
270 {
271         static uint32 j;
272         TDB_DATA ret;
273
274         SIVAL(&j, 0, jobid);
275         ret.dptr = (uint8 *)&j;
276         ret.dsize = sizeof(j);
277         return ret;
278 }
279
280 /***********************************************************************
281  unpack a pjob from a tdb buffer 
282 ***********************************************************************/
283  
284 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
285 {
286         int     len = 0;
287         int     used;
288         uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
289         uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
290
291         if ( !buf || !pjob )
292                 return -1;
293                 
294         len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
295                                 &pjpid,
296                                 &pjsysjob,
297                                 &pjfd,
298                                 &pjstarttime,
299                                 &pjstatus,
300                                 &pjsize,
301                                 &pjpage_count,
302                                 &pjspooled,
303                                 &pjsmbjob,
304                                 pjob->filename,
305                                 pjob->jobname,
306                                 pjob->user,
307                                 pjob->queuename);
308                                 
309         if ( len == -1 )
310                 return -1;
311                 
312         if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
313                 return -1;
314         
315         len += used;
316
317         pjob->pid = pjpid;
318         pjob->sysjob = pjsysjob;
319         pjob->fd = pjfd;
320         pjob->starttime = pjstarttime;
321         pjob->status = pjstatus;
322         pjob->size = pjsize;
323         pjob->page_count = pjpage_count;
324         pjob->spooled = pjspooled;
325         pjob->smbjob = pjsmbjob;
326         
327         return len;
328
329 }
330
331 /****************************************************************************
332  Useful function to find a print job in the database.
333 ****************************************************************************/
334
335 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
336 {
337         static struct printjob  pjob;
338         TDB_DATA                ret;
339         struct tdb_print_db     *pdb = get_print_db_byname(sharename);
340         
341         DEBUG(10,("print_job_find: looking up job %u for share %s\n",
342                         (unsigned int)jobid, sharename ));
343
344         if (!pdb) {
345                 return NULL;
346         }
347
348         ret = tdb_fetch(pdb->tdb, print_key(jobid));
349         release_print_db(pdb);
350
351         if (!ret.dptr) {
352                 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
353                 return NULL;
354         }
355         
356         if ( pjob.nt_devmode ) {
357                 free_nt_devicemode( &pjob.nt_devmode );
358         }
359                 
360         ZERO_STRUCT( pjob );
361         
362         if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
363                 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
364                 SAFE_FREE(ret.dptr);
365                 return NULL;
366         }
367         
368         SAFE_FREE(ret.dptr);
369
370         DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
371                         (int)pjob.sysjob, (unsigned int)jobid ));
372
373         return &pjob;
374 }
375
376 /* Convert a unix jobid to a smb jobid */
377
378 static uint32 sysjob_to_jobid_value;
379
380 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
381                                TDB_DATA data, void *state)
382 {
383         struct printjob *pjob;
384         int *sysjob = (int *)state;
385
386         if (!data.dptr || data.dsize == 0)
387                 return 0;
388
389         pjob = (struct printjob *)data.dptr;
390         if (key.dsize != sizeof(uint32))
391                 return 0;
392
393         if (*sysjob == pjob->sysjob) {
394                 uint32 jobid = IVAL(key.dptr,0);
395
396                 sysjob_to_jobid_value = jobid;
397                 return 1;
398         }
399
400         return 0;
401 }
402
403 /****************************************************************************
404  This is a *horribly expensive call as we have to iterate through all the
405  current printer tdb's. Don't do this often ! JRA.
406 ****************************************************************************/
407
408 uint32 sysjob_to_jobid(int unix_jobid)
409 {
410         int services = lp_numservices();
411         int snum;
412
413         sysjob_to_jobid_value = (uint32)-1;
414
415         for (snum = 0; snum < services; snum++) {
416                 struct tdb_print_db *pdb;
417                 if (!lp_print_ok(snum))
418                         continue;
419                 pdb = get_print_db_byname(lp_const_servicename(snum));
420                 if (!pdb) {
421                         continue;
422                 }
423                 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
424                 release_print_db(pdb);
425                 if (sysjob_to_jobid_value != (uint32)-1)
426                         return sysjob_to_jobid_value;
427         }
428         return (uint32)-1;
429 }
430
431 /****************************************************************************
432  Send notifications based on what has changed after a pjob_store.
433 ****************************************************************************/
434
435 static struct {
436         uint32 lpq_status;
437         uint32 spoolss_status;
438 } lpq_to_spoolss_status_map[] = {
439         { LPQ_QUEUED, JOB_STATUS_QUEUED },
440         { LPQ_PAUSED, JOB_STATUS_PAUSED },
441         { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
442         { LPQ_PRINTING, JOB_STATUS_PRINTING },
443         { LPQ_DELETING, JOB_STATUS_DELETING },
444         { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
445         { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
446         { LPQ_PRINTED, JOB_STATUS_PRINTED },
447         { LPQ_DELETED, JOB_STATUS_DELETED },
448         { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
449         { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
450         { -1, 0 }
451 };
452
453 /* Convert a lpq status value stored in printing.tdb into the
454    appropriate win32 API constant. */
455
456 static uint32 map_to_spoolss_status(uint32 lpq_status)
457 {
458         int i = 0;
459
460         while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
461                 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
462                         return lpq_to_spoolss_status_map[i].spoolss_status;
463                 i++;
464         }
465
466         return 0;
467 }
468
469 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
470                               struct printjob *new_data)
471 {
472         BOOL new_job = False;
473
474         if (!old_data)
475                 new_job = True;
476
477         /* Job attributes that can't be changed.  We only send
478            notification for these on a new job. */
479
480         /* ACHTUNG!  Due to a bug in Samba's spoolss parsing of the 
481            NOTIFY_INFO_DATA buffer, we *have* to send the job submission 
482            time first or else we'll end up with potential alignment 
483            errors.  I don't think the systemtime should be spooled as 
484            a string, but this gets us around that error.   
485            --jerry (i'll feel dirty for this) */
486  
487         if (new_job) {
488                 notify_job_submitted(sharename, jobid, new_data->starttime);
489                 notify_job_username(sharename, jobid, new_data->user);
490         }
491
492         if (new_job || !strequal(old_data->jobname, new_data->jobname))
493                 notify_job_name(sharename, jobid, new_data->jobname);
494
495         /* Job attributes of a new job or attributes that can be
496            modified. */
497
498         if (new_job || !strequal(old_data->jobname, new_data->jobname))
499                 notify_job_name(sharename, jobid, new_data->jobname);
500
501         if (new_job || old_data->status != new_data->status)
502                 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
503
504         if (new_job || old_data->size != new_data->size)
505                 notify_job_total_bytes(sharename, jobid, new_data->size);
506
507         if (new_job || old_data->page_count != new_data->page_count)
508                 notify_job_total_pages(sharename, jobid, new_data->page_count);
509 }
510
511 /****************************************************************************
512  Store a job structure back to the database.
513 ****************************************************************************/
514
515 static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
516 {
517         TDB_DATA                old_data, new_data;
518         BOOL                    ret = False;
519         struct tdb_print_db     *pdb = get_print_db_byname(sharename);
520         uint8                   *buf = NULL;
521         int                     len, newlen, buflen;
522         
523
524         if (!pdb)
525                 return False;
526
527         /* Get old data */
528
529         old_data = tdb_fetch(pdb->tdb, print_key(jobid));
530
531         /* Doh!  Now we have to pack/unpack data since the NT_DEVICEMODE was added */
532
533         newlen = 0;
534         
535         do {
536                 len = 0;
537                 buflen = newlen;
538                 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
539                                 (uint32)pjob->pid,
540                                 (uint32)pjob->sysjob,
541                                 (uint32)pjob->fd,
542                                 (uint32)pjob->starttime,
543                                 (uint32)pjob->status,
544                                 (uint32)pjob->size,
545                                 (uint32)pjob->page_count,
546                                 (uint32)pjob->spooled,
547                                 (uint32)pjob->smbjob,
548                                 pjob->filename,
549                                 pjob->jobname,
550                                 pjob->user,
551                                 pjob->queuename);
552
553                 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
554         
555                 if (buflen != len) {
556                         buf = (uint8 *)SMB_REALLOC(buf, len);
557                         if (!buf) {
558                                 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
559                                 goto done;
560                         }
561                         newlen = len;
562                 }
563         } while ( buflen != len );
564                 
565         
566         /* Store new data */
567
568         new_data.dptr = buf;
569         new_data.dsize = len;
570         ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
571
572         release_print_db(pdb);
573
574         /* Send notify updates for what has changed */
575
576         if ( ret ) {
577                 struct printjob old_pjob;
578
579                 if ( old_data.dsize )
580                 {
581                         if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
582                         {
583                                 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
584                                 free_nt_devicemode( &old_pjob.nt_devmode );
585                         }
586                 }
587                 else {
588                         /* new job */
589                         pjob_store_notify( sharename, jobid, NULL, pjob );
590                 }
591         }
592
593 done:
594         SAFE_FREE( old_data.dptr );
595         SAFE_FREE( buf );
596
597         return ret;
598 }
599
600 /****************************************************************************
601  Remove a job structure from the database.
602 ****************************************************************************/
603
604 void pjob_delete(const char* sharename, uint32 jobid)
605 {
606         struct printjob *pjob;
607         uint32 job_status = 0;
608         struct tdb_print_db *pdb;
609
610         pdb = get_print_db_byname( sharename );
611
612         if (!pdb)
613                 return;
614
615         pjob = print_job_find( sharename, jobid );
616
617         if (!pjob) {
618                 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
619                                         (unsigned int)jobid));
620                 release_print_db(pdb);
621                 return;
622         }
623
624         /* We must cycle through JOB_STATUS_DELETING and
625            JOB_STATUS_DELETED for the port monitor to delete the job
626            properly. */
627         
628         job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
629         notify_job_status(sharename, jobid, job_status);
630         
631         /* Remove from printing.tdb */
632
633         tdb_delete(pdb->tdb, print_key(jobid));
634         remove_from_jobs_changed(sharename, jobid);
635         release_print_db( pdb );
636         rap_jobid_delete(sharename, jobid);
637 }
638
639 /****************************************************************************
640  Parse a file name from the system spooler to generate a jobid.
641 ****************************************************************************/
642
643 static uint32 print_parse_jobid(char *fname)
644 {
645         int jobid;
646
647         if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
648                 return (uint32)-1;
649         fname += strlen(PRINT_SPOOL_PREFIX);
650
651         jobid = atoi(fname);
652         if (jobid <= 0)
653                 return (uint32)-1;
654
655         return (uint32)jobid;
656 }
657
658 /****************************************************************************
659  List a unix job in the print database.
660 ****************************************************************************/
661
662 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
663 {
664         struct printjob pj, *old_pj;
665
666         if (jobid == (uint32)-1) 
667                 jobid = q->job + UNIX_JOB_START;
668
669         /* Preserve the timestamp on an existing unix print job */
670
671         old_pj = print_job_find(sharename, jobid);
672
673         ZERO_STRUCT(pj);
674
675         pj.pid = (pid_t)-1;
676         pj.sysjob = q->job;
677         pj.fd = -1;
678         pj.starttime = old_pj ? old_pj->starttime : q->time;
679         pj.status = q->status;
680         pj.size = q->size;
681         pj.spooled = True;
682         fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
683         if (jobid < UNIX_JOB_START) {
684                 pj.smbjob = True;
685                 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
686         } else {
687                 pj.smbjob = False;
688                 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
689         }
690         fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
691         fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
692
693         pjob_store(sharename, jobid, &pj);
694 }
695
696
697 struct traverse_struct {
698         print_queue_struct *queue;
699         int qcount, snum, maxcount, total_jobs;
700         const char *sharename;
701         time_t lpq_time;
702         const char *lprm_command;
703         struct printif *print_if;
704 };
705
706 /****************************************************************************
707  Utility fn to delete any jobs that are no longer active.
708 ****************************************************************************/
709
710 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
711 {
712         struct traverse_struct *ts = (struct traverse_struct *)state;
713         struct printjob pjob;
714         uint32 jobid;
715         int i = 0;
716
717         if (  key.dsize != sizeof(jobid) )
718                 return 0;
719                 
720         jobid = IVAL(key.dptr, 0);
721         if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
722                 return 0;
723         free_nt_devicemode( &pjob.nt_devmode );
724
725
726         if (!pjob.smbjob) {
727                 /* remove a unix job if it isn't in the system queue any more */
728
729                 for (i=0;i<ts->qcount;i++) {
730                         uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
731                         if (jobid == u_jobid)
732                                 break;
733                 }
734                 if (i == ts->qcount) {
735                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
736                                                 (unsigned int)jobid ));
737                         pjob_delete(ts->sharename, jobid);
738                         return 0;
739                 } 
740
741                 /* need to continue the the bottom of the function to
742                    save the correct attributes */
743         }
744
745         /* maybe it hasn't been spooled yet */
746         if (!pjob.spooled) {
747                 /* if a job is not spooled and the process doesn't
748                    exist then kill it. This cleans up after smbd
749                    deaths */
750                 if (!process_exists_by_pid(pjob.pid)) {
751                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
752                                                 (unsigned int)jobid, (unsigned int)pjob.pid ));
753                         pjob_delete(ts->sharename, jobid);
754                 } else
755                         ts->total_jobs++;
756                 return 0;
757         }
758
759         /* this check only makes sense for jobs submitted from Windows clients */
760         
761         if ( pjob.smbjob ) {
762                 for (i=0;i<ts->qcount;i++) {
763                         uint32 curr_jobid;
764
765                         if ( pjob.status == LPQ_DELETED )
766                                 continue;
767
768                         curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
769
770                         if (jobid == curr_jobid) {
771
772                                 /* try to clean up any jobs that need to be deleted */
773
774                                 if ( pjob.status == LPQ_DELETING ) {
775                                         int result;
776
777                                         result = (*(ts->print_if->job_delete))( 
778                                                 ts->sharename, ts->lprm_command, &pjob );
779
780                                         if ( result != 0 ) {
781                                                 /* if we can't delete, then reset the job status */
782                                                 pjob.status = LPQ_QUEUED;
783                                                 pjob_store(ts->sharename, jobid, &pjob);
784                                         }
785                                         else {
786                                                 /* if we deleted the job, the remove the tdb record */
787                                                 pjob_delete(ts->sharename, jobid);
788                                                 pjob.status = LPQ_DELETED;
789                                         }
790                                                 
791                                 }
792
793                                 break;
794                         }
795                 }
796         }
797         
798         /* The job isn't in the system queue - we have to assume it has
799            completed, so delete the database entry. */
800
801         if (i == ts->qcount) {
802
803                 /* A race can occur between the time a job is spooled and
804                    when it appears in the lpq output.  This happens when
805                    the job is added to printing.tdb when another smbd
806                    running print_queue_update() has completed a lpq and
807                    is currently traversing the printing tdb and deleting jobs.
808                    Don't delete the job if it was submitted after the lpq_time. */
809
810                 if (pjob.starttime < ts->lpq_time) {
811                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
812                                                 (unsigned int)jobid,
813                                                 (unsigned int)pjob.starttime,
814                                                 (unsigned int)ts->lpq_time ));
815                         pjob_delete(ts->sharename, jobid);
816                 } else
817                         ts->total_jobs++;
818                 return 0;
819         }
820
821         /* Save the pjob attributes we will store. 
822            FIXME!!! This is the only place where queue->job 
823            represents the SMB jobid      --jerry */
824
825         ts->queue[i].job = jobid;               
826         ts->queue[i].size = pjob.size;
827         ts->queue[i].page_count = pjob.page_count;
828         ts->queue[i].status = pjob.status;
829         ts->queue[i].priority = 1;
830         ts->queue[i].time = pjob.starttime;
831         fstrcpy(ts->queue[i].fs_user, pjob.user);
832         fstrcpy(ts->queue[i].fs_file, pjob.jobname);
833
834         ts->total_jobs++;
835
836         return 0;
837 }
838
839 /****************************************************************************
840  Check if the print queue has been updated recently enough.
841 ****************************************************************************/
842
843 static void print_cache_flush(const char *sharename)
844 {
845         fstring key;
846         struct tdb_print_db *pdb = get_print_db_byname(sharename);
847
848         if (!pdb)
849                 return;
850         slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
851         tdb_store_int32(pdb->tdb, key, -1);
852         release_print_db(pdb);
853 }
854
855 /****************************************************************************
856  Check if someone already thinks they are doing the update.
857 ****************************************************************************/
858
859 static pid_t get_updating_pid(const char *sharename)
860 {
861         fstring keystr;
862         TDB_DATA data, key;
863         pid_t updating_pid;
864         struct tdb_print_db *pdb = get_print_db_byname(sharename);
865
866         if (!pdb)
867                 return (pid_t)-1;
868         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
869         key = string_tdb_data(keystr);
870
871         data = tdb_fetch(pdb->tdb, key);
872         release_print_db(pdb);
873         if (!data.dptr || data.dsize != sizeof(pid_t)) {
874                 SAFE_FREE(data.dptr);
875                 return (pid_t)-1;
876         }
877
878         updating_pid = IVAL(data.dptr, 0);
879         SAFE_FREE(data.dptr);
880
881         if (process_exists_by_pid(updating_pid))
882                 return updating_pid;
883
884         return (pid_t)-1;
885 }
886
887 /****************************************************************************
888  Set the fact that we're doing the update, or have finished doing the update
889  in the tdb.
890 ****************************************************************************/
891
892 static void set_updating_pid(const fstring sharename, BOOL updating)
893 {
894         fstring keystr;
895         TDB_DATA key;
896         TDB_DATA data;
897         pid_t updating_pid = sys_getpid();
898         uint8 buffer[4];
899         
900         struct tdb_print_db *pdb = get_print_db_byname(sharename);
901
902         if (!pdb)
903                 return;
904
905         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
906         key = string_tdb_data(keystr);
907         
908         DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", 
909                 updating ? "" : "not ",
910                 sharename ));
911
912         if ( !updating ) {
913                 tdb_delete(pdb->tdb, key);
914                 release_print_db(pdb);
915                 return;
916         }
917         
918         SIVAL( buffer, 0, updating_pid);
919         data.dptr = buffer;
920         data.dsize = 4;         /* we always assume this is a 4 byte value */
921
922         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
923         release_print_db(pdb);
924 }
925
926 /****************************************************************************
927  Sort print jobs by submittal time.
928 ****************************************************************************/
929
930 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
931 {
932         /* Silly cases */
933
934         if (!j1 && !j2)
935                 return 0;
936         if (!j1)
937                 return -1;
938         if (!j2)
939                 return 1;
940
941         /* Sort on job start time */
942
943         if (j1->time == j2->time)
944                 return 0;
945         return (j1->time > j2->time) ? 1 : -1;
946 }
947
948 /****************************************************************************
949  Store the sorted queue representation for later portmon retrieval.
950  Skip deleted jobs
951 ****************************************************************************/
952
953 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
954 {
955         TDB_DATA data;
956         int max_reported_jobs = lp_max_reported_jobs(pts->snum);
957         print_queue_struct *queue = pts->queue;
958         size_t len;
959         size_t i;
960         uint qcount;
961
962         if (max_reported_jobs && (max_reported_jobs < pts->qcount))
963                 pts->qcount = max_reported_jobs;
964         qcount = 0;
965
966         /* Work out the size. */
967         data.dsize = 0;
968         data.dsize += tdb_pack(NULL, 0, "d", qcount);
969
970         for (i = 0; i < pts->qcount; i++) {
971                 if ( queue[i].status == LPQ_DELETED )
972                         continue;
973
974                 qcount++;
975                 data.dsize += tdb_pack(NULL, 0, "ddddddff",
976                                 (uint32)queue[i].job,
977                                 (uint32)queue[i].size,
978                                 (uint32)queue[i].page_count,
979                                 (uint32)queue[i].status,
980                                 (uint32)queue[i].priority,
981                                 (uint32)queue[i].time,
982                                 queue[i].fs_user,
983                                 queue[i].fs_file);
984         }
985
986         if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
987                 return;
988
989         len = 0;
990         len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
991         for (i = 0; i < pts->qcount; i++) {
992                 if ( queue[i].status == LPQ_DELETED )
993                         continue;
994
995                 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
996                                 (uint32)queue[i].job,
997                                 (uint32)queue[i].size,
998                                 (uint32)queue[i].page_count,
999                                 (uint32)queue[i].status,
1000                                 (uint32)queue[i].priority,
1001                                 (uint32)queue[i].time,
1002                                 queue[i].fs_user,
1003                                 queue[i].fs_file);
1004         }
1005
1006         tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1007                   TDB_REPLACE);
1008         SAFE_FREE(data.dptr);
1009         return;
1010 }
1011
1012 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1013 {
1014         TDB_DATA data;
1015
1016         ZERO_STRUCT(data);
1017
1018         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1019         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1020                 SAFE_FREE(data.dptr);
1021                 ZERO_STRUCT(data);
1022         }
1023
1024         return data;
1025 }
1026
1027 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1028 {
1029         unsigned int i;
1030         unsigned int job_count = data.dsize / 4;
1031
1032         for (i = 0; i < job_count; i++) {
1033                 uint32 ch_jobid;
1034
1035                 ch_jobid = IVAL(data.dptr, i*4);
1036                 if (ch_jobid == jobid)
1037                         remove_from_jobs_changed(sharename, jobid);
1038         }
1039 }
1040
1041 /****************************************************************************
1042  Check if the print queue has been updated recently enough.
1043 ****************************************************************************/
1044
1045 static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
1046 {
1047         fstring key;
1048         time_t last_qscan_time, time_now = time(NULL);
1049         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1050         BOOL result = False;
1051
1052         if (!pdb)
1053                 return False;
1054
1055         snprintf(key, sizeof(key), "CACHE/%s", sharename);
1056         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1057
1058         /*
1059          * Invalidate the queue for 3 reasons.
1060          * (1). last queue scan time == -1.
1061          * (2). Current time - last queue scan time > allowed cache time.
1062          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1063          * This last test picks up machines for which the clock has been moved
1064          * forward, an lpq scan done and then the clock moved back. Otherwise
1065          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1066          */
1067
1068         if (last_qscan_time == ((time_t)-1) 
1069                 || (time_now - last_qscan_time) >= lp_lpqcachetime() 
1070                 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) 
1071         {
1072                 uint32 u;
1073                 time_t msg_pending_time;
1074
1075                 DEBUG(4, ("print_cache_expired: cache expired for queue %s " 
1076                         "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", 
1077                         sharename, (int)last_qscan_time, (int)time_now, 
1078                         (int)lp_lpqcachetime() ));
1079
1080                 /* check if another smbd has already sent a message to update the 
1081                    queue.  Give the pending message one minute to clear and 
1082                    then send another message anyways.  Make sure to check for 
1083                    clocks that have been run forward and then back again. */
1084
1085                 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1086
1087                 if ( check_pending 
1088                         && tdb_fetch_uint32( pdb->tdb, key, &u ) 
1089                         && (msg_pending_time=u) > 0
1090                         && msg_pending_time <= time_now 
1091                         && (time_now - msg_pending_time) < 60 ) 
1092                 {
1093                         DEBUG(4,("print_cache_expired: message already pending for %s.  Accepting cache\n",
1094                                 sharename));
1095                         goto done;
1096                 }
1097                 
1098                 result = True;
1099         }
1100
1101 done:
1102         release_print_db(pdb);
1103         return result;
1104 }
1105
1106 /****************************************************************************
1107  main work for updating the lpq cahe for a printer queue
1108 ****************************************************************************/
1109
1110 static void print_queue_update_internal( const char *sharename, 
1111                                          struct printif *current_printif,
1112                                          char *lpq_command, char *lprm_command )
1113 {
1114         int i, qcount;
1115         print_queue_struct *queue = NULL;
1116         print_status_struct status;
1117         print_status_struct old_status;
1118         struct printjob *pjob;
1119         struct traverse_struct tstruct;
1120         TDB_DATA data, key;
1121         TDB_DATA jcdata;
1122         fstring keystr, cachestr;
1123         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1124
1125         if (!pdb) {
1126                 return;
1127         }
1128         
1129         DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1130                 sharename, current_printif->type, lpq_command));
1131
1132         /*
1133          * Update the cache time FIRST ! Stops others even
1134          * attempting to get the lock and doing this
1135          * if the lpq takes a long time.
1136          */
1137          
1138         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1139         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1140
1141         /* get the current queue using the appropriate interface */
1142         ZERO_STRUCT(status);
1143
1144         qcount = (*(current_printif->queue_get))(sharename, 
1145                 current_printif->type, 
1146                 lpq_command, &queue, &status);
1147
1148         DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n", 
1149                 qcount, (qcount != 1) ? "s" : "", sharename));
1150
1151         /* Sort the queue by submission time otherwise they are displayed
1152            in hash order. */
1153
1154         qsort(queue, qcount, sizeof(print_queue_struct),
1155                 QSORT_CAST(printjob_comp));
1156
1157         /*
1158           any job in the internal database that is marked as spooled
1159           and doesn't exist in the system queue is considered finished
1160           and removed from the database
1161
1162           any job in the system database but not in the internal database 
1163           is added as a unix job
1164
1165           fill in any system job numbers as we go
1166         */
1167
1168         jcdata = get_jobs_changed_data(pdb);
1169
1170         for (i=0; i<qcount; i++) {
1171                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1172
1173                 if (jobid == (uint32)-1) {
1174                         /* assume its a unix print job */
1175                         print_unix_job(sharename, &queue[i], jobid);
1176                         continue;
1177                 }
1178
1179                 /* we have an active SMB print job - update its status */
1180                 pjob = print_job_find(sharename, jobid);
1181                 if (!pjob) {
1182                         /* err, somethings wrong. Probably smbd was restarted
1183                            with jobs in the queue. All we can do is treat them
1184                            like unix jobs. Pity. */
1185                         print_unix_job(sharename, &queue[i], jobid);
1186                         continue;
1187                 }
1188
1189                 pjob->sysjob = queue[i].job;
1190
1191                 /* don't reset the status on jobs to be deleted */
1192
1193                 if ( pjob->status != LPQ_DELETING )
1194                         pjob->status = queue[i].status;
1195
1196                 pjob_store(sharename, jobid, pjob);
1197
1198                 check_job_changed(sharename, jcdata, jobid);
1199         }
1200
1201         SAFE_FREE(jcdata.dptr);
1202
1203         /* now delete any queued entries that don't appear in the
1204            system queue */
1205         tstruct.queue = queue;
1206         tstruct.qcount = qcount;
1207         tstruct.snum = -1;
1208         tstruct.total_jobs = 0;
1209         tstruct.lpq_time = time(NULL);
1210         tstruct.sharename = sharename;
1211         tstruct.lprm_command = lprm_command;
1212         tstruct.print_if = current_printif;
1213
1214         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1215
1216         /* Store the linearised queue, max jobs only. */
1217         store_queue_struct(pdb, &tstruct);
1218
1219         SAFE_FREE(tstruct.queue);
1220
1221         DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1222                                 sharename, tstruct.total_jobs ));
1223
1224         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1225
1226         get_queue_status(sharename, &old_status);
1227         if (old_status.qcount != qcount)
1228                 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1229                                         old_status.qcount, qcount, sharename));
1230
1231         /* store the new queue status structure */
1232         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1233         key = string_tdb_data(keystr);
1234
1235         status.qcount = qcount;
1236         data.dptr = (uint8 *)&status;
1237         data.dsize = sizeof(status);
1238         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
1239
1240         /*
1241          * Update the cache time again. We want to do this call
1242          * as little as possible...
1243          */
1244
1245         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1246         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1247
1248         /* clear the msg pending record for this queue */
1249
1250         snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1251
1252         if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1253                 /* log a message but continue on */
1254
1255                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1256                         sharename));
1257         }
1258
1259         release_print_db( pdb );
1260
1261         return;
1262 }
1263
1264 /****************************************************************************
1265  Update the internal database from the system print queue for a queue.
1266  obtain a lock on the print queue before proceeding (needed when mutiple
1267  smbd processes maytry to update the lpq cache concurrently).
1268 ****************************************************************************/
1269
1270 static void print_queue_update_with_lock( const char *sharename, 
1271                                           struct printif *current_printif,
1272                                           char *lpq_command, char *lprm_command )
1273 {
1274         fstring keystr;
1275         struct tdb_print_db *pdb;
1276
1277         DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1278         pdb = get_print_db_byname(sharename);
1279         if (!pdb)
1280                 return;
1281
1282         if ( !print_cache_expired(sharename, False) ) {
1283                 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1284                 release_print_db(pdb);
1285                 return;
1286         }
1287         
1288         /*
1289          * Check to see if someone else is doing this update.
1290          * This is essentially a mutex on the update.
1291          */
1292
1293         if (get_updating_pid(sharename) != -1) {
1294                 release_print_db(pdb);
1295                 return;
1296         }
1297
1298         /* Lock the queue for the database update */
1299
1300         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1301         /* Only wait 10 seconds for this. */
1302         if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1303                 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1304                 release_print_db(pdb);
1305                 return;
1306         }
1307
1308         /*
1309          * Ensure that no one else got in here.
1310          * If the updating pid is still -1 then we are
1311          * the winner.
1312          */
1313
1314         if (get_updating_pid(sharename) != -1) {
1315                 /*
1316                  * Someone else is doing the update, exit.
1317                  */
1318                 tdb_unlock_bystring(pdb->tdb, keystr);
1319                 release_print_db(pdb);
1320                 return;
1321         }
1322
1323         /*
1324          * We're going to do the update ourselves.
1325          */
1326
1327         /* Tell others we're doing the update. */
1328         set_updating_pid(sharename, True);
1329
1330         /*
1331          * Allow others to enter and notice we're doing
1332          * the update.
1333          */
1334
1335         tdb_unlock_bystring(pdb->tdb, keystr);
1336
1337         /* do the main work now */
1338         
1339         print_queue_update_internal( sharename, current_printif, 
1340                 lpq_command, lprm_command );
1341         
1342         /* Delete our pid from the db. */
1343         set_updating_pid(sharename, False);
1344         release_print_db(pdb);
1345 }
1346
1347 /****************************************************************************
1348 this is the receive function of the background lpq updater
1349 ****************************************************************************/
1350 static void print_queue_receive(struct messaging_context *msg,
1351                                 void *private_data,
1352                                 uint32_t msg_type,
1353                                 struct server_id server_id,
1354                                 DATA_BLOB *data)
1355 {
1356         fstring sharename;
1357         pstring lpqcommand, lprmcommand;
1358         int printing_type;
1359         size_t len;
1360
1361         len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1362                 sharename,
1363                 &printing_type,
1364                 lpqcommand,
1365                 lprmcommand );
1366
1367         if ( len == -1 ) {
1368                 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1369                 return;
1370         }
1371
1372         print_queue_update_with_lock(sharename, 
1373                 get_printer_fns_from_type((enum printing_types)printing_type),
1374                 lpqcommand, lprmcommand );
1375
1376         return;
1377 }
1378
1379 static pid_t background_lpq_updater_pid = -1;
1380
1381 /****************************************************************************
1382 main thread of the background lpq updater
1383 ****************************************************************************/
1384 void start_background_queue(void)
1385 {
1386         DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1387         background_lpq_updater_pid = sys_fork();
1388
1389         if (background_lpq_updater_pid == -1) {
1390                 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1391                 exit(1);
1392         }
1393
1394         if(background_lpq_updater_pid == 0) {
1395                 /* Child. */
1396                 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1397
1398                 claim_connection( NULL, "smbd lpq backend",
1399                         FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1400
1401                 if (!locking_init(0)) {
1402                         exit(1);
1403                 }
1404
1405                 messaging_register(smbd_messaging_context(), NULL,
1406                                    MSG_PRINTER_UPDATE, print_queue_receive);
1407                 
1408                 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1409                 while (1) {
1410                         pause();
1411                         
1412                         /* check for some essential signals first */
1413                         
1414                         if (got_sig_term) {
1415                                 exit_server_cleanly(NULL);
1416                         }
1417
1418                         if (reload_after_sighup) {
1419                                 change_to_root_user();
1420                                 DEBUG(1,("Reloading services after SIGHUP\n"));
1421                                 reload_services(False);
1422                                 reload_after_sighup = 0;
1423                         }
1424                         
1425                         /* now check for messages */
1426                         
1427                         DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1428                         message_dispatch(smbd_messaging_context());
1429
1430                         /* process any pending print change notify messages */
1431
1432                         print_notify_send_messages(smbd_messaging_context(),
1433                                                    0);
1434                 }
1435         }
1436 }
1437
1438 /****************************************************************************
1439 update the internal database from the system print queue for a queue
1440 ****************************************************************************/
1441
1442 static void print_queue_update(int snum, BOOL force)
1443 {
1444         fstring key;
1445         fstring sharename;
1446         pstring lpqcommand, lprmcommand;
1447         uint8 *buffer = NULL;
1448         size_t len = 0;
1449         size_t newlen;
1450         struct tdb_print_db *pdb;
1451         int type;
1452         struct printif *current_printif;
1453
1454         fstrcpy( sharename, lp_const_servicename(snum));
1455
1456         /* don't strip out characters like '$' from the printername */
1457         
1458         pstrcpy( lpqcommand, lp_lpqcommand(snum));
1459         string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), 
1460                      False, False, False );
1461         standard_sub_advanced(lp_servicename(snum),
1462                               current_user_info.unix_name, "",
1463                               current_user.ut.gid,
1464                               get_current_username(),
1465                               current_user_info.domain,
1466                               lpqcommand, sizeof(lpqcommand) );
1467         
1468         pstrcpy( lprmcommand, lp_lprmcommand(snum));
1469         string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), 
1470                      False, False, False );
1471         standard_sub_advanced(lp_servicename(snum),
1472                               current_user_info.unix_name, "",
1473                               current_user.ut.gid,
1474                               get_current_username(),
1475                               current_user_info.domain,
1476                               lprmcommand, sizeof(lprmcommand) );
1477         
1478         /* 
1479          * Make sure that the background queue process exists.  
1480          * Otherwise just do the update ourselves 
1481          */
1482         
1483         if ( force || background_lpq_updater_pid == -1 ) {
1484                 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1485                 current_printif = get_printer_fns( snum );
1486                 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1487
1488                 return;
1489         }
1490
1491         type = lp_printing(snum);
1492         
1493         /* get the length */
1494
1495         len = tdb_pack( NULL, 0, "fdPP",
1496                 sharename,
1497                 type,
1498                 lpqcommand, 
1499                 lprmcommand );
1500
1501         buffer = SMB_XMALLOC_ARRAY( uint8, len );
1502
1503         /* now pack the buffer */
1504         newlen = tdb_pack( buffer, len, "fdPP",
1505                 sharename,
1506                 type,
1507                 lpqcommand,
1508                 lprmcommand );
1509
1510         SMB_ASSERT( newlen == len );
1511
1512         DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1513                 "type = %d, lpq command = [%s] lprm command = [%s]\n", 
1514                 sharename, type, lpqcommand, lprmcommand ));
1515
1516         /* here we set a msg pending record for other smbd processes 
1517            to throttle the number of duplicate print_queue_update msgs
1518            sent.  */
1519
1520         pdb = get_print_db_byname(sharename);
1521         if (!pdb) {
1522                 SAFE_FREE(buffer);
1523                 return;
1524         }
1525
1526         snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1527
1528         if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1529                 /* log a message but continue on */
1530
1531                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1532                         sharename));
1533         }
1534
1535         release_print_db( pdb );
1536
1537         /* finally send the message */
1538         
1539         messaging_send_buf(smbd_messaging_context(),
1540                            pid_to_procid(background_lpq_updater_pid),
1541                            MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1542
1543         SAFE_FREE( buffer );
1544
1545         return;
1546 }
1547
1548 /****************************************************************************
1549  Create/Update an entry in the print tdb that will allow us to send notify
1550  updates only to interested smbd's. 
1551 ****************************************************************************/
1552
1553 BOOL print_notify_register_pid(int snum)
1554 {
1555         TDB_DATA data;
1556         struct tdb_print_db *pdb = NULL;
1557         TDB_CONTEXT *tdb = NULL;
1558         const char *printername;
1559         uint32 mypid = (uint32)sys_getpid();
1560         BOOL ret = False;
1561         size_t i;
1562
1563         /* if (snum == -1), then the change notify request was
1564            on a print server handle and we need to register on
1565            all print queus */
1566            
1567         if (snum == -1) 
1568         {
1569                 int num_services = lp_numservices();
1570                 int idx;
1571                 
1572                 for ( idx=0; idx<num_services; idx++ ) {
1573                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1574                                 print_notify_register_pid(idx);
1575                 }
1576                 
1577                 return True;
1578         }
1579         else /* register for a specific printer */
1580         {
1581                 printername = lp_const_servicename(snum);
1582                 pdb = get_print_db_byname(printername);
1583                 if (!pdb)
1584                         return False;
1585                 tdb = pdb->tdb;
1586         }
1587
1588         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1589                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1590                                         printername));
1591                 if (pdb)
1592                         release_print_db(pdb);
1593                 return False;
1594         }
1595
1596         data = get_printer_notify_pid_list( tdb, printername, True );
1597
1598         /* Add ourselves and increase the refcount. */
1599
1600         for (i = 0; i < data.dsize; i += 8) {
1601                 if (IVAL(data.dptr,i) == mypid) {
1602                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1603                         SIVAL(data.dptr, i+4, new_refcount);
1604                         break;
1605                 }
1606         }
1607
1608         if (i == data.dsize) {
1609                 /* We weren't in the list. Realloc. */
1610                 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1611                 if (!data.dptr) {
1612                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1613                                                 printername));
1614                         goto done;
1615                 }
1616                 data.dsize += 8;
1617                 SIVAL(data.dptr,data.dsize - 8,mypid);
1618                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1619         }
1620
1621         /* Store back the record. */
1622         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1623                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1624 list for printer %s\n", printername));
1625                 goto done;
1626         }
1627
1628         ret = True;
1629
1630  done:
1631
1632         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1633         if (pdb)
1634                 release_print_db(pdb);
1635         SAFE_FREE(data.dptr);
1636         return ret;
1637 }
1638
1639 /****************************************************************************
1640  Update an entry in the print tdb that will allow us to send notify
1641  updates only to interested smbd's. 
1642 ****************************************************************************/
1643
1644 BOOL print_notify_deregister_pid(int snum)
1645 {
1646         TDB_DATA data;
1647         struct tdb_print_db *pdb = NULL;
1648         TDB_CONTEXT *tdb = NULL;
1649         const char *printername;
1650         uint32 mypid = (uint32)sys_getpid();
1651         size_t i;
1652         BOOL ret = False;
1653
1654         /* if ( snum == -1 ), we are deregister a print server handle
1655            which means to deregister on all print queues */
1656            
1657         if (snum == -1) 
1658         {
1659                 int num_services = lp_numservices();
1660                 int idx;
1661                 
1662                 for ( idx=0; idx<num_services; idx++ ) {
1663                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1664                                 print_notify_deregister_pid(idx);
1665                 }
1666                 
1667                 return True;
1668         }
1669         else /* deregister a specific printer */
1670         {
1671                 printername = lp_const_servicename(snum);
1672                 pdb = get_print_db_byname(printername);
1673                 if (!pdb)
1674                         return False;
1675                 tdb = pdb->tdb;
1676         }
1677
1678         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1679                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1680 printer %s database\n", printername));
1681                 if (pdb)
1682                         release_print_db(pdb);
1683                 return False;
1684         }
1685
1686         data = get_printer_notify_pid_list( tdb, printername, True );
1687
1688         /* Reduce refcount. Remove ourselves if zero. */
1689
1690         for (i = 0; i < data.dsize; ) {
1691                 if (IVAL(data.dptr,i) == mypid) {
1692                         uint32 refcount = IVAL(data.dptr, i+4);
1693
1694                         refcount--;
1695
1696                         if (refcount == 0) {
1697                                 if (data.dsize - i > 8)
1698                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1699                                 data.dsize -= 8;
1700                                 continue;
1701                         }
1702                         SIVAL(data.dptr, i+4, refcount);
1703                 }
1704
1705                 i += 8;
1706         }
1707
1708         if (data.dsize == 0)
1709                 SAFE_FREE(data.dptr);
1710
1711         /* Store back the record. */
1712         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1713                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1714 list for printer %s\n", printername));
1715                 goto done;
1716         }
1717
1718         ret = True;
1719
1720   done:
1721
1722         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1723         if (pdb)
1724                 release_print_db(pdb);
1725         SAFE_FREE(data.dptr);
1726         return ret;
1727 }
1728
1729 /****************************************************************************
1730  Check if a jobid is valid. It is valid if it exists in the database.
1731 ****************************************************************************/
1732
1733 BOOL print_job_exists(const char* sharename, uint32 jobid)
1734 {
1735         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1736         BOOL ret;
1737
1738         if (!pdb)
1739                 return False;
1740         ret = tdb_exists(pdb->tdb, print_key(jobid));
1741         release_print_db(pdb);
1742         return ret;
1743 }
1744
1745 /****************************************************************************
1746  Give the fd used for a jobid.
1747 ****************************************************************************/
1748
1749 int print_job_fd(const char* sharename, uint32 jobid)
1750 {
1751         struct printjob *pjob = print_job_find(sharename, jobid);
1752         if (!pjob)
1753                 return -1;
1754         /* don't allow another process to get this info - it is meaningless */
1755         if (pjob->pid != sys_getpid())
1756                 return -1;
1757         return pjob->fd;
1758 }
1759
1760 /****************************************************************************
1761  Give the filename used for a jobid.
1762  Only valid for the process doing the spooling and when the job
1763  has not been spooled.
1764 ****************************************************************************/
1765
1766 char *print_job_fname(const char* sharename, uint32 jobid)
1767 {
1768         struct printjob *pjob = print_job_find(sharename, jobid);
1769         if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1770                 return NULL;
1771         return pjob->filename;
1772 }
1773
1774
1775 /****************************************************************************
1776  Give the filename used for a jobid.
1777  Only valid for the process doing the spooling and when the job
1778  has not been spooled.
1779 ****************************************************************************/
1780
1781 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1782 {
1783         struct printjob *pjob = print_job_find(sharename, jobid);
1784         
1785         if ( !pjob )
1786                 return NULL;
1787                 
1788         return pjob->nt_devmode;
1789 }
1790
1791 /****************************************************************************
1792  Set the place in the queue for a job.
1793 ****************************************************************************/
1794
1795 BOOL print_job_set_place(const char *sharename, uint32 jobid, int place)
1796 {
1797         DEBUG(2,("print_job_set_place not implemented yet\n"));
1798         return False;
1799 }
1800
1801 /****************************************************************************
1802  Set the name of a job. Only possible for owner.
1803 ****************************************************************************/
1804
1805 BOOL print_job_set_name(const char *sharename, uint32 jobid, char *name)
1806 {
1807         struct printjob *pjob;
1808
1809         pjob = print_job_find(sharename, jobid);
1810         if (!pjob || pjob->pid != sys_getpid())
1811                 return False;
1812
1813         fstrcpy(pjob->jobname, name);
1814         return pjob_store(sharename, jobid, pjob);
1815 }
1816
1817 /***************************************************************************
1818  Remove a jobid from the 'jobs changed' list.
1819 ***************************************************************************/
1820
1821 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1822 {
1823         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1824         TDB_DATA data, key;
1825         size_t job_count, i;
1826         BOOL ret = False;
1827         BOOL gotlock = False;
1828
1829         if (!pdb) {
1830                 return False;
1831         }
1832
1833         ZERO_STRUCT(data);
1834
1835         key = string_tdb_data("INFO/jobs_changed");
1836
1837         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1838                 goto out;
1839
1840         gotlock = True;
1841
1842         data = tdb_fetch(pdb->tdb, key);
1843
1844         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1845                 goto out;
1846
1847         job_count = data.dsize / 4;
1848         for (i = 0; i < job_count; i++) {
1849                 uint32 ch_jobid;
1850
1851                 ch_jobid = IVAL(data.dptr, i*4);
1852                 if (ch_jobid == jobid) {
1853                         if (i < job_count -1 )
1854                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1855                         data.dsize -= 4;
1856                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1857                                 goto out;
1858                         break;
1859                 }
1860         }
1861
1862         ret = True;
1863   out:
1864
1865         if (gotlock)
1866                 tdb_chainunlock(pdb->tdb, key);
1867         SAFE_FREE(data.dptr);
1868         release_print_db(pdb);
1869         if (ret)
1870                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1871         else
1872                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1873         return ret;
1874 }
1875
1876 /****************************************************************************
1877  Delete a print job - don't update queue.
1878 ****************************************************************************/
1879
1880 static BOOL print_job_delete1(int snum, uint32 jobid)
1881 {
1882         const char* sharename = lp_const_servicename(snum);
1883         struct printjob *pjob = print_job_find(sharename, jobid);
1884         int result = 0;
1885         struct printif *current_printif = get_printer_fns( snum );
1886
1887         if (!pjob)
1888                 return False;
1889
1890         /*
1891          * If already deleting just return.
1892          */
1893
1894         if (pjob->status == LPQ_DELETING)
1895                 return True;
1896
1897         /* Hrm - we need to be able to cope with deleting a job before it
1898            has reached the spooler.  Just mark it as LPQ_DELETING and 
1899            let the print_queue_update() code rmeove the record */
1900            
1901
1902         if (pjob->sysjob == -1) {
1903                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1904         }
1905
1906         /* Set the tdb entry to be deleting. */
1907
1908         pjob->status = LPQ_DELETING;
1909         pjob_store(sharename, jobid, pjob);
1910
1911         if (pjob->spooled && pjob->sysjob != -1) 
1912         {
1913                 result = (*(current_printif->job_delete))(
1914                         PRINTERNAME(snum),
1915                         lp_lprmcommand(snum), 
1916                         pjob);
1917
1918                 /* Delete the tdb entry if the delete succeeded or the job hasn't
1919                    been spooled. */
1920
1921                 if (result == 0) {
1922                         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1923                         int njobs = 1;
1924
1925                         if (!pdb)
1926                                 return False;
1927                         pjob_delete(sharename, jobid);
1928                         /* Ensure we keep a rough count of the number of total jobs... */
1929                         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1930                         release_print_db(pdb);
1931                 }
1932         }
1933
1934         remove_from_jobs_changed( sharename, jobid );
1935
1936         return (result == 0);
1937 }
1938
1939 /****************************************************************************
1940  Return true if the current user owns the print job.
1941 ****************************************************************************/
1942
1943 static BOOL is_owner(struct current_user *user, const char *servicename,
1944                      uint32 jobid)
1945 {
1946         struct printjob *pjob = print_job_find(servicename, jobid);
1947         user_struct *vuser;
1948
1949         if (!pjob || !user)
1950                 return False;
1951
1952         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1953                 return strequal(pjob->user, vuser->user.smb_name);
1954         } else {
1955                 return strequal(pjob->user, uidtoname(user->ut.uid));
1956         }
1957 }
1958
1959 /****************************************************************************
1960  Delete a print job.
1961 ****************************************************************************/
1962
1963 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1964 {
1965         const char* sharename = lp_const_servicename( snum );
1966         struct printjob *pjob;
1967         BOOL    owner;
1968         char    *fname;
1969
1970         *errcode = WERR_OK;
1971                 
1972         owner = is_owner(user, lp_const_servicename(snum), jobid);
1973         
1974         /* Check access against security descriptor or whether the user
1975            owns their job. */
1976
1977         if (!owner && 
1978             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1979                 DEBUG(3, ("delete denied by security descriptor\n"));
1980                 *errcode = WERR_ACCESS_DENIED;
1981
1982                 /* BEGIN_ADMIN_LOG */
1983                 sys_adminlog( LOG_ERR, 
1984                               "Permission denied-- user not allowed to delete, \
1985 pause, or resume print job. User name: %s. Printer name: %s.",
1986                               uidtoname(user->ut.uid), PRINTERNAME(snum) );
1987                 /* END_ADMIN_LOG */
1988
1989                 return False;
1990         }
1991
1992         /* 
1993          * get the spooled filename of the print job
1994          * if this works, then the file has not been spooled
1995          * to the underlying print system.  Just delete the 
1996          * spool file & return.
1997          */
1998          
1999         if ( (fname = print_job_fname( sharename, jobid )) != NULL )
2000         {
2001                 /* remove the spool file */
2002                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
2003                 if ( unlink( fname ) == -1 ) {
2004                         *errcode = map_werror_from_unix(errno);
2005                         return False;
2006                 }
2007         }
2008         
2009         if (!print_job_delete1(snum, jobid)) {
2010                 *errcode = WERR_ACCESS_DENIED;
2011                 return False;
2012         }
2013
2014         /* force update the database and say the delete failed if the
2015            job still exists */
2016
2017         print_queue_update(snum, True);
2018         
2019         pjob = print_job_find(sharename, jobid);
2020         if ( pjob && (pjob->status != LPQ_DELETING) )
2021                 *errcode = WERR_ACCESS_DENIED;
2022
2023         return (pjob == NULL );
2024 }
2025
2026 /****************************************************************************
2027  Pause a job.
2028 ****************************************************************************/
2029
2030 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
2031 {
2032         const char* sharename = lp_const_servicename(snum);
2033         struct printjob *pjob;
2034         int ret = -1;
2035         struct printif *current_printif = get_printer_fns( snum );
2036
2037         pjob = print_job_find(sharename, jobid);
2038         
2039         if (!pjob || !user) {
2040                 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2041                         (unsigned int)jobid ));
2042                 return False;
2043         }
2044
2045         if (!pjob->spooled || pjob->sysjob == -1) {
2046                 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2047                         (int)pjob->sysjob, (unsigned int)jobid ));
2048                 return False;
2049         }
2050
2051         if (!is_owner(user, lp_const_servicename(snum), jobid) &&
2052             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2053                 DEBUG(3, ("pause denied by security descriptor\n"));
2054
2055                 /* BEGIN_ADMIN_LOG */
2056                 sys_adminlog( LOG_ERR, 
2057                         "Permission denied-- user not allowed to delete, \
2058 pause, or resume print job. User name: %s. Printer name: %s.",
2059                                 uidtoname(user->ut.uid), PRINTERNAME(snum) );
2060                 /* END_ADMIN_LOG */
2061
2062                 *errcode = WERR_ACCESS_DENIED;
2063                 return False;
2064         }
2065
2066         /* need to pause the spooled entry */
2067         ret = (*(current_printif->job_pause))(snum, pjob);
2068
2069         if (ret != 0) {
2070                 *errcode = WERR_INVALID_PARAM;
2071                 return False;
2072         }
2073
2074         /* force update the database */
2075         print_cache_flush(lp_const_servicename(snum));
2076
2077         /* Send a printer notify message */
2078
2079         notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
2080
2081         /* how do we tell if this succeeded? */
2082
2083         return True;
2084 }
2085
2086 /****************************************************************************
2087  Resume a job.
2088 ****************************************************************************/
2089
2090 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
2091 {
2092         const char *sharename = lp_const_servicename(snum);
2093         struct printjob *pjob;
2094         int ret;
2095         struct printif *current_printif = get_printer_fns( snum );
2096
2097         pjob = print_job_find(sharename, jobid);
2098         
2099         if (!pjob || !user) {
2100                 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2101                         (unsigned int)jobid ));
2102                 return False;
2103         }
2104
2105         if (!pjob->spooled || pjob->sysjob == -1) {
2106                 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2107                         (int)pjob->sysjob, (unsigned int)jobid ));
2108                 return False;
2109         }
2110
2111         if (!is_owner(user, lp_const_servicename(snum), jobid) &&
2112             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2113                 DEBUG(3, ("resume denied by security descriptor\n"));
2114                 *errcode = WERR_ACCESS_DENIED;
2115
2116                 /* BEGIN_ADMIN_LOG */
2117                 sys_adminlog( LOG_ERR, 
2118                          "Permission denied-- user not allowed to delete, \
2119 pause, or resume print job. User name: %s. Printer name: %s.",
2120                         uidtoname(user->ut.uid), PRINTERNAME(snum) );
2121                 /* END_ADMIN_LOG */
2122                 return False;
2123         }
2124
2125         ret = (*(current_printif->job_resume))(snum, pjob);
2126
2127         if (ret != 0) {
2128                 *errcode = WERR_INVALID_PARAM;
2129                 return False;
2130         }
2131
2132         /* force update the database */
2133         print_cache_flush(lp_const_servicename(snum));
2134
2135         /* Send a printer notify message */
2136
2137         notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2138
2139         return True;
2140 }
2141
2142 /****************************************************************************
2143  Write to a print file.
2144 ****************************************************************************/
2145
2146 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2147 {
2148         const char* sharename = lp_const_servicename(snum);
2149         int return_code;
2150         struct printjob *pjob;
2151
2152         pjob = print_job_find(sharename, jobid);
2153
2154         if (!pjob)
2155                 return -1;
2156         /* don't allow another process to get this info - it is meaningless */
2157         if (pjob->pid != sys_getpid())
2158                 return -1;
2159
2160         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2161
2162         if (return_code>0) {
2163                 pjob->size += size;
2164                 pjob_store(sharename, jobid, pjob);
2165         }
2166         return return_code;
2167 }
2168
2169 /****************************************************************************
2170  Get the queue status - do not update if db is out of date.
2171 ****************************************************************************/
2172
2173 static int get_queue_status(const char* sharename, print_status_struct *status)
2174 {
2175         fstring keystr;
2176         TDB_DATA data;
2177         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2178         int len;
2179
2180         if (status) {
2181                 ZERO_STRUCTP(status);
2182         }
2183
2184         if (!pdb)
2185                 return 0;
2186
2187         if (status) {
2188                 fstr_sprintf(keystr, "STATUS/%s", sharename);
2189                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2190                 if (data.dptr) {
2191                         if (data.dsize == sizeof(print_status_struct))
2192                                 /* this memcpy is ok since the status struct was 
2193                                    not packed before storing it in the tdb */
2194                                 memcpy(status, data.dptr, sizeof(print_status_struct));
2195                         SAFE_FREE(data.dptr);
2196                 }
2197         }
2198         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2199         release_print_db(pdb);
2200         return (len == -1 ? 0 : len);
2201 }
2202
2203 /****************************************************************************
2204  Determine the number of jobs in a queue.
2205 ****************************************************************************/
2206
2207 int print_queue_length(int snum, print_status_struct *pstatus)
2208 {
2209         const char* sharename = lp_const_servicename( snum );
2210         print_status_struct status;
2211         int len;
2212
2213         ZERO_STRUCT( status );
2214  
2215         /* make sure the database is up to date */
2216         if (print_cache_expired(lp_const_servicename(snum), True))
2217                 print_queue_update(snum, False);
2218  
2219         /* also fetch the queue status */
2220         memset(&status, 0, sizeof(status));
2221         len = get_queue_status(sharename, &status);
2222
2223         if (pstatus)
2224                 *pstatus = status;
2225
2226         return len;
2227 }
2228
2229 /***************************************************************************
2230  Allocate a jobid. Hold the lock for as short a time as possible.
2231 ***************************************************************************/
2232
2233 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2234 {
2235         int i;
2236         uint32 jobid;
2237
2238         *pjobid = (uint32)-1;
2239
2240         for (i = 0; i < 3; i++) {
2241                 /* Lock the database - only wait 20 seconds. */
2242                 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) {
2243                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2244                         return False;
2245                 }
2246
2247                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2248                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2249                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2250                                         sharename));
2251                                 return False;
2252                         }
2253                         jobid = 0;
2254                 }
2255
2256                 jobid = NEXT_JOBID(jobid);
2257
2258                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2259                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2260                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2261                         return False;
2262                 }
2263
2264                 /* We've finished with the INFO/nextjob lock. */
2265                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2266                                 
2267                 if (!print_job_exists(sharename, jobid))
2268                         break;
2269         }
2270
2271         if (i > 2) {
2272                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2273                         sharename));
2274                 /* Probably full... */
2275                 errno = ENOSPC;
2276                 return False;
2277         }
2278
2279         /* Store a dummy placeholder. */
2280         {
2281                 TDB_DATA dum;
2282                 dum.dptr = NULL;
2283                 dum.dsize = 0;
2284                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2285                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2286                                 jobid ));
2287                         return False;
2288                 }
2289         }
2290
2291         *pjobid = jobid;
2292         return True;
2293 }
2294
2295 /***************************************************************************
2296  Append a jobid to the 'jobs changed' list.
2297 ***************************************************************************/
2298
2299 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2300 {
2301         TDB_DATA data;
2302         uint32 store_jobid;
2303
2304         SIVAL(&store_jobid, 0, jobid);
2305         data.dptr = (uint8 *)&store_jobid;
2306         data.dsize = 4;
2307
2308         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2309
2310         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2311                            data) == 0);
2312 }
2313
2314 /***************************************************************************
2315  Start spooling a job - return the jobid.
2316 ***************************************************************************/
2317
2318 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2319 {
2320         uint32 jobid;
2321         char *path;
2322         struct printjob pjob;
2323         user_struct *vuser;
2324         const char *sharename = lp_const_servicename(snum);
2325         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2326         int njobs;
2327
2328         errno = 0;
2329
2330         if (!pdb)
2331                 return (uint32)-1;
2332
2333         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2334                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2335                 release_print_db(pdb);
2336                 return (uint32)-1;
2337         }
2338
2339         if (!print_time_access_check(lp_servicename(snum))) {
2340                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2341                 release_print_db(pdb);
2342                 return (uint32)-1;
2343         }
2344
2345         path = lp_pathname(snum);
2346
2347         /* see if we have sufficient disk space */
2348         if (lp_minprintspace(snum)) {
2349                 SMB_BIG_UINT dspace, dsize;
2350                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2351                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2352                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
2353                         release_print_db(pdb);
2354                         errno = ENOSPC;
2355                         return (uint32)-1;
2356                 }
2357         }
2358
2359         /* for autoloaded printers, check that the printcap entry still exists */
2360         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2361                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2362                 release_print_db(pdb);
2363                 errno = ENOENT;
2364                 return (uint32)-1;
2365         }
2366
2367         /* Insure the maximum queue size is not violated */
2368         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2369                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2370                         sharename, njobs, lp_maxprintjobs(snum) ));
2371                 release_print_db(pdb);
2372                 errno = ENOSPC;
2373                 return (uint32)-1;
2374         }
2375
2376         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2377                 sharename, njobs, lp_maxprintjobs(snum) ));
2378
2379         if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2380                 goto fail;
2381
2382         /* create the database entry */
2383         
2384         ZERO_STRUCT(pjob);
2385         
2386         pjob.pid = sys_getpid();
2387         pjob.sysjob = -1;
2388         pjob.fd = -1;
2389         pjob.starttime = time(NULL);
2390         pjob.status = LPQ_SPOOLING;
2391         pjob.size = 0;
2392         pjob.spooled = False;
2393         pjob.smbjob = True;
2394         pjob.nt_devmode = nt_devmode;
2395         
2396         fstrcpy(pjob.jobname, jobname);
2397
2398         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2399                 fstrcpy(pjob.user, lp_printjob_username(snum));
2400                 standard_sub_basic(vuser->user.smb_name, vuser->user.domain, 
2401                                    pjob.user, sizeof(pjob.user)-1);
2402                 /* ensure NULL termination */ 
2403                 pjob.user[sizeof(pjob.user)-1] = '\0'; 
2404         } else {
2405                 fstrcpy(pjob.user, uidtoname(user->ut.uid));
2406         }
2407
2408         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2409
2410         /* we have a job entry - now create the spool file */
2411         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
2412                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2413         pjob.fd = smb_mkstemp(pjob.filename);
2414
2415         if (pjob.fd == -1) {
2416                 if (errno == EACCES) {
2417                         /* Common setup error, force a report. */
2418                         DEBUG(0, ("print_job_start: insufficient permissions \
2419 to open spool file %s.\n", pjob.filename));
2420                 } else {
2421                         /* Normal case, report at level 3 and above. */
2422                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2423                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2424                 }
2425                 goto fail;
2426         }
2427
2428         pjob_store(sharename, jobid, &pjob);
2429
2430         /* Update the 'jobs changed' entry used by print_queue_status. */
2431         add_to_jobs_changed(pdb, jobid);
2432
2433         /* Ensure we keep a rough count of the number of total jobs... */
2434         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2435
2436         release_print_db(pdb);
2437
2438         return jobid;
2439
2440  fail:
2441         if (jobid != -1)
2442                 pjob_delete(sharename, jobid);
2443
2444         release_print_db(pdb);
2445
2446         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2447         return (uint32)-1;
2448 }
2449
2450 /****************************************************************************
2451  Update the number of pages spooled to jobid
2452 ****************************************************************************/
2453
2454 void print_job_endpage(int snum, uint32 jobid)
2455 {
2456         const char* sharename = lp_const_servicename(snum);
2457         struct printjob *pjob;
2458
2459         pjob = print_job_find(sharename, jobid);
2460         if (!pjob)
2461                 return;
2462         /* don't allow another process to get this info - it is meaningless */
2463         if (pjob->pid != sys_getpid())
2464                 return;
2465
2466         pjob->page_count++;
2467         pjob_store(sharename, jobid, pjob);
2468 }
2469
2470 /****************************************************************************
2471  Print a file - called on closing the file. This spools the job.
2472  If normal close is false then we're tearing down the jobs - treat as an
2473  error.
2474 ****************************************************************************/
2475
2476 BOOL print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
2477 {
2478         const char* sharename = lp_const_servicename(snum);
2479         struct printjob *pjob;
2480         int ret;
2481         SMB_STRUCT_STAT sbuf;
2482         struct printif *current_printif = get_printer_fns( snum );
2483
2484         pjob = print_job_find(sharename, jobid);
2485
2486         if (!pjob)
2487                 return False;
2488
2489         if (pjob->spooled || pjob->pid != sys_getpid())
2490                 return False;
2491
2492         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
2493                                 (sys_fstat(pjob->fd, &sbuf) == 0)) {
2494                 pjob->size = sbuf.st_size;
2495                 close(pjob->fd);
2496                 pjob->fd = -1;
2497         } else {
2498
2499                 /* 
2500                  * Not a normal close or we couldn't stat the job file,
2501                  * so something has gone wrong. Cleanup.
2502                  */
2503                 close(pjob->fd);
2504                 pjob->fd = -1;
2505                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2506                 goto fail;
2507         }
2508
2509         /* Technically, this is not quite right. If the printer has a separator
2510          * page turned on, the NT spooler prints the separator page even if the
2511          * print job is 0 bytes. 010215 JRR */
2512         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2513                 /* don't bother spooling empty files or something being deleted. */
2514                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2515                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2516                 unlink(pjob->filename);
2517                 pjob_delete(sharename, jobid);
2518                 return True;
2519         }
2520
2521         pjob->smbjob = jobid;
2522
2523         ret = (*(current_printif->job_submit))(snum, pjob);
2524
2525         if (ret)
2526                 goto fail;
2527
2528         /* The print job has been sucessfully handed over to the back-end */
2529         
2530         pjob->spooled = True;
2531         pjob->status = LPQ_QUEUED;
2532         pjob_store(sharename, jobid, pjob);
2533         
2534         /* make sure the database is up to date */
2535         if (print_cache_expired(lp_const_servicename(snum), True))
2536                 print_queue_update(snum, False);
2537         
2538         return True;
2539
2540 fail:
2541
2542         /* The print job was not succesfully started. Cleanup */
2543         /* Still need to add proper error return propagation! 010122:JRR */
2544         unlink(pjob->filename);
2545         pjob_delete(sharename, jobid);
2546         return False;
2547 }
2548
2549 /****************************************************************************
2550  Get a snapshot of jobs in the system without traversing.
2551 ****************************************************************************/
2552
2553 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2554 {
2555         TDB_DATA data, cgdata;
2556         print_queue_struct *queue = NULL;
2557         uint32 qcount = 0;
2558         uint32 extra_count = 0;
2559         int total_count = 0;
2560         size_t len = 0;
2561         uint32 i;
2562         int max_reported_jobs = lp_max_reported_jobs(snum);
2563         BOOL ret = False;
2564         const char* sharename = lp_servicename(snum);
2565
2566         /* make sure the database is up to date */
2567         if (print_cache_expired(lp_const_servicename(snum), True))
2568                 print_queue_update(snum, False);
2569  
2570         *pcount = 0;
2571         *ppqueue = NULL;
2572
2573         ZERO_STRUCT(data);
2574         ZERO_STRUCT(cgdata);
2575
2576         /* Get the stored queue data. */
2577         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2578         
2579         if (data.dptr && data.dsize >= sizeof(qcount))
2580                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2581                 
2582         /* Get the changed jobs list. */
2583         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2584         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2585                 extra_count = cgdata.dsize/4;
2586
2587         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2588
2589         /* Allocate the queue size. */
2590         if (qcount == 0 && extra_count == 0)
2591                 goto out;
2592
2593         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2594                 goto out;
2595
2596         /* Retrieve the linearised queue data. */
2597
2598         for( i  = 0; i < qcount; i++) {
2599                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2600                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2601                                 &qjob,
2602                                 &qsize,
2603                                 &qpage_count,
2604                                 &qstatus,
2605                                 &qpriority,
2606                                 &qtime,
2607                                 queue[i].fs_user,
2608                                 queue[i].fs_file);
2609                 queue[i].job = qjob;
2610                 queue[i].size = qsize;
2611                 queue[i].page_count = qpage_count;
2612                 queue[i].status = qstatus;
2613                 queue[i].priority = qpriority;
2614                 queue[i].time = qtime;
2615         }
2616
2617         total_count = qcount;
2618
2619         /* Add in the changed jobids. */
2620         for( i  = 0; i < extra_count; i++) {
2621                 uint32 jobid;
2622                 struct printjob *pjob;
2623
2624                 jobid = IVAL(cgdata.dptr, i*4);
2625                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2626                 pjob = print_job_find(lp_const_servicename(snum), jobid);
2627                 if (!pjob) {
2628                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2629                         remove_from_jobs_changed(sharename, jobid);
2630                         continue;
2631                 }
2632
2633                 queue[total_count].job = jobid;
2634                 queue[total_count].size = pjob->size;
2635                 queue[total_count].page_count = pjob->page_count;
2636                 queue[total_count].status = pjob->status;
2637                 queue[total_count].priority = 1;
2638                 queue[total_count].time = pjob->starttime;
2639                 fstrcpy(queue[total_count].fs_user, pjob->user);
2640                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2641                 total_count++;
2642         }
2643
2644         /* Sort the queue by submission time otherwise they are displayed
2645            in hash order. */
2646
2647         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2648
2649         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2650
2651         if (max_reported_jobs && total_count > max_reported_jobs)
2652                 total_count = max_reported_jobs;
2653
2654         *ppqueue = queue;
2655         *pcount = total_count;
2656
2657         ret = True;
2658
2659   out:
2660
2661         SAFE_FREE(data.dptr);
2662         SAFE_FREE(cgdata.dptr);
2663         return ret;
2664 }
2665
2666 /****************************************************************************
2667  Get a printer queue listing.
2668  set queue = NULL and status = NULL if you just want to update the cache
2669 ****************************************************************************/
2670
2671 int print_queue_status(int snum, 
2672                        print_queue_struct **ppqueue,
2673                        print_status_struct *status)
2674 {
2675         fstring keystr;
2676         TDB_DATA data, key;
2677         const char *sharename;
2678         struct tdb_print_db *pdb;
2679         int count = 0;
2680
2681         /* make sure the database is up to date */
2682
2683         if (print_cache_expired(lp_const_servicename(snum), True))
2684                 print_queue_update(snum, False);
2685
2686         /* return if we are done */
2687         if ( !ppqueue || !status )
2688                 return 0;
2689
2690         *ppqueue = NULL;
2691         sharename = lp_const_servicename(snum);
2692         pdb = get_print_db_byname(sharename);
2693
2694         if (!pdb)
2695                 return 0;
2696
2697         /*
2698          * Fetch the queue status.  We must do this first, as there may
2699          * be no jobs in the queue.
2700          */
2701
2702         ZERO_STRUCTP(status);
2703         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2704         key = string_tdb_data(keystr);
2705
2706         data = tdb_fetch(pdb->tdb, key);
2707         if (data.dptr) {
2708                 if (data.dsize == sizeof(*status)) {
2709                         /* this memcpy is ok since the status struct was 
2710                            not packed before storing it in the tdb */
2711                         memcpy(status, data.dptr, sizeof(*status));
2712                 }
2713                 SAFE_FREE(data.dptr);
2714         }
2715
2716         /*
2717          * Now, fetch the print queue information.  We first count the number
2718          * of entries, and then only retrieve the queue if necessary.
2719          */
2720
2721         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2722                 release_print_db(pdb);
2723                 return 0;
2724         }
2725
2726         release_print_db(pdb);
2727         return count;
2728 }
2729
2730 /****************************************************************************
2731  Pause a queue.
2732 ****************************************************************************/
2733
2734 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2735 {
2736         int ret;
2737         struct printif *current_printif = get_printer_fns( snum );
2738         
2739         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2740                 *errcode = WERR_ACCESS_DENIED;
2741                 return False;
2742         }
2743         
2744
2745         become_root();
2746                 
2747         ret = (*(current_printif->queue_pause))(snum);
2748
2749         unbecome_root();
2750                 
2751         if (ret != 0) {
2752                 *errcode = WERR_INVALID_PARAM;
2753                 return False;
2754         }
2755
2756         /* force update the database */
2757         print_cache_flush(lp_const_servicename(snum));
2758
2759         /* Send a printer notify message */
2760
2761         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2762
2763         return True;
2764 }
2765
2766 /****************************************************************************
2767  Resume a queue.
2768 ****************************************************************************/
2769
2770 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2771 {
2772         int ret;
2773         struct printif *current_printif = get_printer_fns( snum );
2774
2775         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2776                 *errcode = WERR_ACCESS_DENIED;
2777                 return False;
2778         }
2779         
2780         become_root();
2781                 
2782         ret = (*(current_printif->queue_resume))(snum);
2783
2784         unbecome_root();
2785                 
2786         if (ret != 0) {
2787                 *errcode = WERR_INVALID_PARAM;
2788                 return False;
2789         }
2790
2791         /* make sure the database is up to date */
2792         if (print_cache_expired(lp_const_servicename(snum), True))
2793                 print_queue_update(snum, True);
2794
2795         /* Send a printer notify message */
2796
2797         notify_printer_status(snum, PRINTER_STATUS_OK);
2798
2799         return True;
2800 }
2801
2802 /****************************************************************************
2803  Purge a queue - implemented by deleting all jobs that we can delete.
2804 ****************************************************************************/
2805
2806 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2807 {
2808         print_queue_struct *queue;
2809         print_status_struct status;
2810         int njobs, i;
2811         BOOL can_job_admin;
2812
2813         /* Force and update so the count is accurate (i.e. not a cached count) */
2814         print_queue_update(snum, True);
2815         
2816         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2817         njobs = print_queue_status(snum, &queue, &status);
2818         
2819         if ( can_job_admin )
2820                 become_root();
2821
2822         for (i=0;i<njobs;i++) {
2823                 BOOL owner = is_owner(user, lp_const_servicename(snum), queue[i].job);
2824
2825                 if (owner || can_job_admin) {
2826                         print_job_delete1(snum, queue[i].job);
2827                 }
2828         }
2829         
2830         if ( can_job_admin )
2831                 unbecome_root();
2832
2833         /* update the cache */
2834         print_queue_update( snum, True );
2835
2836         SAFE_FREE(queue);
2837
2838         return True;
2839 }