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