i guess i'm the only one this ever annyoed...
[ira/wip.git] / source3 / printing / printing.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing backend routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    Copyright (C) Jeremy Allison 2002
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "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, "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         SAFE_FREE(data.dptr);
893         return;
894 }
895
896 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
897 {
898         TDB_DATA data, key;
899
900         key.dptr = "INFO/jobs_changed";
901         key.dsize = strlen(key.dptr);
902         ZERO_STRUCT(data);
903
904         data = tdb_fetch(pdb->tdb, key);
905         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
906                 SAFE_FREE(data.dptr);
907                 ZERO_STRUCT(data);
908         }
909
910         return data;
911 }
912
913 static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
914 {
915         unsigned int i;
916         unsigned int job_count = data.dsize / 4;
917
918         for (i = 0; i < job_count; i++) {
919                 uint32 ch_jobid;
920
921                 memcpy(&ch_jobid, data.dptr + (i*4), 4);
922                 if (ch_jobid == jobid)
923                         remove_from_jobs_changed(snum, jobid);
924         }
925 }
926
927 /****************************************************************************
928  Update the internal database from the system print queue for a queue.
929 ****************************************************************************/
930
931 static void print_queue_update(int snum)
932 {
933         int i, qcount;
934         print_queue_struct *queue = NULL;
935         print_status_struct status;
936         print_status_struct old_status;
937         struct printjob *pjob;
938         struct traverse_struct tstruct;
939         fstring keystr, printer_name, cachestr;
940         TDB_DATA data, key;
941         TDB_DATA jcdata;
942         struct tdb_print_db *pdb;
943
944         fstrcpy(printer_name, lp_const_servicename(snum));
945         pdb = get_print_db_byname(printer_name);
946         if (!pdb)
947                 return;
948
949         /*
950          * Check to see if someone else is doing this update.
951          * This is essentially a mutex on the update.
952          */
953
954         if (get_updating_pid(printer_name) != -1) {
955                 release_print_db(pdb);
956                 return;
957         }
958
959         /* Lock the queue for the database update */
960
961         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
962         /* Only wait 10 seconds for this. */
963         if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
964                 DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
965                 release_print_db(pdb);
966                 return;
967         }
968
969         /*
970          * Ensure that no one else got in here.
971          * If the updating pid is still -1 then we are
972          * the winner.
973          */
974
975         if (get_updating_pid(printer_name) != -1) {
976                 /*
977                  * Someone else is doing the update, exit.
978                  */
979                 tdb_unlock_bystring(pdb->tdb, keystr);
980                 release_print_db(pdb);
981                 return;
982         }
983
984         /*
985          * We're going to do the update ourselves.
986          */
987
988         /* Tell others we're doing the update. */
989         set_updating_pid(printer_name, False);
990
991         /*
992          * Allow others to enter and notice we're doing
993          * the update.
994          */
995
996         tdb_unlock_bystring(pdb->tdb, keystr);
997
998         /*
999          * Update the cache time FIRST ! Stops others even
1000          * attempting to get the lock and doing this
1001          * if the lpq takes a long time.
1002          */
1003
1004         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
1005         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1006
1007         /* get the current queue using the appropriate interface */
1008         ZERO_STRUCT(status);
1009
1010         qcount = (*(current_printif->queue_get))(snum, &queue, &status);
1011
1012         DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
1013                 "s" : "", printer_name));
1014
1015         /* Sort the queue by submission time otherwise they are displayed
1016            in hash order. */
1017
1018         qsort(queue, qcount, sizeof(print_queue_struct),
1019               QSORT_CAST(printjob_comp));
1020
1021         /*
1022           any job in the internal database that is marked as spooled
1023           and doesn't exist in the system queue is considered finished
1024           and removed from the database
1025
1026           any job in the system database but not in the internal database 
1027           is added as a unix job
1028
1029           fill in any system job numbers as we go
1030         */
1031
1032         jcdata = get_jobs_changed_data(pdb);
1033
1034         for (i=0; i<qcount; i++) {
1035                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1036
1037                 if (jobid == (uint32)-1) {
1038                         /* assume its a unix print job */
1039                         print_unix_job(snum, &queue[i], jobid);
1040                         continue;
1041                 }
1042
1043                 /* we have an active SMB print job - update its status */
1044                 pjob = print_job_find(snum, jobid);
1045                 if (!pjob) {
1046                         /* err, somethings wrong. Probably smbd was restarted
1047                            with jobs in the queue. All we can do is treat them
1048                            like unix jobs. Pity. */
1049                         print_unix_job(snum, &queue[i], jobid);
1050                         continue;
1051                 }
1052
1053                 pjob->sysjob = queue[i].job;
1054                 pjob->status = queue[i].status;
1055                 pjob_store(snum, jobid, pjob);
1056                 check_job_changed(snum, jcdata, jobid);
1057         }
1058
1059         SAFE_FREE(jcdata.dptr);
1060
1061         /* now delete any queued entries that don't appear in the
1062            system queue */
1063         tstruct.queue = queue;
1064         tstruct.qcount = qcount;
1065         tstruct.snum = snum;
1066         tstruct.total_jobs = 0;
1067         tstruct.lpq_time = time(NULL);
1068
1069         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1070
1071         /* Store the linearised queue, max jobs only. */
1072         store_queue_struct(pdb, &tstruct);
1073
1074         SAFE_FREE(tstruct.queue);
1075
1076         DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
1077                                 printer_name, tstruct.total_jobs ));
1078
1079         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1080
1081         get_queue_status(snum, &old_status);
1082         if (old_status.qcount != qcount)
1083                 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
1084                                         old_status.qcount, qcount, printer_name ));
1085
1086         /* store the new queue status structure */
1087         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
1088         key.dptr = keystr;
1089         key.dsize = strlen(keystr);
1090
1091         status.qcount = qcount;
1092         data.dptr = (void *)&status;
1093         data.dsize = sizeof(status);
1094         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
1095
1096         /*
1097          * Update the cache time again. We want to do this call
1098          * as little as possible...
1099          */
1100
1101         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
1102         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1103
1104         /* Delete our pid from the db. */
1105         set_updating_pid(printer_name, True);
1106         release_print_db(pdb);
1107 }
1108
1109 /****************************************************************************
1110  Create/Update an entry in the print tdb that will allow us to send notify
1111  updates only to interested smbd's. 
1112 ****************************************************************************/
1113
1114 BOOL print_notify_register_pid(int snum)
1115 {
1116         TDB_DATA data;
1117         struct tdb_print_db *pdb = NULL;
1118         TDB_CONTEXT *tdb = NULL;
1119         const char *printername;
1120         uint32 mypid = (uint32)sys_getpid();
1121         BOOL ret = False;
1122         size_t i;
1123
1124         /* if (snum == -1), then the change notify request was
1125            on a print server handle and we need to register on
1126            all print queus */
1127            
1128         if (snum == -1) 
1129         {
1130                 int num_services = lp_numservices();
1131                 int idx;
1132                 
1133                 for ( idx=0; idx<num_services; idx++ ) {
1134                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1135                                 print_notify_register_pid(idx);
1136                 }
1137                 
1138                 return True;
1139         }
1140         else /* register for a specific printer */
1141         {
1142                 printername = lp_const_servicename(snum);
1143                 pdb = get_print_db_byname(printername);
1144                 if (!pdb)
1145                         return False;
1146                 tdb = pdb->tdb;
1147         }
1148
1149         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1150                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1151                                         printername));
1152                 if (pdb)
1153                         release_print_db(pdb);
1154                 return False;
1155         }
1156
1157         data = get_printer_notify_pid_list( tdb, printername, True );
1158
1159         /* Add ourselves and increase the refcount. */
1160
1161         for (i = 0; i < data.dsize; i += 8) {
1162                 if (IVAL(data.dptr,i) == mypid) {
1163                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1164                         SIVAL(data.dptr, i+4, new_refcount);
1165                         break;
1166                 }
1167         }
1168
1169         if (i == data.dsize) {
1170                 /* We weren't in the list. Realloc. */
1171                 data.dptr = Realloc(data.dptr, data.dsize + 8);
1172                 if (!data.dptr) {
1173                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1174                                                 printername));
1175                         goto done;
1176                 }
1177                 data.dsize += 8;
1178                 SIVAL(data.dptr,data.dsize - 8,mypid);
1179                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1180         }
1181
1182         /* Store back the record. */
1183         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1184                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1185 list for printer %s\n", printername));
1186                 goto done;
1187         }
1188
1189         ret = True;
1190
1191  done:
1192
1193         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1194         if (pdb)
1195                 release_print_db(pdb);
1196         SAFE_FREE(data.dptr);
1197         return ret;
1198 }
1199
1200 /****************************************************************************
1201  Update an entry in the print tdb that will allow us to send notify
1202  updates only to interested smbd's. 
1203 ****************************************************************************/
1204
1205 BOOL print_notify_deregister_pid(int snum)
1206 {
1207         TDB_DATA data;
1208         struct tdb_print_db *pdb = NULL;
1209         TDB_CONTEXT *tdb = NULL;
1210         const char *printername;
1211         uint32 mypid = (uint32)sys_getpid();
1212         size_t i;
1213         BOOL ret = False;
1214
1215         /* if ( snum == -1 ), we are deregister a print server handle
1216            which means to deregister on all print queues */
1217            
1218         if (snum == -1) 
1219         {
1220                 int num_services = lp_numservices();
1221                 int idx;
1222                 
1223                 for ( idx=0; idx<num_services; idx++ ) {
1224                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1225                                 print_notify_deregister_pid(idx);
1226                 }
1227                 
1228                 return True;
1229         }
1230         else /* deregister a specific printer */
1231         {
1232                 printername = lp_const_servicename(snum);
1233                 pdb = get_print_db_byname(printername);
1234                 if (!pdb)
1235                         return False;
1236                 tdb = pdb->tdb;
1237         }
1238
1239         if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1240                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1241 printer %s database\n", printername));
1242                 if (pdb)
1243                         release_print_db(pdb);
1244                 return False;
1245         }
1246
1247         data = get_printer_notify_pid_list( tdb, printername, True );
1248
1249         /* Reduce refcount. Remove ourselves if zero. */
1250
1251         for (i = 0; i < data.dsize; ) {
1252                 if (IVAL(data.dptr,i) == mypid) {
1253                         uint32 refcount = IVAL(data.dptr, i+4);
1254
1255                         refcount--;
1256
1257                         if (refcount == 0) {
1258                                 if (data.dsize - i > 8)
1259                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1260                                 data.dsize -= 8;
1261                                 continue;
1262                         }
1263                         SIVAL(data.dptr, i+4, refcount);
1264                 }
1265
1266                 i += 8;
1267         }
1268
1269         if (data.dsize == 0)
1270                 SAFE_FREE(data.dptr);
1271
1272         /* Store back the record. */
1273         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1274                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1275 list for printer %s\n", printername));
1276                 goto done;
1277         }
1278
1279         ret = True;
1280
1281   done:
1282
1283         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1284         if (pdb)
1285                 release_print_db(pdb);
1286         SAFE_FREE(data.dptr);
1287         return ret;
1288 }
1289
1290 /****************************************************************************
1291  Check if a jobid is valid. It is valid if it exists in the database.
1292 ****************************************************************************/
1293
1294 BOOL print_job_exists(int snum, uint32 jobid)
1295 {
1296         struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
1297         BOOL ret;
1298
1299         if (!pdb)
1300                 return False;
1301         ret = tdb_exists(pdb->tdb, print_key(jobid));
1302         release_print_db(pdb);
1303         return ret;
1304 }
1305
1306 /****************************************************************************
1307  Give the fd used for a jobid.
1308 ****************************************************************************/
1309
1310 int print_job_fd(int snum, uint32 jobid)
1311 {
1312         struct printjob *pjob = print_job_find(snum, jobid);
1313         if (!pjob)
1314                 return -1;
1315         /* don't allow another process to get this info - it is meaningless */
1316         if (pjob->pid != local_pid)
1317                 return -1;
1318         return pjob->fd;
1319 }
1320
1321 /****************************************************************************
1322  Give the filename used for a jobid.
1323  Only valid for the process doing the spooling and when the job
1324  has not been spooled.
1325 ****************************************************************************/
1326
1327 char *print_job_fname(int snum, uint32 jobid)
1328 {
1329         struct printjob *pjob = print_job_find(snum, jobid);
1330         if (!pjob || pjob->spooled || pjob->pid != local_pid)
1331                 return NULL;
1332         return pjob->filename;
1333 }
1334
1335
1336 /****************************************************************************
1337  Give the filename used for a jobid.
1338  Only valid for the process doing the spooling and when the job
1339  has not been spooled.
1340 ****************************************************************************/
1341
1342 NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
1343 {
1344         struct printjob *pjob = print_job_find(snum, jobid);
1345         
1346         if ( !pjob )
1347                 return NULL;
1348                 
1349         return pjob->nt_devmode;
1350 }
1351
1352 /****************************************************************************
1353  Set the place in the queue for a job.
1354 ****************************************************************************/
1355
1356 BOOL print_job_set_place(int snum, uint32 jobid, int place)
1357 {
1358         DEBUG(2,("print_job_set_place not implemented yet\n"));
1359         return False;
1360 }
1361
1362 /****************************************************************************
1363  Set the name of a job. Only possible for owner.
1364 ****************************************************************************/
1365
1366 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1367 {
1368         struct printjob *pjob = print_job_find(snum, jobid);
1369         if (!pjob || pjob->pid != local_pid)
1370                 return False;
1371
1372         fstrcpy(pjob->jobname, name);
1373         return pjob_store(snum, jobid, pjob);
1374 }
1375
1376 /***************************************************************************
1377  Remove a jobid from the 'jobs changed' list.
1378 ***************************************************************************/
1379
1380 static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
1381 {
1382         const char *printername = lp_const_servicename(snum);
1383         struct tdb_print_db *pdb = get_print_db_byname(printername);
1384         TDB_DATA data, key;
1385         size_t job_count, i;
1386         BOOL ret = False;
1387         BOOL gotlock = False;
1388
1389         key.dptr = "INFO/jobs_changed";
1390         key.dsize = strlen(key.dptr);
1391         ZERO_STRUCT(data);
1392
1393         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1394                 goto out;
1395
1396         gotlock = True;
1397
1398         data = tdb_fetch(pdb->tdb, key);
1399
1400         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1401                 goto out;
1402
1403         job_count = data.dsize / 4;
1404         for (i = 0; i < job_count; i++) {
1405                 uint32 ch_jobid;
1406
1407                 memcpy(&ch_jobid, data.dptr + (i*4), 4);
1408                 if (ch_jobid == jobid) {
1409                         if (i < job_count -1 )
1410                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1411                         data.dsize -= 4;
1412                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1413                                 goto out;
1414                         break;
1415                 }
1416         }
1417
1418         ret = True;
1419   out:
1420
1421         if (gotlock)
1422                 tdb_chainunlock(pdb->tdb, key);
1423         SAFE_FREE(data.dptr);
1424         release_print_db(pdb);
1425         if (ret)
1426                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1427         else
1428                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1429         return ret;
1430 }
1431
1432 /****************************************************************************
1433  Delete a print job - don't update queue.
1434 ****************************************************************************/
1435
1436 static BOOL print_job_delete1(int snum, uint32 jobid)
1437 {
1438         struct printjob *pjob = print_job_find(snum, jobid);
1439         int result = 0;
1440
1441         if (!pjob)
1442                 return False;
1443
1444         /*
1445          * If already deleting just return.
1446          */
1447
1448         if (pjob->status == LPQ_DELETING)
1449                 return True;
1450
1451         /* Hrm - we need to be able to cope with deleting a job before it
1452            has reached the spooler. */
1453
1454         if (pjob->sysjob == -1) {
1455                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1456         }
1457
1458         /* Set the tdb entry to be deleting. */
1459
1460         pjob->status = LPQ_DELETING;
1461         pjob_store(snum, jobid, pjob);
1462
1463         if (pjob->spooled && pjob->sysjob != -1)
1464                 result = (*(current_printif->job_delete))(snum, pjob);
1465         else
1466                 remove_from_jobs_changed(snum, jobid);
1467
1468         /* Delete the tdb entry if the delete succeeded or the job hasn't
1469            been spooled. */
1470
1471         if (result == 0) {
1472                 const char *printername = lp_const_servicename(snum);
1473                 struct tdb_print_db *pdb = get_print_db_byname(printername);
1474                 int njobs = 1;
1475
1476                 if (!pdb)
1477                         return False;
1478                 pjob_delete(snum, jobid);
1479                 /* Ensure we keep a rough count of the number of total jobs... */
1480                 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1481                 release_print_db(pdb);
1482         }
1483
1484         return (result == 0);
1485 }
1486
1487 /****************************************************************************
1488  Return true if the current user owns the print job.
1489 ****************************************************************************/
1490
1491 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1492 {
1493         struct printjob *pjob = print_job_find(snum, jobid);
1494         user_struct *vuser;
1495
1496         if (!pjob || !user)
1497                 return False;
1498
1499         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1500                 return strequal(pjob->user, vuser->user.smb_name);
1501         } else {
1502                 return strequal(pjob->user, uidtoname(user->uid));
1503         }
1504 }
1505
1506 /****************************************************************************
1507  Delete a print job.
1508 ****************************************************************************/
1509
1510 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1511 {
1512         BOOL    owner, deleted;
1513         char    *fname;
1514
1515         *errcode = WERR_OK;
1516                 
1517         owner = is_owner(user, snum, jobid);
1518         
1519         /* Check access against security descriptor or whether the user
1520            owns their job. */
1521
1522         if (!owner && 
1523             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1524                 DEBUG(3, ("delete denied by security descriptor\n"));
1525                 *errcode = WERR_ACCESS_DENIED;
1526
1527                 /* BEGIN_ADMIN_LOG */
1528                 sys_adminlog( LOG_ERR, 
1529                               "Permission denied-- user not allowed to delete, \
1530 pause, or resume print job. User name: %s. Printer name: %s.",
1531                               uidtoname(user->uid), PRINTERNAME(snum) );
1532                 /* END_ADMIN_LOG */
1533
1534                 return False;
1535         }
1536
1537         /* 
1538          * get the spooled filename of the print job
1539          * if this works, then the file has not been spooled
1540          * to the underlying print system.  Just delete the 
1541          * spool file & return.
1542          */
1543          
1544         if ( (fname = print_job_fname( snum, jobid )) != NULL )
1545         {
1546                 /* remove the spool file */
1547                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1548                 if ( unlink( fname ) == -1 ) {
1549                         *errcode = map_werror_from_unix(errno);
1550                         return False;
1551                 }
1552                 
1553                 return True;
1554         }
1555         
1556         if (!print_job_delete1(snum, jobid)) {
1557                 *errcode = WERR_ACCESS_DENIED;
1558                 return False;
1559         }
1560
1561         /* force update the database and say the delete failed if the
1562            job still exists */
1563
1564         print_queue_update(snum);
1565         
1566         deleted = !print_job_exists(snum, jobid);
1567         if ( !deleted )
1568                 *errcode = WERR_ACCESS_DENIED;
1569
1570         return deleted;
1571 }
1572
1573 /****************************************************************************
1574  Pause a job.
1575 ****************************************************************************/
1576
1577 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1578 {
1579         struct printjob *pjob = print_job_find(snum, jobid);
1580         int ret = -1;
1581         
1582         if (!pjob || !user) 
1583                 return False;
1584
1585         if (!pjob->spooled || pjob->sysjob == -1) 
1586                 return False;
1587
1588         if (!is_owner(user, snum, jobid) &&
1589             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1590                 DEBUG(3, ("pause denied by security descriptor\n"));
1591
1592                 /* BEGIN_ADMIN_LOG */
1593                 sys_adminlog( LOG_ERR, 
1594                         "Permission denied-- user not allowed to delete, \
1595 pause, or resume print job. User name: %s. Printer name: %s.",
1596                                 uidtoname(user->uid), PRINTERNAME(snum) );
1597                 /* END_ADMIN_LOG */
1598
1599                 *errcode = WERR_ACCESS_DENIED;
1600                 return False;
1601         }
1602
1603         /* need to pause the spooled entry */
1604         ret = (*(current_printif->job_pause))(snum, pjob);
1605
1606         if (ret != 0) {
1607                 *errcode = WERR_INVALID_PARAM;
1608                 return False;
1609         }
1610
1611         /* force update the database */
1612         print_cache_flush(snum);
1613
1614         /* Send a printer notify message */
1615
1616         notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
1617
1618         /* how do we tell if this succeeded? */
1619
1620         return True;
1621 }
1622
1623 /****************************************************************************
1624  Resume a job.
1625 ****************************************************************************/
1626
1627 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1628 {
1629         struct printjob *pjob = print_job_find(snum, jobid);
1630         int ret;
1631         
1632         if (!pjob || !user)
1633                 return False;
1634
1635         if (!pjob->spooled || pjob->sysjob == -1)
1636                 return False;
1637
1638         if (!is_owner(user, snum, jobid) &&
1639             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1640                 DEBUG(3, ("resume denied by security descriptor\n"));
1641                 *errcode = WERR_ACCESS_DENIED;
1642
1643                 /* BEGIN_ADMIN_LOG */
1644                 sys_adminlog( LOG_ERR, 
1645                          "Permission denied-- user not allowed to delete, \
1646 pause, or resume print job. User name: %s. Printer name: %s.",
1647                         uidtoname(user->uid), PRINTERNAME(snum) );
1648                 /* END_ADMIN_LOG */
1649                 return False;
1650         }
1651
1652         ret = (*(current_printif->job_resume))(snum, pjob);
1653
1654         if (ret != 0) {
1655                 *errcode = WERR_INVALID_PARAM;
1656                 return False;
1657         }
1658
1659         /* force update the database */
1660         print_cache_flush(snum);
1661
1662         /* Send a printer notify message */
1663
1664         notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
1665
1666         return True;
1667 }
1668
1669 /****************************************************************************
1670  Write to a print file.
1671 ****************************************************************************/
1672
1673 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
1674 {
1675         int return_code;
1676         struct printjob *pjob = print_job_find(snum, jobid);
1677
1678         if (!pjob)
1679                 return -1;
1680         /* don't allow another process to get this info - it is meaningless */
1681         if (pjob->pid != local_pid)
1682                 return -1;
1683
1684         return_code = write(pjob->fd, buf, size);
1685         if (return_code>0) {
1686                 pjob->size += size;
1687                 pjob_store(snum, jobid, pjob);
1688         }
1689         return return_code;
1690 }
1691
1692 /****************************************************************************
1693  Check if the print queue has been updated recently enough.
1694 ****************************************************************************/
1695
1696 static BOOL print_cache_expired(int snum)
1697 {
1698         fstring key;
1699         time_t last_qscan_time, time_now = time(NULL);
1700         const char *printername = lp_const_servicename(snum);
1701         struct tdb_print_db *pdb = get_print_db_byname(printername);
1702
1703         if (!pdb)
1704                 return False;
1705
1706         slprintf(key, sizeof(key), "CACHE/%s", printername);
1707         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1708
1709         /*
1710          * Invalidate the queue for 3 reasons.
1711          * (1). last queue scan time == -1.
1712          * (2). Current time - last queue scan time > allowed cache time.
1713          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1714          * This last test picks up machines for which the clock has been moved
1715          * forward, an lpq scan done and then the clock moved back. Otherwise
1716          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1717          */
1718
1719         if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
1720                         last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
1721                 DEBUG(3, ("print cache expired for queue %s \
1722 (last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
1723                         (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
1724                 release_print_db(pdb);
1725                 return True;
1726         }
1727         release_print_db(pdb);
1728         return False;
1729 }
1730
1731 /****************************************************************************
1732  Get the queue status - do not update if db is out of date.
1733 ****************************************************************************/
1734
1735 static int get_queue_status(int snum, print_status_struct *status)
1736 {
1737         fstring keystr;
1738         TDB_DATA data, key;
1739         const char *printername = lp_const_servicename(snum);
1740         struct tdb_print_db *pdb = get_print_db_byname(printername);
1741         int len;
1742
1743         if (!pdb)
1744                 return 0;
1745
1746         if (status) {
1747                 ZERO_STRUCTP(status);
1748                 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
1749                 key.dptr = keystr;
1750                 key.dsize = strlen(keystr);
1751                 data = tdb_fetch(pdb->tdb, key);
1752                 if (data.dptr) {
1753                         if (data.dsize == sizeof(print_status_struct))
1754                                 memcpy(status, data.dptr, sizeof(print_status_struct));
1755                         SAFE_FREE(data.dptr);
1756                 }
1757         }
1758         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
1759         release_print_db(pdb);
1760         return (len == -1 ? 0 : len);
1761 }
1762
1763 /****************************************************************************
1764  Determine the number of jobs in a queue.
1765 ****************************************************************************/
1766
1767 int print_queue_length(int snum, print_status_struct *pstatus)
1768 {
1769         print_status_struct status;
1770         int len;
1771  
1772         /* make sure the database is up to date */
1773         if (print_cache_expired(snum))
1774                 print_queue_update(snum);
1775  
1776         /* also fetch the queue status */
1777         memset(&status, 0, sizeof(status));
1778         len = get_queue_status(snum, &status);
1779
1780         if (pstatus)
1781                 *pstatus = status;
1782
1783         return len;
1784 }
1785
1786 /***************************************************************************
1787  Allocate a jobid. Hold the lock for as short a time as possible.
1788 ***************************************************************************/
1789
1790 static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
1791 {
1792         int i;
1793         uint32 jobid;
1794
1795         *pjobid = (uint32)-1;
1796
1797         for (i = 0; i < 3; i++) {
1798                 /* Lock the database - only wait 20 seconds. */
1799                 if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
1800                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
1801                         return False;
1802                 }
1803
1804                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
1805                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
1806                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
1807                                                 printername ));
1808                                 return False;
1809                         }
1810                         jobid = 0;
1811                 }
1812
1813                 jobid = NEXT_JOBID(jobid);
1814
1815                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
1816                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
1817                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1818                         return False;
1819                 }
1820
1821                 /* We've finished with the INFO/nextjob lock. */
1822                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
1823                                 
1824                 if (!print_job_exists(snum, jobid))
1825                         break;
1826         }
1827
1828         if (i > 2) {
1829                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
1830                                 printername ));
1831                 /* Probably full... */
1832                 errno = ENOSPC;
1833                 return False;
1834         }
1835
1836         /* Store a dummy placeholder. */
1837         {
1838                 TDB_DATA dum;
1839                 dum.dptr = NULL;
1840                 dum.dsize = 0;
1841                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
1842                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
1843                                 jobid ));
1844                         return False;
1845                 }
1846         }
1847
1848         *pjobid = jobid;
1849         return True;
1850 }
1851
1852 /***************************************************************************
1853  Append a jobid to the 'jobs changed' list.
1854 ***************************************************************************/
1855
1856 static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
1857 {
1858         TDB_DATA data, key;
1859
1860         key.dptr = "INFO/jobs_changed";
1861         key.dsize = strlen(key.dptr);
1862         data.dptr = (char *)&jobid;
1863         data.dsize = 4;
1864
1865         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
1866
1867         return (tdb_append(pdb->tdb, key, data) == 0);
1868 }
1869
1870 /***************************************************************************
1871  Start spooling a job - return the jobid.
1872 ***************************************************************************/
1873
1874 uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
1875 {
1876         uint32 jobid;
1877         char *path;
1878         struct printjob pjob;
1879         user_struct *vuser;
1880         const char *printername = lp_const_servicename(snum);
1881         struct tdb_print_db *pdb = get_print_db_byname(printername);
1882         int njobs;
1883
1884         errno = 0;
1885
1886         if (!pdb)
1887                 return (uint32)-1;
1888
1889         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
1890                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
1891                 release_print_db(pdb);
1892                 return (uint32)-1;
1893         }
1894
1895         if (!print_time_access_check(snum)) {
1896                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
1897                 release_print_db(pdb);
1898                 return (uint32)-1;
1899         }
1900
1901         path = lp_pathname(snum);
1902
1903         /* see if we have sufficient disk space */
1904         if (lp_minprintspace(snum)) {
1905                 SMB_BIG_UINT dspace, dsize;
1906                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
1907                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
1908                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
1909                         release_print_db(pdb);
1910                         errno = ENOSPC;
1911                         return (uint32)-1;
1912                 }
1913         }
1914
1915         /* for autoloaded printers, check that the printcap entry still exists */
1916         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
1917                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
1918                 release_print_db(pdb);
1919                 errno = ENOENT;
1920                 return (uint32)-1;
1921         }
1922
1923         /* Insure the maximum queue size is not violated */
1924         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
1925                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
1926                         printername, njobs, lp_maxprintjobs(snum) ));
1927                 release_print_db(pdb);
1928                 errno = ENOSPC;
1929                 return (uint32)-1;
1930         }
1931
1932         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
1933                         printername, njobs, lp_maxprintjobs(snum) ));
1934
1935         if (!allocate_print_jobid(pdb, snum, printername, &jobid))
1936                 goto fail;
1937
1938         /* create the database entry */
1939         
1940         ZERO_STRUCT(pjob);
1941         
1942         pjob.pid = local_pid;
1943         pjob.sysjob = -1;
1944         pjob.fd = -1;
1945         pjob.starttime = time(NULL);
1946         pjob.status = LPQ_SPOOLING;
1947         pjob.size = 0;
1948         pjob.spooled = False;
1949         pjob.smbjob = True;
1950         pjob.nt_devmode = nt_devmode;
1951         
1952         fstrcpy(pjob.jobname, jobname);
1953
1954         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1955                 fstrcpy(pjob.user, vuser->user.smb_name);
1956         } else {
1957                 fstrcpy(pjob.user, uidtoname(user->uid));
1958         }
1959
1960         fstrcpy(pjob.queuename, lp_const_servicename(snum));
1961
1962         /* we have a job entry - now create the spool file */
1963         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
1964                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
1965         pjob.fd = smb_mkstemp(pjob.filename);
1966
1967         if (pjob.fd == -1) {
1968                 if (errno == EACCES) {
1969                         /* Common setup error, force a report. */
1970                         DEBUG(0, ("print_job_start: insufficient permissions \
1971 to open spool file %s.\n", pjob.filename));
1972                 } else {
1973                         /* Normal case, report at level 3 and above. */
1974                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
1975                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
1976                 }
1977                 goto fail;
1978         }
1979
1980         pjob_store(snum, jobid, &pjob);
1981
1982         /* Update the 'jobs changed' entry used by print_queue_status. */
1983         add_to_jobs_changed(pdb, jobid);
1984
1985         /* Ensure we keep a rough count of the number of total jobs... */
1986         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
1987
1988         release_print_db(pdb);
1989
1990         return jobid;
1991
1992  fail:
1993         if (jobid != -1)
1994                 pjob_delete(snum, jobid);
1995
1996         release_print_db(pdb);
1997
1998         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
1999         return (uint32)-1;
2000 }
2001
2002 /****************************************************************************
2003  Update the number of pages spooled to jobid
2004 ****************************************************************************/
2005
2006 void print_job_endpage(int snum, uint32 jobid)
2007 {
2008         struct printjob *pjob = print_job_find(snum, jobid);
2009         if (!pjob)
2010                 return;
2011         /* don't allow another process to get this info - it is meaningless */
2012         if (pjob->pid != local_pid)
2013                 return;
2014
2015         pjob->page_count++;
2016         pjob_store(snum, jobid, pjob);
2017 }
2018
2019 /****************************************************************************
2020  Print a file - called on closing the file. This spools the job.
2021  If normal close is false then we're tearing down the jobs - treat as an
2022  error.
2023 ****************************************************************************/
2024
2025 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2026 {
2027         struct printjob *pjob = print_job_find(snum, jobid);
2028         int ret;
2029         SMB_STRUCT_STAT sbuf;
2030
2031         if (!pjob)
2032                 return False;
2033
2034         if (pjob->spooled || pjob->pid != local_pid)
2035                 return False;
2036
2037         if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2038                 pjob->size = sbuf.st_size;
2039                 close(pjob->fd);
2040                 pjob->fd = -1;
2041         } else {
2042
2043                 /* 
2044                  * Not a normal close or we couldn't stat the job file,
2045                  * so something has gone wrong. Cleanup.
2046                  */
2047                 close(pjob->fd);
2048                 pjob->fd = -1;
2049                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2050                 goto fail;
2051         }
2052
2053         /* Technically, this is not quite right. If the printer has a separator
2054          * page turned on, the NT spooler prints the separator page even if the
2055          * print job is 0 bytes. 010215 JRR */
2056         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2057                 /* don't bother spooling empty files or something being deleted. */
2058                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2059                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2060                 unlink(pjob->filename);
2061                 pjob_delete(snum, jobid);
2062                 return True;
2063         }
2064
2065         ret = (*(current_printif->job_submit))(snum, pjob);
2066
2067         if (ret)
2068                 goto fail;
2069
2070         /* The print job has been sucessfully handed over to the back-end */
2071         
2072         pjob->spooled = True;
2073         pjob->status = LPQ_QUEUED;
2074         pjob_store(snum, jobid, pjob);
2075         
2076         /* make sure the database is up to date */
2077         if (print_cache_expired(snum))
2078                 print_queue_update(snum);
2079         
2080         return True;
2081
2082 fail:
2083
2084         /* The print job was not succesfully started. Cleanup */
2085         /* Still need to add proper error return propagation! 010122:JRR */
2086         unlink(pjob->filename);
2087         pjob_delete(snum, jobid);
2088         remove_from_jobs_changed(snum, jobid);
2089         return False;
2090 }
2091
2092 /****************************************************************************
2093  Get a snapshot of jobs in the system without traversing.
2094 ****************************************************************************/
2095
2096 static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2097 {
2098         TDB_DATA data, key, cgdata;
2099         print_queue_struct *queue = NULL;
2100         uint32 qcount = 0;
2101         uint32 extra_count = 0;
2102         int total_count = 0;
2103         size_t len = 0;
2104         uint32 i;
2105         int max_reported_jobs = lp_max_reported_jobs(snum);
2106         BOOL ret = False;
2107
2108         /* make sure the database is up to date */
2109         if (print_cache_expired(snum))
2110                 print_queue_update(snum);
2111  
2112         *pcount = 0;
2113         *ppqueue = NULL;
2114
2115         ZERO_STRUCT(data);
2116         ZERO_STRUCT(cgdata);
2117         key.dptr = "INFO/linear_queue_array";
2118         key.dsize = strlen(key.dptr);
2119
2120         /* Get the stored queue data. */
2121         data = tdb_fetch(pdb->tdb, key);
2122
2123         if (data.dptr == NULL || data.dsize < 4)
2124                 qcount = 0;
2125         else
2126                 memcpy(&qcount, data.dptr, 4);
2127
2128         /* Get the changed jobs list. */
2129         key.dptr = "INFO/jobs_changed";
2130         key.dsize = strlen(key.dptr);
2131
2132         cgdata = tdb_fetch(pdb->tdb, key);
2133         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2134                 extra_count = cgdata.dsize/4;
2135
2136         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2137
2138         /* Allocate the queue size. */
2139         if (qcount == 0 && extra_count == 0)
2140                 goto out;
2141
2142         if ((queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(qcount + extra_count))) == NULL)
2143                 goto out;
2144
2145         /* Retrieve the linearised queue data. */
2146         len = 0;
2147         for( i  = 0; i < qcount; i++) {
2148                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2149                 len += tdb_unpack(data.dptr + 4 + len, data.dsize - len, NULL, "ddddddff",
2150                                 &qjob,
2151                                 &qsize,
2152                                 &qpage_count,
2153                                 &qstatus,
2154                                 &qpriority,
2155                                 &qtime,
2156                                 queue[i].fs_user,
2157                                 queue[i].fs_file);
2158                 queue[i].job = qjob;
2159                 queue[i].size = qsize;
2160                 queue[i].page_count = qpage_count;
2161                 queue[i].status = qstatus;
2162                 queue[i].priority = qpriority;
2163                 queue[i].time = qtime;
2164         }
2165
2166         total_count = qcount;
2167
2168         /* Add in the changed jobids. */
2169         for( i  = 0; i < extra_count; i++) {
2170                 uint32 jobid;
2171                 struct printjob *pjob;
2172
2173                 memcpy(&jobid, &cgdata.dptr[i*4], 4);
2174                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2175                 pjob = print_job_find(snum, jobid);
2176                 if (!pjob) {
2177                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2178                         remove_from_jobs_changed(snum, jobid);
2179                         continue;
2180                 }
2181
2182                 queue[total_count].job = jobid;
2183                 queue[total_count].size = pjob->size;
2184                 queue[total_count].page_count = pjob->page_count;
2185                 queue[total_count].status = pjob->status;
2186                 queue[total_count].priority = 1;
2187                 fstrcpy(queue[total_count].fs_user, pjob->user);
2188                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2189                 total_count++;
2190         }
2191
2192         /* Sort the queue by submission time otherwise they are displayed
2193            in hash order. */
2194
2195         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2196
2197         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2198
2199         if (max_reported_jobs && total_count > max_reported_jobs)
2200                 total_count = max_reported_jobs;
2201
2202         *ppqueue = queue;
2203         *pcount = total_count;
2204
2205         ret = True;
2206
2207   out:
2208
2209         SAFE_FREE(data.dptr);
2210         SAFE_FREE(cgdata.dptr);
2211         return ret;
2212 }
2213
2214 /****************************************************************************
2215  Get a printer queue listing.
2216  set queue = NULL and status = NULL if you just want to update the cache
2217 ****************************************************************************/
2218
2219 int print_queue_status(int snum, 
2220                        print_queue_struct **ppqueue,
2221                        print_status_struct *status)
2222 {
2223         fstring keystr;
2224         TDB_DATA data, key;
2225         const char *printername;
2226         struct tdb_print_db *pdb;
2227         int count = 0;
2228
2229         /* make sure the database is up to date */
2230
2231         if (print_cache_expired(snum))
2232                 print_queue_update(snum);
2233
2234         /* return if we are done */
2235         if ( !ppqueue || !status )
2236                 return 0;
2237
2238         *ppqueue = NULL;
2239         printername = lp_const_servicename(snum);
2240         pdb = get_print_db_byname(printername);
2241
2242         if (!pdb)
2243                 return 0;
2244
2245         /*
2246          * Fetch the queue status.  We must do this first, as there may
2247          * be no jobs in the queue.
2248          */
2249
2250         ZERO_STRUCTP(status);
2251         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
2252         key.dptr = keystr;
2253         key.dsize = strlen(keystr);
2254         data = tdb_fetch(pdb->tdb, key);
2255         if (data.dptr) {
2256                 if (data.dsize == sizeof(*status)) {
2257                         memcpy(status, data.dptr, sizeof(*status));
2258                 }
2259                 SAFE_FREE(data.dptr);
2260         }
2261
2262         /*
2263          * Now, fetch the print queue information.  We first count the number
2264          * of entries, and then only retrieve the queue if necessary.
2265          */
2266
2267         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2268                 release_print_db(pdb);
2269                 return 0;
2270         }
2271
2272         release_print_db(pdb);
2273         return count;
2274 }
2275
2276 /****************************************************************************
2277  Pause a queue.
2278 ****************************************************************************/
2279
2280 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2281 {
2282         int ret;
2283         
2284         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2285                 *errcode = WERR_ACCESS_DENIED;
2286                 return False;
2287         }
2288
2289         ret = (*(current_printif->queue_pause))(snum);
2290
2291         if (ret != 0) {
2292                 *errcode = WERR_INVALID_PARAM;
2293                 return False;
2294         }
2295
2296         /* force update the database */
2297         print_cache_flush(snum);
2298
2299         /* Send a printer notify message */
2300
2301         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2302
2303         return True;
2304 }
2305
2306 /****************************************************************************
2307  Resume a queue.
2308 ****************************************************************************/
2309
2310 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2311 {
2312         int ret;
2313
2314         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2315                 *errcode = WERR_ACCESS_DENIED;
2316                 return False;
2317         }
2318
2319         ret = (*(current_printif->queue_resume))(snum);
2320
2321         if (ret != 0) {
2322                 *errcode = WERR_INVALID_PARAM;
2323                 return False;
2324         }
2325
2326         /* make sure the database is up to date */
2327         if (print_cache_expired(snum))
2328                 print_queue_update(snum);
2329
2330         /* Send a printer notify message */
2331
2332         notify_printer_status(snum, PRINTER_STATUS_OK);
2333
2334         return True;
2335 }
2336
2337 /****************************************************************************
2338  Purge a queue - implemented by deleting all jobs that we can delete.
2339 ****************************************************************************/
2340
2341 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2342 {
2343         print_queue_struct *queue;
2344         print_status_struct status;
2345         int njobs, i;
2346         BOOL can_job_admin;
2347
2348         /* Force and update so the count is accurate (i.e. not a cached count) */
2349         print_queue_update(snum);
2350         
2351         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2352         njobs = print_queue_status(snum, &queue, &status);
2353
2354         for (i=0;i<njobs;i++) {
2355                 BOOL owner = is_owner(user, snum, queue[i].job);
2356
2357                 if (owner || can_job_admin) {
2358                         print_job_delete1(snum, queue[i].job);
2359                 }
2360         }
2361
2362         SAFE_FREE(queue);
2363
2364         return True;
2365 }