r10555: a few compile warnings from jason Mader
[ira/wip.git] / source3 / printing / printing.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing backend routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    Copyright (C) Jeremy Allison 2002
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 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 };
695
696 /****************************************************************************
697  Utility fn to delete any jobs that are no longer active.
698 ****************************************************************************/
699
700 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
701 {
702         struct traverse_struct *ts = (struct traverse_struct *)state;
703         struct printjob pjob;
704         uint32 jobid;
705         int i = 0;
706
707         if (  key.dsize != sizeof(jobid) )
708                 return 0;
709                 
710         jobid = IVAL(key.dptr, 0);
711         if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
712                 return 0;
713         free_nt_devicemode( &pjob.nt_devmode );
714
715
716         if (!pjob.smbjob) {
717                 /* remove a unix job if it isn't in the system queue any more */
718
719                 for (i=0;i<ts->qcount;i++) {
720                         uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
721                         if (jobid == u_jobid)
722                                 break;
723                 }
724                 if (i == ts->qcount) {
725                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
726                                                 (unsigned int)jobid ));
727                         pjob_delete(ts->sharename, jobid);
728                         return 0;
729                 } 
730
731                 /* need to continue the the bottom of the function to
732                    save the correct attributes */
733         }
734
735         /* maybe it hasn't been spooled yet */
736         if (!pjob.spooled) {
737                 /* if a job is not spooled and the process doesn't
738                    exist then kill it. This cleans up after smbd
739                    deaths */
740                 if (!process_exists(pjob.pid)) {
741                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
742                                                 (unsigned int)jobid, (unsigned int)pjob.pid ));
743                         pjob_delete(ts->sharename, jobid);
744                 } else
745                         ts->total_jobs++;
746                 return 0;
747         }
748
749         /* this check only makes sense for jobs submitted from Windows clients */
750         
751         if ( pjob.smbjob ) {
752                 for (i=0;i<ts->qcount;i++) {
753                         uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
754                         if (jobid == curr_jobid)
755                                 break;
756                 }
757         }
758         
759         /* The job isn't in the system queue - we have to assume it has
760            completed, so delete the database entry. */
761
762         if (i == ts->qcount) {
763
764                 /* A race can occur between the time a job is spooled and
765                    when it appears in the lpq output.  This happens when
766                    the job is added to printing.tdb when another smbd
767                    running print_queue_update() has completed a lpq and
768                    is currently traversing the printing tdb and deleting jobs.
769                    Don't delete the job if it was submitted after the lpq_time. */
770
771                 if (pjob.starttime < ts->lpq_time) {
772                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
773                                                 (unsigned int)jobid,
774                                                 (unsigned int)pjob.starttime,
775                                                 (unsigned int)ts->lpq_time ));
776                         pjob_delete(ts->sharename, jobid);
777                 } else
778                         ts->total_jobs++;
779                 return 0;
780         }
781
782         /* Save the pjob attributes we will store. */
783         /* FIXME!!! This is the only place where queue->job 
784            represents the SMB jobid      --jerry */
785         ts->queue[i].job = jobid;               
786         ts->queue[i].size = pjob.size;
787         ts->queue[i].page_count = pjob.page_count;
788         ts->queue[i].status = pjob.status;
789         ts->queue[i].priority = 1;
790         ts->queue[i].time = pjob.starttime;
791         fstrcpy(ts->queue[i].fs_user, pjob.user);
792         fstrcpy(ts->queue[i].fs_file, pjob.jobname);
793
794         ts->total_jobs++;
795
796         return 0;
797 }
798
799 /****************************************************************************
800  Check if the print queue has been updated recently enough.
801 ****************************************************************************/
802
803 static void print_cache_flush(int snum)
804 {
805         fstring key;
806         const char *sharename = lp_const_servicename(snum);
807         struct tdb_print_db *pdb = get_print_db_byname(sharename);
808
809         if (!pdb)
810                 return;
811         slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
812         tdb_store_int32(pdb->tdb, key, -1);
813         release_print_db(pdb);
814 }
815
816 /****************************************************************************
817  Check if someone already thinks they are doing the update.
818 ****************************************************************************/
819
820 static pid_t get_updating_pid(const char *sharename)
821 {
822         fstring keystr;
823         TDB_DATA data, key;
824         pid_t updating_pid;
825         struct tdb_print_db *pdb = get_print_db_byname(sharename);
826
827         if (!pdb)
828                 return (pid_t)-1;
829         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
830         key.dptr = keystr;
831         key.dsize = strlen(keystr);
832
833         data = tdb_fetch(pdb->tdb, key);
834         release_print_db(pdb);
835         if (!data.dptr || data.dsize != sizeof(pid_t)) {
836                 SAFE_FREE(data.dptr);
837                 return (pid_t)-1;
838         }
839
840         updating_pid = IVAL(data.dptr, 0);
841         SAFE_FREE(data.dptr);
842
843         if (process_exists(updating_pid))
844                 return updating_pid;
845
846         return (pid_t)-1;
847 }
848
849 /****************************************************************************
850  Set the fact that we're doing the update, or have finished doing the update
851  in the tdb.
852 ****************************************************************************/
853
854 static void set_updating_pid(const fstring sharename, BOOL updating)
855 {
856         fstring keystr;
857         TDB_DATA key;
858         TDB_DATA data;
859         pid_t updating_pid = sys_getpid();
860         uint8 buffer[4];
861         
862         struct tdb_print_db *pdb = get_print_db_byname(sharename);
863
864         if (!pdb)
865                 return;
866
867         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
868         key.dptr = keystr;
869         key.dsize = strlen(keystr);
870         
871         DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", 
872                 updating ? "" : "not ",
873                 sharename ));
874
875         if ( !updating ) {
876                 tdb_delete(pdb->tdb, key);
877                 release_print_db(pdb);
878                 return;
879         }
880         
881         SIVAL( buffer, 0, updating_pid);
882         data.dptr = (void *)buffer;
883         data.dsize = 4;         /* we always assume this is a 4 byte value */
884
885         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
886         release_print_db(pdb);
887 }
888
889 /****************************************************************************
890  Sort print jobs by submittal time.
891 ****************************************************************************/
892
893 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
894 {
895         /* Silly cases */
896
897         if (!j1 && !j2)
898                 return 0;
899         if (!j1)
900                 return -1;
901         if (!j2)
902                 return 1;
903
904         /* Sort on job start time */
905
906         if (j1->time == j2->time)
907                 return 0;
908         return (j1->time > j2->time) ? 1 : -1;
909 }
910
911 /****************************************************************************
912  Store the sorted queue representation for later portmon retrieval.
913 ****************************************************************************/
914
915 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
916 {
917         TDB_DATA data;
918         int max_reported_jobs = lp_max_reported_jobs(pts->snum);
919         print_queue_struct *queue = pts->queue;
920         size_t len;
921         size_t i;
922         uint qcount;
923
924         if (max_reported_jobs && (max_reported_jobs < pts->qcount))
925                 pts->qcount = max_reported_jobs;
926         qcount = pts->qcount;
927
928         /* Work out the size. */
929         data.dsize = 0;
930         data.dsize += tdb_pack(NULL, 0, "d", qcount);
931
932         for (i = 0; i < pts->qcount; i++) {
933                 data.dsize += tdb_pack(NULL, 0, "ddddddff",
934                                 (uint32)queue[i].job,
935                                 (uint32)queue[i].size,
936                                 (uint32)queue[i].page_count,
937                                 (uint32)queue[i].status,
938                                 (uint32)queue[i].priority,
939                                 (uint32)queue[i].time,
940                                 queue[i].fs_user,
941                                 queue[i].fs_file);
942         }
943
944         if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL)
945                 return;
946
947         len = 0;
948         len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
949         for (i = 0; i < pts->qcount; i++) {
950                 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
951                                 (uint32)queue[i].job,
952                                 (uint32)queue[i].size,
953                                 (uint32)queue[i].page_count,
954                                 (uint32)queue[i].status,
955                                 (uint32)queue[i].priority,
956                                 (uint32)queue[i].time,
957                                 queue[i].fs_user,
958                                 queue[i].fs_file);
959         }
960
961         tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
962                   TDB_REPLACE);
963         SAFE_FREE(data.dptr);
964         return;
965 }
966
967 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
968 {
969         TDB_DATA data;
970
971         ZERO_STRUCT(data);
972
973         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
974         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
975                 SAFE_FREE(data.dptr);
976                 ZERO_STRUCT(data);
977         }
978
979         return data;
980 }
981
982 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
983 {
984         unsigned int i;
985         unsigned int job_count = data.dsize / 4;
986
987         for (i = 0; i < job_count; i++) {
988                 uint32 ch_jobid;
989
990                 ch_jobid = IVAL(data.dptr, i*4);
991                 if (ch_jobid == jobid)
992                         remove_from_jobs_changed(sharename, jobid);
993         }
994 }
995
996 /****************************************************************************
997  Check if the print queue has been updated recently enough.
998 ****************************************************************************/
999
1000 static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
1001 {
1002         fstring key;
1003         time_t last_qscan_time, time_now = time(NULL);
1004         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1005         BOOL result = False;
1006
1007         if (!pdb)
1008                 return False;
1009
1010         snprintf(key, sizeof(key), "CACHE/%s", sharename);
1011         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1012
1013         /*
1014          * Invalidate the queue for 3 reasons.
1015          * (1). last queue scan time == -1.
1016          * (2). Current time - last queue scan time > allowed cache time.
1017          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1018          * This last test picks up machines for which the clock has been moved
1019          * forward, an lpq scan done and then the clock moved back. Otherwise
1020          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1021          */
1022
1023         if (last_qscan_time == ((time_t)-1) 
1024                 || (time_now - last_qscan_time) >= lp_lpqcachetime() 
1025                 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) 
1026         {
1027                 time_t msg_pending_time;
1028
1029                 DEBUG(4, ("print_cache_expired: cache expired for queue %s " 
1030                         "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", 
1031                         sharename, (int)last_qscan_time, (int)time_now, 
1032                         (int)lp_lpqcachetime() ));
1033
1034                 /* check if another smbd has already sent a message to update the 
1035                    queue.  Give the pending message one minute to clear and 
1036                    then send another message anyways.  Make sure to check for 
1037                    clocks that have been run forward and then back again. */
1038
1039                 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1040
1041                 if ( check_pending 
1042                         && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time ) 
1043                         && msg_pending_time > 0
1044                         && msg_pending_time <= time_now 
1045                         && (time_now - msg_pending_time) < 60 ) 
1046                 {
1047                         DEBUG(4,("print_cache_expired: message already pending for %s.  Accepting cache\n",
1048                                 sharename));
1049                         goto done;
1050                 }
1051                 
1052                 result = True;
1053         }
1054
1055 done:
1056         release_print_db(pdb);
1057         return result;
1058 }
1059
1060 /****************************************************************************
1061  main work for updating the lpq cahe for a printer queue
1062 ****************************************************************************/
1063
1064 static void print_queue_update_internal( const char *sharename, 
1065                                          struct printif *current_printif,
1066                                          char *lpq_command )
1067 {
1068         int i, qcount;
1069         print_queue_struct *queue = NULL;
1070         print_status_struct status;
1071         print_status_struct old_status;
1072         struct printjob *pjob;
1073         struct traverse_struct tstruct;
1074         TDB_DATA data, key;
1075         TDB_DATA jcdata;
1076         fstring keystr, cachestr;
1077         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1078
1079         if (!pdb) {
1080                 return;
1081         }
1082         
1083         DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1084                 sharename, current_printif->type, lpq_command));
1085
1086         /*
1087          * Update the cache time FIRST ! Stops others even
1088          * attempting to get the lock and doing this
1089          * if the lpq takes a long time.
1090          */
1091          
1092         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1093         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1094
1095         /* get the current queue using the appropriate interface */
1096         ZERO_STRUCT(status);
1097
1098         qcount = (*(current_printif->queue_get))(sharename, 
1099                 current_printif->type, 
1100                 lpq_command, &queue, &status);
1101
1102         DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n", 
1103                 qcount, (qcount != 1) ? "s" : "", sharename));
1104
1105         /* Sort the queue by submission time otherwise they are displayed
1106            in hash order. */
1107
1108         qsort(queue, qcount, sizeof(print_queue_struct),
1109                 QSORT_CAST(printjob_comp));
1110
1111         /*
1112           any job in the internal database that is marked as spooled
1113           and doesn't exist in the system queue is considered finished
1114           and removed from the database
1115
1116           any job in the system database but not in the internal database 
1117           is added as a unix job
1118
1119           fill in any system job numbers as we go
1120         */
1121
1122         jcdata = get_jobs_changed_data(pdb);
1123
1124         for (i=0; i<qcount; i++) {
1125                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1126
1127                 if (jobid == (uint32)-1) {
1128                         /* assume its a unix print job */
1129                         print_unix_job(sharename, &queue[i], jobid);
1130                         continue;
1131                 }
1132
1133                 /* we have an active SMB print job - update its status */
1134                 pjob = print_job_find(sharename, jobid);
1135                 if (!pjob) {
1136                         /* err, somethings wrong. Probably smbd was restarted
1137                            with jobs in the queue. All we can do is treat them
1138                            like unix jobs. Pity. */
1139                         print_unix_job(sharename, &queue[i], jobid);
1140                         continue;
1141                 }
1142
1143                 pjob->sysjob = queue[i].job;
1144                 pjob->status = queue[i].status;
1145                 pjob_store(sharename, jobid, pjob);
1146                 check_job_changed(sharename, jcdata, jobid);
1147         }
1148
1149         SAFE_FREE(jcdata.dptr);
1150
1151         /* now delete any queued entries that don't appear in the
1152            system queue */
1153         tstruct.queue = queue;
1154         tstruct.qcount = qcount;
1155         tstruct.snum = -1;
1156         tstruct.total_jobs = 0;
1157         tstruct.lpq_time = time(NULL);
1158         tstruct.sharename = sharename;
1159
1160         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1161
1162         /* Store the linearised queue, max jobs only. */
1163         store_queue_struct(pdb, &tstruct);
1164
1165         SAFE_FREE(tstruct.queue);
1166
1167         DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1168                                 sharename, tstruct.total_jobs ));
1169
1170         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1171
1172         get_queue_status(sharename, &old_status);
1173         if (old_status.qcount != qcount)
1174                 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1175                                         old_status.qcount, qcount, sharename));
1176
1177         /* store the new queue status structure */
1178         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1179         key.dptr = keystr;
1180         key.dsize = strlen(keystr);
1181
1182         status.qcount = qcount;
1183         data.dptr = (void *)&status;
1184         data.dsize = sizeof(status);
1185         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
1186
1187         /*
1188          * Update the cache time again. We want to do this call
1189          * as little as possible...
1190          */
1191
1192         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1193         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1194
1195         /* clear the msg pending record for this queue */
1196
1197         snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1198
1199         if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1200                 /* log a message but continue on */
1201
1202                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1203                         sharename));
1204         }
1205
1206         release_print_db( pdb );
1207
1208         return;
1209 }
1210
1211 /****************************************************************************
1212  Update the internal database from the system print queue for a queue.
1213  obtain a lock on the print queue before proceeding (needed when mutiple
1214  smbd processes maytry to update the lpq cache concurrently).
1215 ****************************************************************************/
1216
1217 static void print_queue_update_with_lock( const char *sharename, 
1218                                           struct printif *current_printif,
1219                                           char *lpq_command )
1220 {
1221         fstring keystr;
1222         struct tdb_print_db *pdb;
1223
1224         DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1225         pdb = get_print_db_byname(sharename);
1226         if (!pdb)
1227                 return;
1228
1229         if ( !print_cache_expired(sharename, False) ) {
1230                 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1231                 release_print_db(pdb);
1232                 return;
1233         }
1234         
1235         /*
1236          * Check to see if someone else is doing this update.
1237          * This is essentially a mutex on the update.
1238          */
1239
1240         if (get_updating_pid(sharename) != -1) {
1241                 release_print_db(pdb);
1242                 return;
1243         }
1244
1245         /* Lock the queue for the database update */
1246
1247         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1248         /* Only wait 10 seconds for this. */
1249         if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1250                 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1251                 release_print_db(pdb);
1252                 return;
1253         }
1254
1255         /*
1256          * Ensure that no one else got in here.
1257          * If the updating pid is still -1 then we are
1258          * the winner.
1259          */
1260
1261         if (get_updating_pid(sharename) != -1) {
1262                 /*
1263                  * Someone else is doing the update, exit.
1264                  */
1265                 tdb_unlock_bystring(pdb->tdb, keystr);
1266                 release_print_db(pdb);
1267                 return;
1268         }
1269
1270         /*
1271          * We're going to do the update ourselves.
1272          */
1273
1274         /* Tell others we're doing the update. */
1275         set_updating_pid(sharename, True);
1276
1277         /*
1278          * Allow others to enter and notice we're doing
1279          * the update.
1280          */
1281
1282         tdb_unlock_bystring(pdb->tdb, keystr);
1283
1284         /* do the main work now */
1285         
1286         print_queue_update_internal( sharename, current_printif, lpq_command );
1287         
1288         /* Delete our pid from the db. */
1289         set_updating_pid(sharename, False);
1290         release_print_db(pdb);
1291 }
1292
1293 /****************************************************************************
1294 this is the receive function of the background lpq updater
1295 ****************************************************************************/
1296 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
1297 {
1298         fstring sharename;
1299         pstring lpqcommand;
1300         int printing_type;
1301         size_t len;
1302
1303         len = tdb_unpack( buf, msglen, "fdP",
1304                 sharename,
1305                 &printing_type,
1306                 lpqcommand );
1307
1308         if ( len == -1 ) {
1309                 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1310                 return;
1311         }
1312
1313         print_queue_update_with_lock(sharename, 
1314                 get_printer_fns_from_type(printing_type),
1315                 lpqcommand );
1316
1317         return;
1318 }
1319
1320 static pid_t background_lpq_updater_pid = -1;
1321
1322 /****************************************************************************
1323 main thread of the background lpq updater
1324 ****************************************************************************/
1325 void start_background_queue(void)
1326 {
1327         DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1328         background_lpq_updater_pid = sys_fork();
1329
1330         if (background_lpq_updater_pid == -1) {
1331                 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1332                 exit(1);
1333         }
1334
1335         if(background_lpq_updater_pid == 0) {
1336                 /* Child. */
1337                 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1338
1339                 claim_connection( NULL, "smbd lpq backend", 0, False, 
1340                         FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1341
1342                 if (!locking_init(0)) {
1343                         exit(1);
1344                 }
1345
1346                 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1347                 
1348                 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1349                 while (1) {
1350                         pause();
1351                         
1352                         /* check for some essential signals first */
1353                         
1354                         if (got_sig_term) {
1355                                 exit_server("Caught TERM signal");
1356                         }
1357
1358                         if (reload_after_sighup) {
1359                                 change_to_root_user();
1360                                 DEBUG(1,("Reloading services after SIGHUP\n"));
1361                                 reload_services(False);
1362                                 reload_after_sighup = 0;
1363                         }
1364                         
1365                         /* now check for messages */
1366                         
1367                         DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1368                         message_dispatch();
1369
1370                         /* process any pending print change notify messages */
1371
1372                         print_notify_send_messages(0);
1373                 }
1374         }
1375 }
1376
1377 /****************************************************************************
1378 update the internal database from the system print queue for a queue
1379 ****************************************************************************/
1380
1381 static void print_queue_update(int snum, BOOL force)
1382 {
1383         fstring key;
1384         fstring sharename;
1385         pstring lpqcommand;
1386         char *buffer = NULL;
1387         size_t len = 0;
1388         size_t newlen;
1389         struct tdb_print_db *pdb;
1390         int type;
1391         struct printif *current_printif;
1392
1393         fstrcpy( sharename, lp_const_servicename(snum));
1394
1395         /* don't strip out characters like '$' from the printername */
1396         
1397         pstrcpy( lpqcommand, lp_lpqcommand(snum));
1398         string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False );
1399         standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
1400         
1401         /* 
1402          * Make sure that the background queue process exists.  
1403          * Otherwise just do the update ourselves 
1404          */
1405         
1406         if ( force || background_lpq_updater_pid == -1 ) {
1407                 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1408                 current_printif = get_printer_fns( snum );
1409                 print_queue_update_with_lock( sharename, current_printif, lpqcommand );
1410
1411                 return;
1412         }
1413
1414         type = lp_printing(snum);
1415         
1416         /* get the length */
1417
1418         len = tdb_pack( buffer, len, "fdP",
1419                 sharename,
1420                 type,
1421                 lpqcommand );
1422
1423         buffer = SMB_XMALLOC_ARRAY( char, len );
1424
1425         /* now pack the buffer */
1426         newlen = tdb_pack( buffer, len, "fdP",
1427                 sharename,
1428                 type,
1429                 lpqcommand );
1430
1431         SMB_ASSERT( newlen == len );
1432
1433         DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1434                 "type = %d, lpq command = [%s]\n", sharename, type, lpqcommand ));
1435
1436         /* here we set a msg pending record for other smbd processes 
1437            to throttle the number of duplicate print_queue_update msgs
1438            sent.  */
1439
1440         pdb = get_print_db_byname(sharename);
1441         if (!pdb) {
1442                 SAFE_FREE(buffer);
1443                 return;
1444         }
1445
1446         snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1447
1448         if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1449                 /* log a message but continue on */
1450
1451                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1452                         sharename));
1453         }
1454
1455         release_print_db( pdb );
1456
1457         /* finally send the message */
1458         
1459         become_root();
1460         message_send_pid(background_lpq_updater_pid,
1461                  MSG_PRINTER_UPDATE, buffer, len, False);
1462         unbecome_root();
1463
1464         SAFE_FREE( buffer );
1465
1466         return;
1467 }
1468
1469 /****************************************************************************
1470  Create/Update an entry in the print tdb that will allow us to send notify
1471  updates only to interested smbd's. 
1472 ****************************************************************************/
1473
1474 BOOL print_notify_register_pid(int snum)
1475 {
1476         TDB_DATA data;
1477         struct tdb_print_db *pdb = NULL;
1478         TDB_CONTEXT *tdb = NULL;
1479         const char *printername;
1480         uint32 mypid = (uint32)sys_getpid();
1481         BOOL ret = False;
1482         size_t i;
1483
1484         /* if (snum == -1), then the change notify request was
1485            on a print server handle and we need to register on
1486            all print queus */
1487            
1488         if (snum == -1) 
1489         {
1490                 int num_services = lp_numservices();
1491                 int idx;
1492                 
1493                 for ( idx=0; idx<num_services; idx++ ) {
1494                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1495                                 print_notify_register_pid(idx);
1496                 }
1497                 
1498                 return True;
1499         }
1500         else /* register for a specific printer */
1501         {
1502                 printername = lp_const_servicename(snum);
1503                 pdb = get_print_db_byname(printername);
1504                 if (!pdb)
1505                         return False;
1506                 tdb = pdb->tdb;
1507         }
1508
1509         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1510                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1511                                         printername));
1512                 if (pdb)
1513                         release_print_db(pdb);
1514                 return False;
1515         }
1516
1517         data = get_printer_notify_pid_list( tdb, printername, True );
1518
1519         /* Add ourselves and increase the refcount. */
1520
1521         for (i = 0; i < data.dsize; i += 8) {
1522                 if (IVAL(data.dptr,i) == mypid) {
1523                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1524                         SIVAL(data.dptr, i+4, new_refcount);
1525                         break;
1526                 }
1527         }
1528
1529         if (i == data.dsize) {
1530                 /* We weren't in the list. Realloc. */
1531                 data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8);
1532                 if (!data.dptr) {
1533                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1534                                                 printername));
1535                         goto done;
1536                 }
1537                 data.dsize += 8;
1538                 SIVAL(data.dptr,data.dsize - 8,mypid);
1539                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1540         }
1541
1542         /* Store back the record. */
1543         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1544                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1545 list for printer %s\n", printername));
1546                 goto done;
1547         }
1548
1549         ret = True;
1550
1551  done:
1552
1553         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1554         if (pdb)
1555                 release_print_db(pdb);
1556         SAFE_FREE(data.dptr);
1557         return ret;
1558 }
1559
1560 /****************************************************************************
1561  Update an entry in the print tdb that will allow us to send notify
1562  updates only to interested smbd's. 
1563 ****************************************************************************/
1564
1565 BOOL print_notify_deregister_pid(int snum)
1566 {
1567         TDB_DATA data;
1568         struct tdb_print_db *pdb = NULL;
1569         TDB_CONTEXT *tdb = NULL;
1570         const char *printername;
1571         uint32 mypid = (uint32)sys_getpid();
1572         size_t i;
1573         BOOL ret = False;
1574
1575         /* if ( snum == -1 ), we are deregister a print server handle
1576            which means to deregister on all print queues */
1577            
1578         if (snum == -1) 
1579         {
1580                 int num_services = lp_numservices();
1581                 int idx;
1582                 
1583                 for ( idx=0; idx<num_services; idx++ ) {
1584                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1585                                 print_notify_deregister_pid(idx);
1586                 }
1587                 
1588                 return True;
1589         }
1590         else /* deregister a specific printer */
1591         {
1592                 printername = lp_const_servicename(snum);
1593                 pdb = get_print_db_byname(printername);
1594                 if (!pdb)
1595                         return False;
1596                 tdb = pdb->tdb;
1597         }
1598
1599         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1600                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1601 printer %s database\n", printername));
1602                 if (pdb)
1603                         release_print_db(pdb);
1604                 return False;
1605         }
1606
1607         data = get_printer_notify_pid_list( tdb, printername, True );
1608
1609         /* Reduce refcount. Remove ourselves if zero. */
1610
1611         for (i = 0; i < data.dsize; ) {
1612                 if (IVAL(data.dptr,i) == mypid) {
1613                         uint32 refcount = IVAL(data.dptr, i+4);
1614
1615                         refcount--;
1616
1617                         if (refcount == 0) {
1618                                 if (data.dsize - i > 8)
1619                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1620                                 data.dsize -= 8;
1621                                 continue;
1622                         }
1623                         SIVAL(data.dptr, i+4, refcount);
1624                 }
1625
1626                 i += 8;
1627         }
1628
1629         if (data.dsize == 0)
1630                 SAFE_FREE(data.dptr);
1631
1632         /* Store back the record. */
1633         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1634                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1635 list for printer %s\n", printername));
1636                 goto done;
1637         }
1638
1639         ret = True;
1640
1641   done:
1642
1643         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1644         if (pdb)
1645                 release_print_db(pdb);
1646         SAFE_FREE(data.dptr);
1647         return ret;
1648 }
1649
1650 /****************************************************************************
1651  Check if a jobid is valid. It is valid if it exists in the database.
1652 ****************************************************************************/
1653
1654 BOOL print_job_exists(const char* sharename, uint32 jobid)
1655 {
1656         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1657         BOOL ret;
1658
1659         if (!pdb)
1660                 return False;
1661         ret = tdb_exists(pdb->tdb, print_key(jobid));
1662         release_print_db(pdb);
1663         return ret;
1664 }
1665
1666 /****************************************************************************
1667  Give the fd used for a jobid.
1668 ****************************************************************************/
1669
1670 int print_job_fd(const char* sharename, uint32 jobid)
1671 {
1672         struct printjob *pjob = print_job_find(sharename, jobid);
1673         if (!pjob)
1674                 return -1;
1675         /* don't allow another process to get this info - it is meaningless */
1676         if (pjob->pid != sys_getpid())
1677                 return -1;
1678         return pjob->fd;
1679 }
1680
1681 /****************************************************************************
1682  Give the filename used for a jobid.
1683  Only valid for the process doing the spooling and when the job
1684  has not been spooled.
1685 ****************************************************************************/
1686
1687 char *print_job_fname(const char* sharename, uint32 jobid)
1688 {
1689         struct printjob *pjob = print_job_find(sharename, jobid);
1690         if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1691                 return NULL;
1692         return pjob->filename;
1693 }
1694
1695
1696 /****************************************************************************
1697  Give the filename used for a jobid.
1698  Only valid for the process doing the spooling and when the job
1699  has not been spooled.
1700 ****************************************************************************/
1701
1702 NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1703 {
1704         struct printjob *pjob = print_job_find(sharename, jobid);
1705         
1706         if ( !pjob )
1707                 return NULL;
1708                 
1709         return pjob->nt_devmode;
1710 }
1711
1712 /****************************************************************************
1713  Set the place in the queue for a job.
1714 ****************************************************************************/
1715
1716 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1717 {
1718         DEBUG(2,("print_job_set_place not implemented yet\n"));
1719         return False;
1720 }
1721
1722 /****************************************************************************
1723  Set the name of a job. Only possible for owner.
1724 ****************************************************************************/
1725
1726 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1727 {
1728         const char* sharename = lp_const_servicename(snum);
1729         struct printjob *pjob;
1730
1731         pjob = print_job_find(sharename, jobid);
1732         if (!pjob || pjob->pid != sys_getpid())
1733                 return False;
1734
1735         fstrcpy(pjob->jobname, name);
1736         return pjob_store(sharename, jobid, pjob);
1737 }
1738
1739 /***************************************************************************
1740  Remove a jobid from the 'jobs changed' list.
1741 ***************************************************************************/
1742
1743 static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1744 {
1745         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1746         TDB_DATA data, key;
1747         size_t job_count, i;
1748         BOOL ret = False;
1749         BOOL gotlock = False;
1750
1751         if (!pdb) {
1752                 return False;
1753         }
1754
1755         ZERO_STRUCT(data);
1756
1757         key = string_tdb_data("INFO/jobs_changed");
1758
1759         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1760                 goto out;
1761
1762         gotlock = True;
1763
1764         data = tdb_fetch(pdb->tdb, key);
1765
1766         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1767                 goto out;
1768
1769         job_count = data.dsize / 4;
1770         for (i = 0; i < job_count; i++) {
1771                 uint32 ch_jobid;
1772
1773                 ch_jobid = IVAL(data.dptr, i*4);
1774                 if (ch_jobid == jobid) {
1775                         if (i < job_count -1 )
1776                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1777                         data.dsize -= 4;
1778                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1779                                 goto out;
1780                         break;
1781                 }
1782         }
1783
1784         ret = True;
1785   out:
1786
1787         if (gotlock)
1788                 tdb_chainunlock(pdb->tdb, key);
1789         SAFE_FREE(data.dptr);
1790         release_print_db(pdb);
1791         if (ret)
1792                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1793         else
1794                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1795         return ret;
1796 }
1797
1798 /****************************************************************************
1799  Delete a print job - don't update queue.
1800 ****************************************************************************/
1801
1802 static BOOL print_job_delete1(int snum, uint32 jobid)
1803 {
1804         const char* sharename = lp_const_servicename(snum);
1805         struct printjob *pjob = print_job_find(sharename, jobid);
1806         int result = 0;
1807         struct printif *current_printif = get_printer_fns( snum );
1808
1809         pjob = print_job_find(sharename, jobid);
1810
1811         if (!pjob)
1812                 return False;
1813
1814         /*
1815          * If already deleting just return.
1816          */
1817
1818         if (pjob->status == LPQ_DELETING)
1819                 return True;
1820
1821         /* Hrm - we need to be able to cope with deleting a job before it
1822            has reached the spooler. */
1823
1824         if (pjob->sysjob == -1) {
1825                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1826         }
1827
1828         /* Set the tdb entry to be deleting. */
1829
1830         pjob->status = LPQ_DELETING;
1831         pjob_store(sharename, jobid, pjob);
1832
1833         if (pjob->spooled && pjob->sysjob != -1)
1834                 result = (*(current_printif->job_delete))(snum, pjob);
1835
1836         /* Delete the tdb entry if the delete succeeded or the job hasn't
1837            been spooled. */
1838
1839         if (result == 0) {
1840                 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1841                 int njobs = 1;
1842
1843                 if (!pdb)
1844                         return False;
1845                 pjob_delete(sharename, jobid);
1846                 /* Ensure we keep a rough count of the number of total jobs... */
1847                 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1848                 release_print_db(pdb);
1849         }
1850
1851         return (result == 0);
1852 }
1853
1854 /****************************************************************************
1855  Return true if the current user owns the print job.
1856 ****************************************************************************/
1857
1858 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1859 {
1860         struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
1861         user_struct *vuser;
1862
1863         if (!pjob || !user)
1864                 return False;
1865
1866         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1867                 return strequal(pjob->user, vuser->user.smb_name);
1868         } else {
1869                 return strequal(pjob->user, uidtoname(user->uid));
1870         }
1871 }
1872
1873 /****************************************************************************
1874  Delete a print job.
1875 ****************************************************************************/
1876
1877 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1878 {
1879         const char* sharename = lp_const_servicename( snum );
1880         BOOL    owner, deleted;
1881         char    *fname;
1882
1883         *errcode = WERR_OK;
1884                 
1885         owner = is_owner(user, snum, jobid);
1886         
1887         /* Check access against security descriptor or whether the user
1888            owns their job. */
1889
1890         if (!owner && 
1891             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1892                 DEBUG(3, ("delete denied by security descriptor\n"));
1893                 *errcode = WERR_ACCESS_DENIED;
1894
1895                 /* BEGIN_ADMIN_LOG */
1896                 sys_adminlog( LOG_ERR, 
1897                               "Permission denied-- user not allowed to delete, \
1898 pause, or resume print job. User name: %s. Printer name: %s.",
1899                               uidtoname(user->uid), PRINTERNAME(snum) );
1900                 /* END_ADMIN_LOG */
1901
1902                 return False;
1903         }
1904
1905         /* 
1906          * get the spooled filename of the print job
1907          * if this works, then the file has not been spooled
1908          * to the underlying print system.  Just delete the 
1909          * spool file & return.
1910          */
1911          
1912         if ( (fname = print_job_fname( sharename, jobid )) != NULL )
1913         {
1914                 /* remove the spool file */
1915                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1916                 if ( unlink( fname ) == -1 ) {
1917                         *errcode = map_werror_from_unix(errno);
1918                         return False;
1919                 }
1920         }
1921         
1922         if (!print_job_delete1(snum, jobid)) {
1923                 *errcode = WERR_ACCESS_DENIED;
1924                 return False;
1925         }
1926
1927         /* force update the database and say the delete failed if the
1928            job still exists */
1929
1930         print_queue_update(snum, True);
1931         
1932         deleted = !print_job_exists(sharename, jobid);
1933         if ( !deleted )
1934                 *errcode = WERR_ACCESS_DENIED;
1935
1936         return deleted;
1937 }
1938
1939 /****************************************************************************
1940  Pause a job.
1941 ****************************************************************************/
1942
1943 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1944 {
1945         const char* sharename = lp_const_servicename(snum);
1946         struct printjob *pjob;
1947         int ret = -1;
1948         struct printif *current_printif = get_printer_fns( snum );
1949
1950         pjob = print_job_find(sharename, jobid);
1951         
1952         if (!pjob || !user) 
1953                 return False;
1954
1955         if (!pjob->spooled || pjob->sysjob == -1) 
1956                 return False;
1957
1958         if (!is_owner(user, snum, jobid) &&
1959             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1960                 DEBUG(3, ("pause denied by security descriptor\n"));
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                 *errcode = WERR_ACCESS_DENIED;
1970                 return False;
1971         }
1972
1973         /* need to pause the spooled entry */
1974         ret = (*(current_printif->job_pause))(snum, pjob);
1975
1976         if (ret != 0) {
1977                 *errcode = WERR_INVALID_PARAM;
1978                 return False;
1979         }
1980
1981         /* force update the database */
1982         print_cache_flush(snum);
1983
1984         /* Send a printer notify message */
1985
1986         notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
1987
1988         /* how do we tell if this succeeded? */
1989
1990         return True;
1991 }
1992
1993 /****************************************************************************
1994  Resume a job.
1995 ****************************************************************************/
1996
1997 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1998 {
1999         const char *sharename = lp_const_servicename(snum);
2000         struct printjob *pjob;
2001         int ret;
2002         struct printif *current_printif = get_printer_fns( snum );
2003
2004         pjob = print_job_find(sharename, jobid);
2005         
2006         if (!pjob || !user)
2007                 return False;
2008
2009         if (!pjob->spooled || pjob->sysjob == -1)
2010                 return False;
2011
2012         if (!is_owner(user, snum, jobid) &&
2013             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
2014                 DEBUG(3, ("resume denied by security descriptor\n"));
2015                 *errcode = WERR_ACCESS_DENIED;
2016
2017                 /* BEGIN_ADMIN_LOG */
2018                 sys_adminlog( LOG_ERR, 
2019                          "Permission denied-- user not allowed to delete, \
2020 pause, or resume print job. User name: %s. Printer name: %s.",
2021                         uidtoname(user->uid), PRINTERNAME(snum) );
2022                 /* END_ADMIN_LOG */
2023                 return False;
2024         }
2025
2026         ret = (*(current_printif->job_resume))(snum, pjob);
2027
2028         if (ret != 0) {
2029                 *errcode = WERR_INVALID_PARAM;
2030                 return False;
2031         }
2032
2033         /* force update the database */
2034         print_cache_flush(snum);
2035
2036         /* Send a printer notify message */
2037
2038         notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2039
2040         return True;
2041 }
2042
2043 /****************************************************************************
2044  Write to a print file.
2045 ****************************************************************************/
2046
2047 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2048 {
2049         const char* sharename = lp_const_servicename(snum);
2050         int return_code;
2051         struct printjob *pjob;
2052
2053         pjob = print_job_find(sharename, jobid);
2054
2055         if (!pjob)
2056                 return -1;
2057         /* don't allow another process to get this info - it is meaningless */
2058         if (pjob->pid != sys_getpid())
2059                 return -1;
2060
2061         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2062
2063         if (return_code>0) {
2064                 pjob->size += size;
2065                 pjob_store(sharename, jobid, pjob);
2066         }
2067         return return_code;
2068 }
2069
2070 /****************************************************************************
2071  Get the queue status - do not update if db is out of date.
2072 ****************************************************************************/
2073
2074 static int get_queue_status(const char* sharename, print_status_struct *status)
2075 {
2076         fstring keystr;
2077         TDB_DATA data;
2078         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2079         int len;
2080
2081         if (status) {
2082                 ZERO_STRUCTP(status);
2083         }
2084
2085         if (!pdb)
2086                 return 0;
2087
2088         if (status) {
2089                 fstr_sprintf(keystr, "STATUS/%s", sharename);
2090                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2091                 if (data.dptr) {
2092                         if (data.dsize == sizeof(print_status_struct))
2093                                 /* this memcpy is ok since the status struct was 
2094                                    not packed before storing it in the tdb */
2095                                 memcpy(status, data.dptr, sizeof(print_status_struct));
2096                         SAFE_FREE(data.dptr);
2097                 }
2098         }
2099         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2100         release_print_db(pdb);
2101         return (len == -1 ? 0 : len);
2102 }
2103
2104 /****************************************************************************
2105  Determine the number of jobs in a queue.
2106 ****************************************************************************/
2107
2108 int print_queue_length(int snum, print_status_struct *pstatus)
2109 {
2110         const char* sharename = lp_const_servicename( snum );
2111         print_status_struct status;
2112         int len;
2113
2114         ZERO_STRUCT( status );
2115  
2116         /* make sure the database is up to date */
2117         if (print_cache_expired(lp_const_servicename(snum), True))
2118                 print_queue_update(snum, False);
2119  
2120         /* also fetch the queue status */
2121         memset(&status, 0, sizeof(status));
2122         len = get_queue_status(sharename, &status);
2123
2124         if (pstatus)
2125                 *pstatus = status;
2126
2127         return len;
2128 }
2129
2130 /***************************************************************************
2131  Allocate a jobid. Hold the lock for as short a time as possible.
2132 ***************************************************************************/
2133
2134 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2135 {
2136         int i;
2137         uint32 jobid;
2138
2139         *pjobid = (uint32)-1;
2140
2141         for (i = 0; i < 3; i++) {
2142                 /* Lock the database - only wait 20 seconds. */
2143                 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
2144                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2145                         return False;
2146                 }
2147
2148                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2149                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2150                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2151                                         sharename));
2152                                 return False;
2153                         }
2154                         jobid = 0;
2155                 }
2156
2157                 jobid = NEXT_JOBID(jobid);
2158
2159                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2160                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2161                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2162                         return False;
2163                 }
2164
2165                 /* We've finished with the INFO/nextjob lock. */
2166                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2167                                 
2168                 if (!print_job_exists(sharename, jobid))
2169                         break;
2170         }
2171
2172         if (i > 2) {
2173                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2174                         sharename));
2175                 /* Probably full... */
2176                 errno = ENOSPC;
2177                 return False;
2178         }
2179
2180         /* Store a dummy placeholder. */
2181         {
2182                 TDB_DATA dum;
2183                 dum.dptr = NULL;
2184                 dum.dsize = 0;
2185                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2186                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2187                                 jobid ));
2188                         return False;
2189                 }
2190         }
2191
2192         *pjobid = jobid;
2193         return True;
2194 }
2195
2196 /***************************************************************************
2197  Append a jobid to the 'jobs changed' list.
2198 ***************************************************************************/
2199
2200 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2201 {
2202         TDB_DATA data;
2203         uint32 store_jobid;
2204
2205         SIVAL(&store_jobid, 0, jobid);
2206         data.dptr = (char *)&store_jobid;
2207         data.dsize = 4;
2208
2209         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2210
2211         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2212                            data) == 0);
2213 }
2214
2215 /***************************************************************************
2216  Start spooling a job - return the jobid.
2217 ***************************************************************************/
2218
2219 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2220 {
2221         uint32 jobid;
2222         char *path;
2223         struct printjob pjob;
2224         user_struct *vuser;
2225         const char *sharename = lp_const_servicename(snum);
2226         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2227         int njobs;
2228
2229         errno = 0;
2230
2231         if (!pdb)
2232                 return (uint32)-1;
2233
2234         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2235                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2236                 release_print_db(pdb);
2237                 return (uint32)-1;
2238         }
2239
2240         if (!print_time_access_check(snum)) {
2241                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2242                 release_print_db(pdb);
2243                 return (uint32)-1;
2244         }
2245
2246         path = lp_pathname(snum);
2247
2248         /* see if we have sufficient disk space */
2249         if (lp_minprintspace(snum)) {
2250                 SMB_BIG_UINT dspace, dsize;
2251                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2252                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2253                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
2254                         release_print_db(pdb);
2255                         errno = ENOSPC;
2256                         return (uint32)-1;
2257                 }
2258         }
2259
2260         /* for autoloaded printers, check that the printcap entry still exists */
2261         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2262                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2263                 release_print_db(pdb);
2264                 errno = ENOENT;
2265                 return (uint32)-1;
2266         }
2267
2268         /* Insure the maximum queue size is not violated */
2269         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2270                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2271                         sharename, njobs, lp_maxprintjobs(snum) ));
2272                 release_print_db(pdb);
2273                 errno = ENOSPC;
2274                 return (uint32)-1;
2275         }
2276
2277         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2278                 sharename, njobs, lp_maxprintjobs(snum) ));
2279
2280         if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2281                 goto fail;
2282
2283         /* create the database entry */
2284         
2285         ZERO_STRUCT(pjob);
2286         
2287         pjob.pid = sys_getpid();
2288         pjob.sysjob = -1;
2289         pjob.fd = -1;
2290         pjob.starttime = time(NULL);
2291         pjob.status = LPQ_SPOOLING;
2292         pjob.size = 0;
2293         pjob.spooled = False;
2294         pjob.smbjob = True;
2295         pjob.nt_devmode = nt_devmode;
2296         
2297         fstrcpy(pjob.jobname, jobname);
2298
2299         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2300                 fstrcpy(pjob.user, vuser->user.smb_name);
2301         } else {
2302                 fstrcpy(pjob.user, uidtoname(user->uid));
2303         }
2304
2305         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2306
2307         /* we have a job entry - now create the spool file */
2308         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
2309                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2310         pjob.fd = smb_mkstemp(pjob.filename);
2311
2312         if (pjob.fd == -1) {
2313                 if (errno == EACCES) {
2314                         /* Common setup error, force a report. */
2315                         DEBUG(0, ("print_job_start: insufficient permissions \
2316 to open spool file %s.\n", pjob.filename));
2317                 } else {
2318                         /* Normal case, report at level 3 and above. */
2319                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2320                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2321                 }
2322                 goto fail;
2323         }
2324
2325         pjob_store(sharename, jobid, &pjob);
2326
2327         /* Update the 'jobs changed' entry used by print_queue_status. */
2328         add_to_jobs_changed(pdb, jobid);
2329
2330         /* Ensure we keep a rough count of the number of total jobs... */
2331         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2332
2333         release_print_db(pdb);
2334
2335         return jobid;
2336
2337  fail:
2338         if (jobid != -1)
2339                 pjob_delete(sharename, jobid);
2340
2341         release_print_db(pdb);
2342
2343         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2344         return (uint32)-1;
2345 }
2346
2347 /****************************************************************************
2348  Update the number of pages spooled to jobid
2349 ****************************************************************************/
2350
2351 void print_job_endpage(int snum, uint32 jobid)
2352 {
2353         const char* sharename = lp_const_servicename(snum);
2354         struct printjob *pjob;
2355
2356         pjob = print_job_find(sharename, jobid);
2357         if (!pjob)
2358                 return;
2359         /* don't allow another process to get this info - it is meaningless */
2360         if (pjob->pid != sys_getpid())
2361                 return;
2362
2363         pjob->page_count++;
2364         pjob_store(sharename, jobid, pjob);
2365 }
2366
2367 /****************************************************************************
2368  Print a file - called on closing the file. This spools the job.
2369  If normal close is false then we're tearing down the jobs - treat as an
2370  error.
2371 ****************************************************************************/
2372
2373 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2374 {
2375         const char* sharename = lp_const_servicename(snum);
2376         struct printjob *pjob;
2377         int ret;
2378         SMB_STRUCT_STAT sbuf;
2379         struct printif *current_printif = get_printer_fns( snum );
2380
2381         pjob = print_job_find(sharename, jobid);
2382
2383         if (!pjob)
2384                 return False;
2385
2386         if (pjob->spooled || pjob->pid != sys_getpid())
2387                 return False;
2388
2389         if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2390                 pjob->size = sbuf.st_size;
2391                 close(pjob->fd);
2392                 pjob->fd = -1;
2393         } else {
2394
2395                 /* 
2396                  * Not a normal close or we couldn't stat the job file,
2397                  * so something has gone wrong. Cleanup.
2398                  */
2399                 close(pjob->fd);
2400                 pjob->fd = -1;
2401                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2402                 goto fail;
2403         }
2404
2405         /* Technically, this is not quite right. If the printer has a separator
2406          * page turned on, the NT spooler prints the separator page even if the
2407          * print job is 0 bytes. 010215 JRR */
2408         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2409                 /* don't bother spooling empty files or something being deleted. */
2410                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2411                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2412                 unlink(pjob->filename);
2413                 pjob_delete(sharename, jobid);
2414                 return True;
2415         }
2416
2417         pjob->smbjob = jobid;
2418
2419         ret = (*(current_printif->job_submit))(snum, pjob);
2420
2421         if (ret)
2422                 goto fail;
2423
2424         /* The print job has been sucessfully handed over to the back-end */
2425         
2426         pjob->spooled = True;
2427         pjob->status = LPQ_QUEUED;
2428         pjob_store(sharename, jobid, pjob);
2429         
2430         /* make sure the database is up to date */
2431         if (print_cache_expired(lp_const_servicename(snum), True))
2432                 print_queue_update(snum, False);
2433         
2434         return True;
2435
2436 fail:
2437
2438         /* The print job was not succesfully started. Cleanup */
2439         /* Still need to add proper error return propagation! 010122:JRR */
2440         unlink(pjob->filename);
2441         pjob_delete(sharename, jobid);
2442         return False;
2443 }
2444
2445 /****************************************************************************
2446  Get a snapshot of jobs in the system without traversing.
2447 ****************************************************************************/
2448
2449 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2450 {
2451         TDB_DATA data, cgdata;
2452         print_queue_struct *queue = NULL;
2453         uint32 qcount = 0;
2454         uint32 extra_count = 0;
2455         int total_count = 0;
2456         size_t len = 0;
2457         uint32 i;
2458         int max_reported_jobs = lp_max_reported_jobs(snum);
2459         BOOL ret = False;
2460         const char* sharename = lp_servicename(snum);
2461
2462         /* make sure the database is up to date */
2463         if (print_cache_expired(lp_const_servicename(snum), True))
2464                 print_queue_update(snum, False);
2465  
2466         *pcount = 0;
2467         *ppqueue = NULL;
2468
2469         ZERO_STRUCT(data);
2470         ZERO_STRUCT(cgdata);
2471
2472         /* Get the stored queue data. */
2473         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2474         
2475         if (data.dptr && data.dsize >= sizeof(qcount))
2476                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2477                 
2478         /* Get the changed jobs list. */
2479         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2480         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2481                 extra_count = cgdata.dsize/4;
2482
2483         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2484
2485         /* Allocate the queue size. */
2486         if (qcount == 0 && extra_count == 0)
2487                 goto out;
2488
2489         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2490                 goto out;
2491
2492         /* Retrieve the linearised queue data. */
2493
2494         for( i  = 0; i < qcount; i++) {
2495                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2496                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2497                                 &qjob,
2498                                 &qsize,
2499                                 &qpage_count,
2500                                 &qstatus,
2501                                 &qpriority,
2502                                 &qtime,
2503                                 queue[i].fs_user,
2504                                 queue[i].fs_file);
2505                 queue[i].job = qjob;
2506                 queue[i].size = qsize;
2507                 queue[i].page_count = qpage_count;
2508                 queue[i].status = qstatus;
2509                 queue[i].priority = qpriority;
2510                 queue[i].time = qtime;
2511         }
2512
2513         total_count = qcount;
2514
2515         /* Add in the changed jobids. */
2516         for( i  = 0; i < extra_count; i++) {
2517                 uint32 jobid;
2518                 struct printjob *pjob;
2519
2520                 jobid = IVAL(cgdata.dptr, i*4);
2521                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2522                 pjob = print_job_find(lp_const_servicename(snum), jobid);
2523                 if (!pjob) {
2524                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2525                         remove_from_jobs_changed(sharename, jobid);
2526                         continue;
2527                 }
2528
2529                 queue[total_count].job = jobid;
2530                 queue[total_count].size = pjob->size;
2531                 queue[total_count].page_count = pjob->page_count;
2532                 queue[total_count].status = pjob->status;
2533                 queue[total_count].priority = 1;
2534                 queue[total_count].time = pjob->starttime;
2535                 fstrcpy(queue[total_count].fs_user, pjob->user);
2536                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2537                 total_count++;
2538         }
2539
2540         /* Sort the queue by submission time otherwise they are displayed
2541            in hash order. */
2542
2543         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2544
2545         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2546
2547         if (max_reported_jobs && total_count > max_reported_jobs)
2548                 total_count = max_reported_jobs;
2549
2550         *ppqueue = queue;
2551         *pcount = total_count;
2552
2553         ret = True;
2554
2555   out:
2556
2557         SAFE_FREE(data.dptr);
2558         SAFE_FREE(cgdata.dptr);
2559         return ret;
2560 }
2561
2562 /****************************************************************************
2563  Get a printer queue listing.
2564  set queue = NULL and status = NULL if you just want to update the cache
2565 ****************************************************************************/
2566
2567 int print_queue_status(int snum, 
2568                        print_queue_struct **ppqueue,
2569                        print_status_struct *status)
2570 {
2571         fstring keystr;
2572         TDB_DATA data, key;
2573         const char *sharename;
2574         struct tdb_print_db *pdb;
2575         int count = 0;
2576
2577         /* make sure the database is up to date */
2578
2579         if (print_cache_expired(lp_const_servicename(snum), True))
2580                 print_queue_update(snum, False);
2581
2582         /* return if we are done */
2583         if ( !ppqueue || !status )
2584                 return 0;
2585
2586         *ppqueue = NULL;
2587         sharename = lp_const_servicename(snum);
2588         pdb = get_print_db_byname(sharename);
2589
2590         if (!pdb)
2591                 return 0;
2592
2593         /*
2594          * Fetch the queue status.  We must do this first, as there may
2595          * be no jobs in the queue.
2596          */
2597
2598         ZERO_STRUCTP(status);
2599         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2600         key.dptr = keystr;
2601         key.dsize = strlen(keystr);
2602         data = tdb_fetch(pdb->tdb, key);
2603         if (data.dptr) {
2604                 if (data.dsize == sizeof(*status)) {
2605                         /* this memcpy is ok since the status struct was 
2606                            not packed before storing it in the tdb */
2607                         memcpy(status, data.dptr, sizeof(*status));
2608                 }
2609                 SAFE_FREE(data.dptr);
2610         }
2611
2612         /*
2613          * Now, fetch the print queue information.  We first count the number
2614          * of entries, and then only retrieve the queue if necessary.
2615          */
2616
2617         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2618                 release_print_db(pdb);
2619                 return 0;
2620         }
2621
2622         release_print_db(pdb);
2623         return count;
2624 }
2625
2626 /****************************************************************************
2627  Pause a queue.
2628 ****************************************************************************/
2629
2630 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2631 {
2632         int ret;
2633         struct printif *current_printif = get_printer_fns( snum );
2634         
2635         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2636                 *errcode = WERR_ACCESS_DENIED;
2637                 return False;
2638         }
2639         
2640
2641         become_root();
2642                 
2643         ret = (*(current_printif->queue_pause))(snum);
2644
2645         unbecome_root();
2646                 
2647         if (ret != 0) {
2648                 *errcode = WERR_INVALID_PARAM;
2649                 return False;
2650         }
2651
2652         /* force update the database */
2653         print_cache_flush(snum);
2654
2655         /* Send a printer notify message */
2656
2657         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2658
2659         return True;
2660 }
2661
2662 /****************************************************************************
2663  Resume a queue.
2664 ****************************************************************************/
2665
2666 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2667 {
2668         int ret;
2669         struct printif *current_printif = get_printer_fns( snum );
2670
2671         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2672                 *errcode = WERR_ACCESS_DENIED;
2673                 return False;
2674         }
2675         
2676         become_root();
2677                 
2678         ret = (*(current_printif->queue_resume))(snum);
2679
2680         unbecome_root();
2681                 
2682         if (ret != 0) {
2683                 *errcode = WERR_INVALID_PARAM;
2684                 return False;
2685         }
2686
2687         /* make sure the database is up to date */
2688         if (print_cache_expired(lp_const_servicename(snum), True))
2689                 print_queue_update(snum, True);
2690
2691         /* Send a printer notify message */
2692
2693         notify_printer_status(snum, PRINTER_STATUS_OK);
2694
2695         return True;
2696 }
2697
2698 /****************************************************************************
2699  Purge a queue - implemented by deleting all jobs that we can delete.
2700 ****************************************************************************/
2701
2702 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2703 {
2704         print_queue_struct *queue;
2705         print_status_struct status;
2706         int njobs, i;
2707         BOOL can_job_admin;
2708
2709         /* Force and update so the count is accurate (i.e. not a cached count) */
2710         print_queue_update(snum, True);
2711         
2712         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2713         njobs = print_queue_status(snum, &queue, &status);
2714         
2715         if ( can_job_admin )
2716                 become_root();
2717
2718         for (i=0;i<njobs;i++) {
2719                 BOOL owner = is_owner(user, snum, queue[i].job);
2720
2721                 if (owner || can_job_admin) {
2722                         print_job_delete1(snum, queue[i].job);
2723                 }
2724         }
2725         
2726         if ( can_job_admin )
2727                 unbecome_root();
2728
2729         /* update the cache */
2730         print_queue_update( snum, True );
2731
2732         SAFE_FREE(queue);
2733
2734         return True;
2735 }