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