r2569: Patch from Rob Foehl <rwf@loonybin.net>:
[ira/wip.git] / source3 / printing / printing.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing backend routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    Copyright (C) Jeremy Allison 2002
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "printing.h"
25
26 extern SIG_ATOMIC_T got_sig_term;
27 extern SIG_ATOMIC_T reload_after_sighup;
28
29 /* Current printer interface */
30 static BOOL remove_from_jobs_changed(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                 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1188                 
1189                 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1190                 while (1) {
1191                         pause();
1192                         
1193                         /* check for some essential signals first */
1194                         
1195                         if (got_sig_term) {
1196                                 exit_server("Caught TERM signal");
1197                         }
1198
1199                         if (reload_after_sighup) {
1200                                 change_to_root_user();
1201                                 DEBUG(1,("Reloading services after SIGHUP\n"));
1202                                 reload_services(False);
1203                                 reload_after_sighup = 0;
1204                         }
1205                         
1206                         /* now check for messages */
1207                         
1208                         DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1209                         message_dispatch();
1210                 }
1211         }
1212 }
1213
1214 /****************************************************************************
1215 update the internal database from the system print queue for a queue
1216 ****************************************************************************/
1217 static void print_queue_update(int snum)
1218 {
1219         /* 
1220          * Make sure that the backgroup queueu process exists.  
1221          * Otherwise just do the update ourselves 
1222          */
1223            
1224         if ( background_lpq_updater_pid != -1 ) {
1225                 become_root();
1226                 message_send_pid(background_lpq_updater_pid,
1227                                  MSG_PRINTER_UPDATE, &snum, sizeof(snum),
1228                                  False);
1229                 unbecome_root();
1230         } else
1231                 print_queue_update_internal( snum );
1232 }
1233
1234 /****************************************************************************
1235  Create/Update an entry in the print tdb that will allow us to send notify
1236  updates only to interested smbd's. 
1237 ****************************************************************************/
1238
1239 BOOL print_notify_register_pid(int snum)
1240 {
1241         TDB_DATA data;
1242         struct tdb_print_db *pdb = NULL;
1243         TDB_CONTEXT *tdb = NULL;
1244         const char *printername;
1245         uint32 mypid = (uint32)sys_getpid();
1246         BOOL ret = False;
1247         size_t i;
1248
1249         /* if (snum == -1), then the change notify request was
1250            on a print server handle and we need to register on
1251            all print queus */
1252            
1253         if (snum == -1) 
1254         {
1255                 int num_services = lp_numservices();
1256                 int idx;
1257                 
1258                 for ( idx=0; idx<num_services; idx++ ) {
1259                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1260                                 print_notify_register_pid(idx);
1261                 }
1262                 
1263                 return True;
1264         }
1265         else /* register for a specific printer */
1266         {
1267                 printername = lp_const_servicename(snum);
1268                 pdb = get_print_db_byname(printername);
1269                 if (!pdb)
1270                         return False;
1271                 tdb = pdb->tdb;
1272         }
1273
1274         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1275                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1276                                         printername));
1277                 if (pdb)
1278                         release_print_db(pdb);
1279                 return False;
1280         }
1281
1282         data = get_printer_notify_pid_list( tdb, printername, True );
1283
1284         /* Add ourselves and increase the refcount. */
1285
1286         for (i = 0; i < data.dsize; i += 8) {
1287                 if (IVAL(data.dptr,i) == mypid) {
1288                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1289                         SIVAL(data.dptr, i+4, new_refcount);
1290                         break;
1291                 }
1292         }
1293
1294         if (i == data.dsize) {
1295                 /* We weren't in the list. Realloc. */
1296                 data.dptr = Realloc(data.dptr, data.dsize + 8);
1297                 if (!data.dptr) {
1298                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1299                                                 printername));
1300                         goto done;
1301                 }
1302                 data.dsize += 8;
1303                 SIVAL(data.dptr,data.dsize - 8,mypid);
1304                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1305         }
1306
1307         /* Store back the record. */
1308         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1309                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1310 list for printer %s\n", printername));
1311                 goto done;
1312         }
1313
1314         ret = True;
1315
1316  done:
1317
1318         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1319         if (pdb)
1320                 release_print_db(pdb);
1321         SAFE_FREE(data.dptr);
1322         return ret;
1323 }
1324
1325 /****************************************************************************
1326  Update an entry in the print tdb that will allow us to send notify
1327  updates only to interested smbd's. 
1328 ****************************************************************************/
1329
1330 BOOL print_notify_deregister_pid(int snum)
1331 {
1332         TDB_DATA data;
1333         struct tdb_print_db *pdb = NULL;
1334         TDB_CONTEXT *tdb = NULL;
1335         const char *printername;
1336         uint32 mypid = (uint32)sys_getpid();
1337         size_t i;
1338         BOOL ret = False;
1339
1340         /* if ( snum == -1 ), we are deregister a print server handle
1341            which means to deregister on all print queues */
1342            
1343         if (snum == -1) 
1344         {
1345                 int num_services = lp_numservices();
1346                 int idx;
1347                 
1348                 for ( idx=0; idx<num_services; idx++ ) {
1349                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1350                                 print_notify_deregister_pid(idx);
1351                 }
1352                 
1353                 return True;
1354         }
1355         else /* deregister a specific printer */
1356         {
1357                 printername = lp_const_servicename(snum);
1358                 pdb = get_print_db_byname(printername);
1359                 if (!pdb)
1360                         return False;
1361                 tdb = pdb->tdb;
1362         }
1363
1364         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1365                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1366 printer %s database\n", printername));
1367                 if (pdb)
1368                         release_print_db(pdb);
1369                 return False;
1370         }
1371
1372         data = get_printer_notify_pid_list( tdb, printername, True );
1373
1374         /* Reduce refcount. Remove ourselves if zero. */
1375
1376         for (i = 0; i < data.dsize; ) {
1377                 if (IVAL(data.dptr,i) == mypid) {
1378                         uint32 refcount = IVAL(data.dptr, i+4);
1379
1380                         refcount--;
1381
1382                         if (refcount == 0) {
1383                                 if (data.dsize - i > 8)
1384                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1385                                 data.dsize -= 8;
1386                                 continue;
1387                         }
1388                         SIVAL(data.dptr, i+4, refcount);
1389                 }
1390
1391                 i += 8;
1392         }
1393
1394         if (data.dsize == 0)
1395                 SAFE_FREE(data.dptr);
1396
1397         /* Store back the record. */
1398         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1399                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1400 list for printer %s\n", printername));
1401                 goto done;
1402         }
1403
1404         ret = True;
1405
1406   done:
1407
1408         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1409         if (pdb)
1410                 release_print_db(pdb);
1411         SAFE_FREE(data.dptr);
1412         return ret;
1413 }
1414
1415 /****************************************************************************
1416  Check if a jobid is valid. It is valid if it exists in the database.
1417 ****************************************************************************/
1418
1419 BOOL print_job_exists(int snum, uint32 jobid)
1420 {
1421         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1422         BOOL ret;
1423
1424         if (!pdb)
1425                 return False;
1426         ret = tdb_exists(pdb->tdb, print_key(jobid));
1427         release_print_db(pdb);
1428         return ret;
1429 }
1430
1431 /****************************************************************************
1432  Give the fd used for a jobid.
1433 ****************************************************************************/
1434
1435 int print_job_fd(int snum, uint32 jobid)
1436 {
1437         struct printjob *pjob = print_job_find(snum, jobid);
1438         if (!pjob)
1439                 return -1;
1440         /* don't allow another process to get this info - it is meaningless */
1441         if (pjob->pid != sys_getpid())
1442                 return -1;
1443         return pjob->fd;
1444 }
1445
1446 /****************************************************************************
1447  Give the filename used for a jobid.
1448  Only valid for the process doing the spooling and when the job
1449  has not been spooled.
1450 ****************************************************************************/
1451
1452 char *print_job_fname(int snum, uint32 jobid)
1453 {
1454         struct printjob *pjob = print_job_find(snum, jobid);
1455         if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1456                 return NULL;
1457         return pjob->filename;
1458 }
1459
1460
1461 /****************************************************************************
1462  Give the filename used for a jobid.
1463  Only valid for the process doing the spooling and when the job
1464  has not been spooled.
1465 ****************************************************************************/
1466
1467 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1468 {
1469         struct printjob *pjob = print_job_find(snum, jobid);
1470         
1471         if ( !pjob )
1472                 return NULL;
1473                 
1474         return pjob->nt_devmode;
1475 }
1476
1477 /****************************************************************************
1478  Set the place in the queue for a job.
1479 ****************************************************************************/
1480
1481 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1482 {
1483         DEBUG(2,("print_job_set_place not implemented yet\n"));
1484         return False;
1485 }
1486
1487 /****************************************************************************
1488  Set the name of a job. Only possible for owner.
1489 ****************************************************************************/
1490
1491 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1492 {
1493         struct printjob *pjob = print_job_find(snum, jobid);
1494         if (!pjob || pjob->pid != sys_getpid())
1495                 return False;
1496
1497         fstrcpy(pjob->jobname, name);
1498         return pjob_store(snum, jobid, pjob);
1499 }
1500
1501 /***************************************************************************
1502  Remove a jobid from the 'jobs changed' list.
1503 ***************************************************************************/
1504
1505 static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
1506 {
1507         const char *printername = lp_const_servicename(snum);
1508         struct tdb_print_db *pdb = get_print_db_byname(printername);
1509         TDB_DATA data, key;
1510         size_t job_count, i;
1511         BOOL ret = False;
1512         BOOL gotlock = False;
1513
1514         key.dptr = "INFO/jobs_changed";
1515         key.dsize = strlen(key.dptr);
1516         ZERO_STRUCT(data);
1517
1518         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1519                 goto out;
1520
1521         gotlock = True;
1522
1523         data = tdb_fetch(pdb->tdb, key);
1524
1525         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1526                 goto out;
1527
1528         job_count = data.dsize / 4;
1529         for (i = 0; i < job_count; i++) {
1530                 uint32 ch_jobid;
1531
1532                 ch_jobid = IVAL(data.dptr, i*4);
1533                 if (ch_jobid == jobid) {
1534                         if (i < job_count -1 )
1535                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1536                         data.dsize -= 4;
1537                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1538                                 goto out;
1539                         break;
1540                 }
1541         }
1542
1543         ret = True;
1544   out:
1545
1546         if (gotlock)
1547                 tdb_chainunlock(pdb->tdb, key);
1548         SAFE_FREE(data.dptr);
1549         release_print_db(pdb);
1550         if (ret)
1551                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1552         else
1553                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1554         return ret;
1555 }
1556
1557 /****************************************************************************
1558  Delete a print job - don't update queue.
1559 ****************************************************************************/
1560
1561 static BOOL print_job_delete1(int snum, uint32 jobid)
1562 {
1563         struct printjob *pjob = print_job_find(snum, jobid);
1564         int result = 0;
1565         struct printif *current_printif = get_printer_fns( snum );
1566
1567         if (!pjob)
1568                 return False;
1569
1570         /*
1571          * If already deleting just return.
1572          */
1573
1574         if (pjob->status == LPQ_DELETING)
1575                 return True;
1576
1577         /* Hrm - we need to be able to cope with deleting a job before it
1578            has reached the spooler. */
1579
1580         if (pjob->sysjob == -1) {
1581                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1582         }
1583
1584         /* Set the tdb entry to be deleting. */
1585
1586         pjob->status = LPQ_DELETING;
1587         pjob_store(snum, jobid, pjob);
1588
1589         if (pjob->spooled && pjob->sysjob != -1)
1590                 result = (*(current_printif->job_delete))(snum, pjob);
1591
1592         /* Delete the tdb entry if the delete succeeded or the job hasn't
1593            been spooled. */
1594
1595         if (result == 0) {
1596                 const char *printername = lp_const_servicename(snum);
1597                 struct tdb_print_db *pdb = get_print_db_byname(printername);
1598                 int njobs = 1;
1599
1600                 if (!pdb)
1601                         return False;
1602                 pjob_delete(snum, jobid);
1603                 /* Ensure we keep a rough count of the number of total jobs... */
1604                 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1605                 release_print_db(pdb);
1606         }
1607
1608         return (result == 0);
1609 }
1610
1611 /****************************************************************************
1612  Return true if the current user owns the print job.
1613 ****************************************************************************/
1614
1615 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1616 {
1617         struct printjob *pjob = print_job_find(snum, jobid);
1618         user_struct *vuser;
1619
1620         if (!pjob || !user)
1621                 return False;
1622
1623         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1624                 return strequal(pjob->user, vuser->user.smb_name);
1625         } else {
1626                 return strequal(pjob->user, uidtoname(user->uid));
1627         }
1628 }
1629
1630 /****************************************************************************
1631  Delete a print job.
1632 ****************************************************************************/
1633
1634 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1635 {
1636         BOOL    owner, deleted;
1637         char    *fname;
1638
1639         *errcode = WERR_OK;
1640                 
1641         owner = is_owner(user, snum, jobid);
1642         
1643         /* Check access against security descriptor or whether the user
1644            owns their job. */
1645
1646         if (!owner && 
1647             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1648                 DEBUG(3, ("delete denied by security descriptor\n"));
1649                 *errcode = WERR_ACCESS_DENIED;
1650
1651                 /* BEGIN_ADMIN_LOG */
1652                 sys_adminlog( LOG_ERR, 
1653                               "Permission denied-- user not allowed to delete, \
1654 pause, or resume print job. User name: %s. Printer name: %s.",
1655                               uidtoname(user->uid), PRINTERNAME(snum) );
1656                 /* END_ADMIN_LOG */
1657
1658                 return False;
1659         }
1660
1661         /* 
1662          * get the spooled filename of the print job
1663          * if this works, then the file has not been spooled
1664          * to the underlying print system.  Just delete the 
1665          * spool file & return.
1666          */
1667          
1668         if ( (fname = print_job_fname( snum, jobid )) != NULL )
1669         {
1670                 /* remove the spool file */
1671                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1672                 if ( unlink( fname ) == -1 ) {
1673                         *errcode = map_werror_from_unix(errno);
1674                         return False;
1675                 }
1676         }
1677         
1678         if (!print_job_delete1(snum, jobid)) {
1679                 *errcode = WERR_ACCESS_DENIED;
1680                 return False;
1681         }
1682
1683         /* force update the database and say the delete failed if the
1684            job still exists */
1685
1686         print_queue_update(snum);
1687         
1688         deleted = !print_job_exists(snum, jobid);
1689         if ( !deleted )
1690                 *errcode = WERR_ACCESS_DENIED;
1691
1692         return deleted;
1693 }
1694
1695 /****************************************************************************
1696  Pause a job.
1697 ****************************************************************************/
1698
1699 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1700 {
1701         struct printjob *pjob = print_job_find(snum, jobid);
1702         int ret = -1;
1703         struct printif *current_printif = get_printer_fns( snum );
1704         
1705         if (!pjob || !user) 
1706                 return False;
1707
1708         if (!pjob->spooled || pjob->sysjob == -1) 
1709                 return False;
1710
1711         if (!is_owner(user, snum, jobid) &&
1712             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1713                 DEBUG(3, ("pause denied by security descriptor\n"));
1714
1715                 /* BEGIN_ADMIN_LOG */
1716                 sys_adminlog( LOG_ERR, 
1717                         "Permission denied-- user not allowed to delete, \
1718 pause, or resume print job. User name: %s. Printer name: %s.",
1719                                 uidtoname(user->uid), PRINTERNAME(snum) );
1720                 /* END_ADMIN_LOG */
1721
1722                 *errcode = WERR_ACCESS_DENIED;
1723                 return False;
1724         }
1725
1726         /* need to pause the spooled entry */
1727         ret = (*(current_printif->job_pause))(snum, pjob);
1728
1729         if (ret != 0) {
1730                 *errcode = WERR_INVALID_PARAM;
1731                 return False;
1732         }
1733
1734         /* force update the database */
1735         print_cache_flush(snum);
1736
1737         /* Send a printer notify message */
1738
1739         notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1740
1741         /* how do we tell if this succeeded? */
1742
1743         return True;
1744 }
1745
1746 /****************************************************************************
1747  Resume a job.
1748 ****************************************************************************/
1749
1750 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1751 {
1752         struct printjob *pjob = print_job_find(snum, jobid);
1753         int ret;
1754         struct printif *current_printif = get_printer_fns( snum );
1755         
1756         if (!pjob || !user)
1757                 return False;
1758
1759         if (!pjob->spooled || pjob->sysjob == -1)
1760                 return False;
1761
1762         if (!is_owner(user, snum, jobid) &&
1763             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1764                 DEBUG(3, ("resume denied by security descriptor\n"));
1765                 *errcode = WERR_ACCESS_DENIED;
1766
1767                 /* BEGIN_ADMIN_LOG */
1768                 sys_adminlog( LOG_ERR, 
1769                          "Permission denied-- user not allowed to delete, \
1770 pause, or resume print job. User name: %s. Printer name: %s.",
1771                         uidtoname(user->uid), PRINTERNAME(snum) );
1772                 /* END_ADMIN_LOG */
1773                 return False;
1774         }
1775
1776         ret = (*(current_printif->job_resume))(snum, pjob);
1777
1778         if (ret != 0) {
1779                 *errcode = WERR_INVALID_PARAM;
1780                 return False;
1781         }
1782
1783         /* force update the database */
1784         print_cache_flush(snum);
1785
1786         /* Send a printer notify message */
1787
1788         notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1789
1790         return True;
1791 }
1792
1793 /****************************************************************************
1794  Write to a print file.
1795 ****************************************************************************/
1796
1797 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1798 {
1799         int return_code;
1800         struct printjob *pjob = print_job_find(snum, jobid);
1801
1802         if (!pjob)
1803                 return -1;
1804         /* don't allow another process to get this info - it is meaningless */
1805         if (pjob->pid != sys_getpid())
1806                 return -1;
1807
1808         return_code = write(pjob->fd, buf, size);
1809         if (return_code>0) {
1810                 pjob->size += size;
1811                 pjob_store(snum, jobid, pjob);
1812         }
1813         return return_code;
1814 }
1815
1816 /****************************************************************************
1817  Check if the print queue has been updated recently enough.
1818 ****************************************************************************/
1819
1820 static BOOL print_cache_expired(int snum)
1821 {
1822         fstring key;
1823         time_t last_qscan_time, time_now = time(NULL);
1824         const char *printername = lp_const_servicename(snum);
1825         struct tdb_print_db *pdb = get_print_db_byname(printername);
1826
1827         if (!pdb)
1828                 return False;
1829
1830         slprintf(key, sizeof(key), "CACHE/%s", printername);
1831         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1832
1833         /*
1834          * Invalidate the queue for 3 reasons.
1835          * (1). last queue scan time == -1.
1836          * (2). Current time - last queue scan time > allowed cache time.
1837          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1838          * This last test picks up machines for which the clock has been moved
1839          * forward, an lpq scan done and then the clock moved back. Otherwise
1840          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1841          */
1842
1843         if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1844                         last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1845                 DEBUG(3, ("print cache expired for queue %s \
1846 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1847                         (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1848                 release_print_db(pdb);
1849                 return True;
1850         }
1851         release_print_db(pdb);
1852         return False;
1853 }
1854
1855 /****************************************************************************
1856  Get the queue status - do not update if db is out of date.
1857 ****************************************************************************/
1858
1859 static int get_queue_status(int snum, print_status_struct *status)
1860 {
1861         fstring keystr;
1862         TDB_DATA data, key;
1863         const char *printername = lp_const_servicename(snum);
1864         struct tdb_print_db *pdb = get_print_db_byname(printername);
1865         int len;
1866
1867         if (!pdb)
1868                 return 0;
1869
1870         if (status) {
1871                 ZERO_STRUCTP(status);
1872                 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1873                 key.dptr = keystr;
1874                 key.dsize = strlen(keystr);
1875                 data = tdb_fetch(pdb->tdb, key);
1876                 if (data.dptr) {
1877                         if (data.dsize == sizeof(print_status_struct))
1878                                 /* this memcpy is ok since the status struct was 
1879                                    not packed before storing it in the tdb */
1880                                 memcpy(status, data.dptr, sizeof(print_status_struct));
1881                         SAFE_FREE(data.dptr);
1882                 }
1883         }
1884         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1885         release_print_db(pdb);
1886         return (len == -1 ? 0 : len);
1887 }
1888
1889 /****************************************************************************
1890  Determine the number of jobs in a queue.
1891 ****************************************************************************/
1892
1893 int print_queue_length(int snum, print_status_struct *pstatus)
1894 {
1895         print_status_struct status;
1896         int len;
1897  
1898         /* make sure the database is up to date */
1899         if (print_cache_expired(snum))
1900                 print_queue_update(snum);
1901  
1902         /* also fetch the queue status */
1903         memset(&status, 0, sizeof(status));
1904         len = get_queue_status(snum, &status);
1905
1906         if (pstatus)
1907                 *pstatus = status;
1908
1909         return len;
1910 }
1911
1912 /***************************************************************************
1913  Allocate a jobid. Hold the lock for as short a time as possible.
1914 ***************************************************************************/
1915
1916 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1917 {
1918         int i;
1919         uint32 jobid;
1920
1921         *pjobid = (uint32)-1;
1922
1923         for (i = 0; i < 3; i++) {
1924                 /* Lock the database - only wait 20 seconds. */
1925                 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1926                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1927                         return False;
1928                 }
1929
1930                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1931                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1932                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1933                                                 printername ));
1934                                 return False;
1935                         }
1936                         jobid = 0;
1937                 }
1938
1939                 jobid = NEXT_JOBID(jobid);
1940
1941                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1942                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1943                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1944                         return False;
1945                 }
1946
1947                 /* We've finished with the INFO/nextjob lock. */
1948                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1949                                 
1950                 if (!print_job_exists(snum, jobid))
1951                         break;
1952         }
1953
1954         if (i > 2) {
1955                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1956                                 printername ));
1957                 /* Probably full... */
1958                 errno = ENOSPC;
1959                 return False;
1960         }
1961
1962         /* Store a dummy placeholder. */
1963         {
1964                 TDB_DATA dum;
1965                 dum.dptr = NULL;
1966                 dum.dsize = 0;
1967                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1968                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1969                                 jobid ));
1970                         return False;
1971                 }
1972         }
1973
1974         *pjobid = jobid;
1975         return True;
1976 }
1977
1978 /***************************************************************************
1979  Append a jobid to the 'jobs changed' list.
1980 ***************************************************************************/
1981
1982 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1983 {
1984         TDB_DATA data, key;
1985         uint32 store_jobid;
1986
1987         key.dptr = "INFO/jobs_changed";
1988         key.dsize = strlen(key.dptr);
1989         SIVAL(&store_jobid, 0, jobid);
1990         data.dptr = (char *)&store_jobid;
1991         data.dsize = 4;
1992
1993         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
1994
1995         return (tdb_append(pdb->tdb, key, data) == 0);
1996 }
1997
1998 /***************************************************************************
1999  Start spooling a job - return the jobid.
2000 ***************************************************************************/
2001
2002 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2003 {
2004         uint32 jobid;
2005         char *path;
2006         struct printjob pjob;
2007         user_struct *vuser;
2008         const char *printername = lp_const_servicename(snum);
2009         struct tdb_print_db *pdb = get_print_db_byname(printername);
2010         int njobs;
2011
2012         errno = 0;
2013
2014         if (!pdb)
2015                 return (uint32)-1;
2016
2017         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2018                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2019                 release_print_db(pdb);
2020                 return (uint32)-1;
2021         }
2022
2023         if (!print_time_access_check(snum)) {
2024                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
2025                 release_print_db(pdb);
2026                 return (uint32)-1;
2027         }
2028
2029         path = lp_pathname(snum);
2030
2031         /* see if we have sufficient disk space */
2032         if (lp_minprintspace(snum)) {
2033                 SMB_BIG_UINT dspace, dsize;
2034                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2035                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2036                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
2037                         release_print_db(pdb);
2038                         errno = ENOSPC;
2039                         return (uint32)-1;
2040                 }
2041         }
2042
2043         /* for autoloaded printers, check that the printcap entry still exists */
2044         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
2045                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2046                 release_print_db(pdb);
2047                 errno = ENOENT;
2048                 return (uint32)-1;
2049         }
2050
2051         /* Insure the maximum queue size is not violated */
2052         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2053                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2054                         printername, njobs, lp_maxprintjobs(snum) ));
2055                 release_print_db(pdb);
2056                 errno = ENOSPC;
2057                 return (uint32)-1;
2058         }
2059
2060         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2061                         printername, njobs, lp_maxprintjobs(snum) ));
2062
2063         if (!allocate_print_jobid(pdb, snum, printername, &jobid))
2064                 goto fail;
2065
2066         /* create the database entry */
2067         
2068         ZERO_STRUCT(pjob);
2069         
2070         pjob.pid = sys_getpid();
2071         pjob.sysjob = -1;
2072         pjob.fd = -1;
2073         pjob.starttime = time(NULL);
2074         pjob.status = LPQ_SPOOLING;
2075         pjob.size = 0;
2076         pjob.spooled = False;
2077         pjob.smbjob = True;
2078         pjob.nt_devmode = nt_devmode;
2079         
2080         fstrcpy(pjob.jobname, jobname);
2081
2082         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2083                 fstrcpy(pjob.user, vuser->user.smb_name);
2084         } else {
2085                 fstrcpy(pjob.user, uidtoname(user->uid));
2086         }
2087
2088         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2089
2090         /* we have a job entry - now create the spool file */
2091         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
2092                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2093         pjob.fd = smb_mkstemp(pjob.filename);
2094
2095         if (pjob.fd == -1) {
2096                 if (errno == EACCES) {
2097                         /* Common setup error, force a report. */
2098                         DEBUG(0, ("print_job_start: insufficient permissions \
2099 to open spool file %s.\n", pjob.filename));
2100                 } else {
2101                         /* Normal case, report at level 3 and above. */
2102                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2103                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2104                 }
2105                 goto fail;
2106         }
2107
2108         pjob_store(snum, jobid, &pjob);
2109
2110         /* Update the 'jobs changed' entry used by print_queue_status. */
2111         add_to_jobs_changed(pdb, jobid);
2112
2113         /* Ensure we keep a rough count of the number of total jobs... */
2114         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2115
2116         release_print_db(pdb);
2117
2118         return jobid;
2119
2120  fail:
2121         if (jobid != -1)
2122                 pjob_delete(snum, jobid);
2123
2124         release_print_db(pdb);
2125
2126         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2127         return (uint32)-1;
2128 }
2129
2130 /****************************************************************************
2131  Update the number of pages spooled to jobid
2132 ****************************************************************************/
2133
2134 void print_job_endpage(int snum, uint32 jobid)
2135 {
2136         struct printjob *pjob = print_job_find(snum, jobid);
2137         if (!pjob)
2138                 return;
2139         /* don't allow another process to get this info - it is meaningless */
2140         if (pjob->pid != sys_getpid())
2141                 return;
2142
2143         pjob->page_count++;
2144         pjob_store(snum, jobid, pjob);
2145 }
2146
2147 /****************************************************************************
2148  Print a file - called on closing the file. This spools the job.
2149  If normal close is false then we're tearing down the jobs - treat as an
2150  error.
2151 ****************************************************************************/
2152
2153 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2154 {
2155         struct printjob *pjob = print_job_find(snum, jobid);
2156         int ret;
2157         SMB_STRUCT_STAT sbuf;
2158         struct printif *current_printif = get_printer_fns( snum );
2159
2160         if (!pjob)
2161                 return False;
2162
2163         if (pjob->spooled || pjob->pid != sys_getpid())
2164                 return False;
2165
2166         if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2167                 pjob->size = sbuf.st_size;
2168                 close(pjob->fd);
2169                 pjob->fd = -1;
2170         } else {
2171
2172                 /* 
2173                  * Not a normal close or we couldn't stat the job file,
2174                  * so something has gone wrong. Cleanup.
2175                  */
2176                 close(pjob->fd);
2177                 pjob->fd = -1;
2178                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2179                 goto fail;
2180         }
2181
2182         /* Technically, this is not quite right. If the printer has a separator
2183          * page turned on, the NT spooler prints the separator page even if the
2184          * print job is 0 bytes. 010215 JRR */
2185         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2186                 /* don't bother spooling empty files or something being deleted. */
2187                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2188                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2189                 unlink(pjob->filename);
2190                 pjob_delete(snum, jobid);
2191                 return True;
2192         }
2193
2194         pjob->smbjob = jobid;
2195
2196         ret = (*(current_printif->job_submit))(snum, pjob);
2197
2198         if (ret)
2199                 goto fail;
2200
2201         /* The print job has been sucessfully handed over to the back-end */
2202         
2203         pjob->spooled = True;
2204         pjob->status = LPQ_QUEUED;
2205         pjob_store(snum, jobid, pjob);
2206         
2207         /* make sure the database is up to date */
2208         if (print_cache_expired(snum))
2209                 print_queue_update(snum);
2210         
2211         return True;
2212
2213 fail:
2214
2215         /* The print job was not succesfully started. Cleanup */
2216         /* Still need to add proper error return propagation! 010122:JRR */
2217         unlink(pjob->filename);
2218         pjob_delete(snum, jobid);
2219         return False;
2220 }
2221
2222 /****************************************************************************
2223  Get a snapshot of jobs in the system without traversing.
2224 ****************************************************************************/
2225
2226 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2227 {
2228         TDB_DATA data, key, cgdata;
2229         print_queue_struct *queue = NULL;
2230         uint32 qcount = 0;
2231         uint32 extra_count = 0;
2232         int total_count = 0;
2233         size_t len = 0;
2234         uint32 i;
2235         int max_reported_jobs = lp_max_reported_jobs(snum);
2236         BOOL ret = False;
2237
2238         /* make sure the database is up to date */
2239         if (print_cache_expired(snum))
2240                 print_queue_update(snum);
2241  
2242         *pcount = 0;
2243         *ppqueue = NULL;
2244
2245         ZERO_STRUCT(data);
2246         ZERO_STRUCT(cgdata);
2247         key.dptr = "INFO/linear_queue_array";
2248         key.dsize = strlen(key.dptr);
2249
2250         /* Get the stored queue data. */
2251         data = tdb_fetch(pdb->tdb, key);
2252         
2253         if (data.dptr && data.dsize >= sizeof(qcount))
2254                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2255                 
2256         /* Get the changed jobs list. */
2257         key.dptr = "INFO/jobs_changed";
2258         key.dsize = strlen(key.dptr);
2259
2260         cgdata = tdb_fetch(pdb->tdb, key);
2261         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2262                 extra_count = cgdata.dsize/4;
2263
2264         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2265
2266         /* Allocate the queue size. */
2267         if (qcount == 0 && extra_count == 0)
2268                 goto out;
2269
2270         if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2271                 goto out;
2272
2273         /* Retrieve the linearised queue data. */
2274
2275         for( i  = 0; i < qcount; i++) {
2276                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2277                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2278                                 &qjob,
2279                                 &qsize,
2280                                 &qpage_count,
2281                                 &qstatus,
2282                                 &qpriority,
2283                                 &qtime,
2284                                 queue[i].fs_user,
2285                                 queue[i].fs_file);
2286                 queue[i].job = qjob;
2287                 queue[i].size = qsize;
2288                 queue[i].page_count = qpage_count;
2289                 queue[i].status = qstatus;
2290                 queue[i].priority = qpriority;
2291                 queue[i].time = qtime;
2292         }
2293
2294         total_count = qcount;
2295
2296         /* Add in the changed jobids. */
2297         for( i  = 0; i < extra_count; i++) {
2298                 uint32 jobid;
2299                 struct printjob *pjob;
2300
2301                 jobid = IVAL(cgdata.dptr, i*4);
2302                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2303                 pjob = print_job_find(snum, jobid);
2304                 if (!pjob) {
2305                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2306                         remove_from_jobs_changed(snum, jobid);
2307                         continue;
2308                 }
2309
2310                 queue[total_count].job = jobid;
2311                 queue[total_count].size = pjob->size;
2312                 queue[total_count].page_count = pjob->page_count;
2313                 queue[total_count].status = pjob->status;
2314                 queue[total_count].priority = 1;
2315                 queue[total_count].time = pjob->starttime;
2316                 fstrcpy(queue[total_count].fs_user, pjob->user);
2317                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2318                 total_count++;
2319         }
2320
2321         /* Sort the queue by submission time otherwise they are displayed
2322            in hash order. */
2323
2324         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2325
2326         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2327
2328         if (max_reported_jobs && total_count > max_reported_jobs)
2329                 total_count = max_reported_jobs;
2330
2331         *ppqueue = queue;
2332         *pcount = total_count;
2333
2334         ret = True;
2335
2336   out:
2337
2338         SAFE_FREE(data.dptr);
2339         SAFE_FREE(cgdata.dptr);
2340         return ret;
2341 }
2342
2343 /****************************************************************************
2344  Get a printer queue listing.
2345  set queue = NULL and status = NULL if you just want to update the cache
2346 ****************************************************************************/
2347
2348 int print_queue_status(int snum, 
2349                        print_queue_struct **ppqueue,
2350                        print_status_struct *status)
2351 {
2352         fstring keystr;
2353         TDB_DATA data, key;
2354         const char *printername;
2355         struct tdb_print_db *pdb;
2356         int count = 0;
2357
2358         /* make sure the database is up to date */
2359
2360         if (print_cache_expired(snum))
2361                 print_queue_update(snum);
2362
2363         /* return if we are done */
2364         if ( !ppqueue || !status )
2365                 return 0;
2366
2367         *ppqueue = NULL;
2368         printername = lp_const_servicename(snum);
2369         pdb = get_print_db_byname(printername);
2370
2371         if (!pdb)
2372                 return 0;
2373
2374         /*
2375          * Fetch the queue status.  We must do this first, as there may
2376          * be no jobs in the queue.
2377          */
2378
2379         ZERO_STRUCTP(status);
2380         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2381         key.dptr = keystr;
2382         key.dsize = strlen(keystr);
2383         data = tdb_fetch(pdb->tdb, key);
2384         if (data.dptr) {
2385                 if (data.dsize == sizeof(*status)) {
2386                         /* this memcpy is ok since the status struct was 
2387                            not packed before storing it in the tdb */
2388                         memcpy(status, data.dptr, sizeof(*status));
2389                 }
2390                 SAFE_FREE(data.dptr);
2391         }
2392
2393         /*
2394          * Now, fetch the print queue information.  We first count the number
2395          * of entries, and then only retrieve the queue if necessary.
2396          */
2397
2398         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2399                 release_print_db(pdb);
2400                 return 0;
2401         }
2402
2403         release_print_db(pdb);
2404         return count;
2405 }
2406
2407 /****************************************************************************
2408  Pause a queue.
2409 ****************************************************************************/
2410
2411 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2412 {
2413         int ret;
2414         struct printif *current_printif = get_printer_fns( snum );
2415         
2416         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2417                 *errcode = WERR_ACCESS_DENIED;
2418                 return False;
2419         }
2420
2421         ret = (*(current_printif->queue_pause))(snum);
2422
2423         if (ret != 0) {
2424                 *errcode = WERR_INVALID_PARAM;
2425                 return False;
2426         }
2427
2428         /* force update the database */
2429         print_cache_flush(snum);
2430
2431         /* Send a printer notify message */
2432
2433         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2434
2435         return True;
2436 }
2437
2438 /****************************************************************************
2439  Resume a queue.
2440 ****************************************************************************/
2441
2442 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2443 {
2444         int ret;
2445         struct printif *current_printif = get_printer_fns( snum );
2446
2447         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2448                 *errcode = WERR_ACCESS_DENIED;
2449                 return False;
2450         }
2451
2452         ret = (*(current_printif->queue_resume))(snum);
2453
2454         if (ret != 0) {
2455                 *errcode = WERR_INVALID_PARAM;
2456                 return False;
2457         }
2458
2459         /* make sure the database is up to date */
2460         if (print_cache_expired(snum))
2461                 print_queue_update(snum);
2462
2463         /* Send a printer notify message */
2464
2465         notify_printer_status(snum, PRINTER_STATUS_OK);
2466
2467         return True;
2468 }
2469
2470 /****************************************************************************
2471  Purge a queue - implemented by deleting all jobs that we can delete.
2472 ****************************************************************************/
2473
2474 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2475 {
2476         print_queue_struct *queue;
2477         print_status_struct status;
2478         int njobs, i;
2479         BOOL can_job_admin;
2480
2481         /* Force and update so the count is accurate (i.e. not a cached count) */
2482         print_queue_update(snum);
2483         
2484         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2485         njobs = print_queue_status(snum, &queue, &status);
2486
2487         for (i=0;i<njobs;i++) {
2488                 BOOL owner = is_owner(user, snum, queue[i].job);
2489
2490                 if (owner || can_job_admin) {
2491                         print_job_delete1(snum, queue[i].job);
2492                 }
2493         }
2494
2495         SAFE_FREE(queue);
2496
2497         return True;
2498 }