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