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