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