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