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