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