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