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