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