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