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