Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header.
[metze/samba/wip.git] / source3 / printing / printing.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing backend routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "printing.h"
23
24 /* Current printer interface */
25 struct printif *current_printif = &generic_printif;
26
27 /* 
28    the printing backend revolves around a tdb database that stores the
29    SMB view of the print queue 
30    
31    The key for this database is a jobid - a internally generated number that
32    uniquely identifies a print job
33
34    reading the print queue involves two steps:
35      - possibly running lpq and updating the internal database from that
36      - reading entries from the database
37
38    jobids are assigned when a job starts spooling. 
39 */
40
41 /* the open printing.tdb database */
42 static TDB_CONTEXT *tdb;
43 static pid_t local_pid;
44
45 static int get_queue_status(int, print_status_struct *);
46
47 /****************************************************************************
48 initialise the printing backend. Called once at startup. 
49 Does not survive a fork
50 ****************************************************************************/
51 BOOL print_backend_init(void)
52 {
53         char *sversion = "INFO/version";
54
55         if (tdb && local_pid == sys_getpid()) return True;
56         tdb = tdb_open_log(lock_path("printing.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
57         if (!tdb) {
58                 DEBUG(0,("print_backend_init: Failed to open printing backend database. Error = [%s]\n",
59                                  tdb_errorstr(tdb)));
60                 return False;
61         }
62         local_pid = sys_getpid();
63
64         /* handle a Samba upgrade */
65         tdb_lock_bystring(tdb, sversion);
66         if (tdb_fetch_int(tdb, sversion) != PRINT_DATABASE_VERSION) {
67                 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
68                 tdb_store_int(tdb, sversion, PRINT_DATABASE_VERSION);
69         }
70         tdb_unlock_bystring(tdb, sversion);
71
72         /* select the appropriate printing interface... */
73 #ifdef HAVE_CUPS
74         if (strcmp(lp_printcapname(), "cups") == 0)
75                 current_printif = &cups_printif;
76 #endif /* HAVE_CUPS */
77
78         /* do NT print initialization... */
79         return nt_printing_init();
80 }
81
82 /****************************************************************************
83 useful function to generate a tdb key
84 ****************************************************************************/
85 static TDB_DATA print_key(int jobid)
86 {
87         static int j;
88         TDB_DATA ret;
89
90         j = jobid;
91         ret.dptr = (void *)&j;
92         ret.dsize = sizeof(j);
93         return ret;
94 }
95
96 /****************************************************************************
97 useful function to find a print job in the database
98 ****************************************************************************/
99 static struct printjob *print_job_find(int jobid)
100 {
101         static struct printjob pjob;
102         TDB_DATA ret;
103
104         ret = tdb_fetch(tdb, print_key(jobid));
105         if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
106
107         memcpy(&pjob, ret.dptr, sizeof(pjob));
108         free(ret.dptr);
109         return &pjob;
110 }
111
112 /****************************************************************************
113 store a job structure back to the database
114 ****************************************************************************/
115 static BOOL print_job_store(int jobid, struct printjob *pjob)
116 {
117         TDB_DATA d;
118         d.dptr = (void *)pjob;
119         d.dsize = sizeof(*pjob);
120
121         return (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0);
122 }
123
124 /****************************************************************************
125 parse a file name from the system spooler to generate a jobid
126 ****************************************************************************/
127 static int print_parse_jobid(char *fname)
128 {
129         int jobid;
130
131         if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1;
132         fname += strlen(PRINT_SPOOL_PREFIX);
133
134         jobid = atoi(fname);
135         if (jobid <= 0) return -1;
136
137         return jobid;
138 }
139
140
141 /****************************************************************************
142 list a unix job in the print database
143 ****************************************************************************/
144 static void print_unix_job(int snum, print_queue_struct *q)
145 {
146         int jobid = q->job + UNIX_JOB_START;
147         struct printjob pj, *old_pj;
148
149         /* Preserve the timestamp on an existing unix print job */
150
151         old_pj = print_job_find(jobid);
152
153         ZERO_STRUCT(pj);
154
155         pj.pid = (pid_t)-1;
156         pj.sysjob = q->job;
157         pj.fd = -1;
158         pj.starttime = old_pj ? old_pj->starttime : q->time;
159         pj.status = q->status;
160         pj.size = q->size;
161         pj.spooled = True;
162         pj.smbjob = False;
163         fstrcpy(pj.filename, "");
164         fstrcpy(pj.jobname, q->file);
165         fstrcpy(pj.user, q->user);
166         fstrcpy(pj.qname, lp_servicename(snum));
167
168         print_job_store(jobid, &pj);
169 }
170
171
172 struct traverse_struct {
173         print_queue_struct *queue;
174         int qcount, snum, maxcount, total_jobs;
175 };
176
177 /* utility fn to delete any jobs that are no longer active */
178 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
179 {
180         struct traverse_struct *ts = (struct traverse_struct *)state;
181         struct printjob pjob;
182         int i, jobid;
183
184         if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
185         memcpy(&jobid, key.dptr, sizeof(jobid));
186         memcpy(&pjob,  data.dptr, sizeof(pjob));
187
188         if (strcmp(lp_servicename(ts->snum), pjob.qname)) {
189                 /* this isn't for the queue we are looking at */
190                 ts->total_jobs++;
191                 return 0;
192         }
193
194         if (!pjob.smbjob) {
195                 /* remove a unix job if it isn't in the system queue any more */
196
197                 for (i=0;i<ts->qcount;i++) {
198                         if (jobid == ts->queue[i].job + UNIX_JOB_START) break;
199                 }
200                 if (i == ts->qcount)
201                         tdb_delete(tdb, key);
202                 else
203                         ts->total_jobs++;
204                 return 0;
205         }
206
207         /* maybe it hasn't been spooled yet */
208         if (!pjob.spooled) {
209                 /* if a job is not spooled and the process doesn't
210                    exist then kill it. This cleans up after smbd
211                    deaths */
212                 if (!process_exists(pjob.pid))
213                         tdb_delete(tdb, key);
214                 else
215                         ts->total_jobs++;
216                 return 0;
217         }
218
219         for (i=0;i<ts->qcount;i++) {
220                 int qid = print_parse_jobid(ts->queue[i].file);
221                 if (jobid == qid) break;
222         }
223         
224         /* The job isn't in the system queue - we have to assume it has
225            completed, so delete the database entry. */
226
227         if (i == ts->qcount) {
228                 time_t cur_t = time(NULL);
229
230                 /* A race can occur between the time a job is spooled and
231                    when it appears in the lpq output.  This happens when
232                    the job is added to printing.tdb when another smbd
233                    running print_queue_update() has completed a lpq and
234                    is currently traversing the printing tdb and deleting jobs.
235                    A workaround is to not delete the job if it has been 
236                    submitted less than lp_lpqcachetime() seconds ago. */
237
238                 if ((cur_t - pjob.starttime) > lp_lpqcachetime())
239                         tdb_delete(t, key);
240                 else
241                         ts->total_jobs++;
242         }
243         else
244                 ts->total_jobs++;
245
246         return 0;
247 }
248
249 /****************************************************************************
250 check if the print queue has been updated recently enough
251 ****************************************************************************/
252 static void print_cache_flush(int snum)
253 {
254         fstring key;
255         slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
256         tdb_store_int(tdb, key, -1);
257 }
258
259 /****************************************************************************
260  Check if someone already thinks they are doing the update.
261 ****************************************************************************/
262
263 static pid_t get_updating_pid(fstring printer_name)
264 {
265         fstring keystr;
266         TDB_DATA data, key;
267         pid_t updating_pid;
268
269         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
270         key.dptr = keystr;
271         key.dsize = strlen(keystr);
272
273         data = tdb_fetch(tdb, key);
274         if (!data.dptr || data.dsize != sizeof(pid_t))
275                 return (pid_t)-1;
276
277         memcpy(&updating_pid, data.dptr, sizeof(pid_t));
278         free(data.dptr);
279
280         if (process_exists(updating_pid))
281                 return updating_pid;
282
283         return (pid_t)-1;
284 }
285
286 /****************************************************************************
287  Set the fact that we're doing the update, or have finished doing the update
288  in th tdb.
289 ****************************************************************************/
290
291 static void set_updating_pid(fstring printer_name, BOOL delete)
292 {
293         fstring keystr;
294         TDB_DATA key;
295         TDB_DATA data;
296         pid_t updating_pid = getpid();
297
298         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
299         key.dptr = keystr;
300         key.dsize = strlen(keystr);
301
302         if (delete) {
303                 tdb_delete(tdb, key);
304                 return;
305         }
306         
307         data.dptr = (void *)&updating_pid;
308         data.dsize = sizeof(pid_t);
309
310         tdb_store(tdb, key, data, TDB_REPLACE); 
311 }
312
313 /****************************************************************************
314 update the internal database from the system print queue for a queue
315 ****************************************************************************/
316
317 static void print_queue_update(int snum)
318 {
319         int i, qcount;
320         print_queue_struct *queue = NULL;
321         print_status_struct status;
322         print_status_struct old_status;
323         struct printjob *pjob;
324         struct traverse_struct tstruct;
325         fstring keystr, printer_name, cachestr;
326         TDB_DATA data, key;
327
328         fstrcpy(printer_name, lp_servicename(snum));
329         
330         /*
331          * Check to see if someone else is doing this update.
332          * This is essentially a mutex on the update.
333          */
334
335         if (get_updating_pid(printer_name) != -1)
336                 return;
337
338         /* Lock the queue for the database update */
339
340         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
341         tdb_lock_bystring(tdb, keystr);
342
343         /*
344          * Ensure that no one else got in here.
345          * If the updating pid is still -1 then we are
346          * the winner.
347          */
348
349         if (get_updating_pid(printer_name) != -1) {
350                 /*
351                  * Someone else is doing the update, exit.
352                  */
353                 tdb_unlock_bystring(tdb, keystr);
354                 return;
355         }
356
357         /*
358          * We're going to do the update ourselves.
359          */
360
361         /* Tell others we're doing the update. */
362         set_updating_pid(printer_name, False);
363
364         /*
365          * Allow others to enter and notice we're doing
366          * the update.
367          */
368
369         tdb_unlock_bystring(tdb, keystr);
370
371         /*
372          * Update the cache time FIRST ! Stops others even
373          * attempting to get the lock and doing this
374          * if the lpq takes a long time.
375          */
376
377         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
378         tdb_store_int(tdb, cachestr, (int)time(NULL));
379
380         /* get the current queue using the appropriate interface */
381         ZERO_STRUCT(status);
382
383         qcount = (*(current_printif->queue_get))(snum, &queue, &status);
384
385         DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
386                 "s" : "", printer_name));
387
388         /*
389           any job in the internal database that is marked as spooled
390           and doesn't exist in the system queue is considered finished
391           and removed from the database
392
393           any job in the system database but not in the internal database 
394           is added as a unix job
395
396           fill in any system job numbers as we go
397         */
398         for (i=0; i<qcount; i++) {
399                 int jobid = print_parse_jobid(queue[i].file);
400
401                 if (jobid == -1) {
402                         /* assume its a unix print job */
403                         print_unix_job(snum, &queue[i]);
404                         continue;
405                 }
406
407                 /* we have an active SMB print job - update its status */
408                 pjob = print_job_find(jobid);
409                 if (!pjob) {
410                         /* err, somethings wrong. Probably smbd was restarted
411                            with jobs in the queue. All we can do is treat them
412                            like unix jobs. Pity. */
413                         print_unix_job(snum, &queue[i]);
414                         continue;
415                 }
416
417                 pjob->sysjob = queue[i].job;
418                 pjob->status = queue[i].status;
419
420                 print_job_store(jobid, pjob);
421         }
422
423         /* now delete any queued entries that don't appear in the
424            system queue */
425         tstruct.queue = queue;
426         tstruct.qcount = qcount;
427         tstruct.snum = snum;
428         tstruct.total_jobs = 0;
429
430         tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
431
432         safe_free(tstruct.queue);
433
434         tdb_store_int(tdb, "INFO/total_jobs", tstruct.total_jobs);
435
436         /*
437          * Get the old print status. We will use this to compare the
438          * number of jobs. If they have changed we need to send a
439          * "changed" message to the smbds.
440          */
441
442         if( qcount != get_queue_status(snum, &old_status)) {
443                 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
444                                 old_status.qcount, qcount, printer_name ));
445                 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
446         }
447
448         /* store the new queue status structure */
449         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
450         key.dptr = keystr;
451         key.dsize = strlen(keystr);
452
453         status.qcount = qcount;
454         data.dptr = (void *)&status;
455         data.dsize = sizeof(status);
456         tdb_store(tdb, key, data, TDB_REPLACE); 
457
458         /*
459          * Update the cache time again. We want to do this call
460          * as little as possible...
461          */
462
463         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
464         tdb_store_int(tdb, keystr, (int)time(NULL));
465
466         /* Delete our pid from the db. */
467         set_updating_pid(printer_name, True);
468 }
469
470 /****************************************************************************
471 check if a jobid is valid. It is valid if it exists in the database
472 ****************************************************************************/
473 BOOL print_job_exists(int jobid)
474 {
475         return tdb_exists(tdb, print_key(jobid));
476 }
477
478
479 /****************************************************************************
480 work out which service a jobid is for
481 note that we have to look up by queue name to ensure that it works for 
482 other than the process that started the job
483 ****************************************************************************/
484 int print_job_snum(int jobid)
485 {
486         struct printjob *pjob = print_job_find(jobid);
487         if (!pjob) return -1;
488
489         return lp_servicenumber(pjob->qname);
490 }
491
492 /****************************************************************************
493 give the fd used for a jobid
494 ****************************************************************************/
495 int print_job_fd(int jobid)
496 {
497         struct printjob *pjob = print_job_find(jobid);
498         if (!pjob) return -1;
499         /* don't allow another process to get this info - it is meaningless */
500         if (pjob->pid != local_pid) return -1;
501         return pjob->fd;
502 }
503
504 /****************************************************************************
505 give the filename used for a jobid
506 only valid for the process doing the spooling and when the job
507 has not been spooled
508 ****************************************************************************/
509 char *print_job_fname(int jobid)
510 {
511         struct printjob *pjob = print_job_find(jobid);
512         if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL;
513         return pjob->filename;
514 }
515
516
517 /****************************************************************************
518 set the place in the queue for a job
519 ****************************************************************************/
520 BOOL print_job_set_place(int jobid, int place)
521 {
522         DEBUG(2,("print_job_set_place not implemented yet\n"));
523         return False;
524 }
525
526 /****************************************************************************
527 set the name of a job. Only possible for owner
528 ****************************************************************************/
529 BOOL print_job_set_name(int jobid, char *name)
530 {
531         struct printjob *pjob = print_job_find(jobid);
532         if (!pjob || pjob->pid != local_pid) return False;
533
534         fstrcpy(pjob->jobname, name);
535         return print_job_store(jobid, pjob);
536 }
537
538
539 /****************************************************************************
540 delete a print job - don't update queue
541 ****************************************************************************/
542 static BOOL print_job_delete1(int jobid)
543 {
544         struct printjob *pjob = print_job_find(jobid);
545         int snum, result = 0;
546
547         if (!pjob) return False;
548
549         /*
550          * If already deleting just return.
551          */
552
553         if (pjob->status == LPQ_DELETING)
554                 return True;
555
556         snum = print_job_snum(jobid);
557
558         /* Hrm - we need to be able to cope with deleting a job before it
559            has reached the spooler. */
560
561         if (pjob->sysjob == -1) {
562                 DEBUG(5, ("attempt to delete job %d not seen by lpr\n",
563                           jobid));
564         }
565
566         /* Set the tdb entry to be deleting. */
567
568         pjob->status = LPQ_DELETING;
569         print_job_store(jobid, pjob);
570
571         if (pjob->spooled && pjob->sysjob != -1)
572                 result = (*(current_printif->job_delete))(snum, pjob);
573
574         /* Delete the tdb entry if the delete suceeded or the job hasn't
575            been spooled. */
576
577         if (result == 0) {
578                 tdb_delete(tdb, print_key(jobid));
579         }
580
581         return (result == 0);
582 }
583
584 /****************************************************************************
585 return true if the current user owns the print job
586 ****************************************************************************/
587 static BOOL is_owner(struct current_user *user, int jobid)
588 {
589         struct printjob *pjob = print_job_find(jobid);
590         user_struct *vuser;
591
592         if (!pjob || !user) return False;
593
594         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
595                 return strequal(pjob->user, vuser->user.smb_name);
596         } else {
597                 return strequal(pjob->user, uidtoname(user->uid));
598         }
599 }
600
601 /****************************************************************************
602 delete a print job
603 ****************************************************************************/
604 BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode)
605 {
606         int snum = print_job_snum(jobid);
607         char *printer_name;
608         BOOL owner;
609         
610         owner = is_owner(user, jobid);
611         
612         /* Check access against security descriptor or whether the user
613            owns their job. */
614
615         if (!owner && 
616             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
617                 DEBUG(3, ("delete denied by security descriptor\n"));
618                 *errcode = WERR_ACCESS_DENIED;
619                 return False;
620         }
621
622         if (!print_job_delete1(jobid)) return False;
623
624         /* force update the database and say the delete failed if the
625            job still exists */
626
627         print_queue_update(snum);
628
629         /* Send a printer notify message */
630
631         printer_name = PRINTERNAME(snum);
632
633         message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
634
635         return !print_job_exists(jobid);
636 }
637
638
639 /****************************************************************************
640 pause a job
641 ****************************************************************************/
642 BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode)
643 {
644         struct printjob *pjob = print_job_find(jobid);
645         int snum, ret = -1;
646         char *printer_name;
647         
648         if (!pjob || !user) return False;
649
650         if (!pjob->spooled || pjob->sysjob == -1) return False;
651
652         snum = print_job_snum(jobid);
653
654         if (!is_owner(user, jobid) &&
655             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
656                 DEBUG(3, ("pause denied by security descriptor\n"));
657                 *errcode = WERR_ACCESS_DENIED;
658                 return False;
659         }
660
661         /* need to pause the spooled entry */
662         ret = (*(current_printif->job_pause))(snum, pjob);
663
664         if (ret != 0) {
665                 *errcode = WERR_INVALID_PARAM;
666                 return False;
667         }
668
669         /* force update the database */
670         print_cache_flush(snum);
671
672         /* Send a printer notify message */
673
674         printer_name = PRINTERNAME(snum);
675
676         message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
677
678         /* how do we tell if this succeeded? */
679
680         return True;
681 }
682
683 /****************************************************************************
684 resume a job
685 ****************************************************************************/
686 BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode)
687 {
688         struct printjob *pjob = print_job_find(jobid);
689         char *printer_name;
690         int snum, ret;
691         
692         if (!pjob || !user) return False;
693
694         if (!pjob->spooled || pjob->sysjob == -1) return False;
695
696         snum = print_job_snum(jobid);
697
698         if (!is_owner(user, jobid) &&
699             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
700                 DEBUG(3, ("resume denied by security descriptor\n"));
701                 *errcode = WERR_ACCESS_DENIED;
702                 return False;
703         }
704
705         ret = (*(current_printif->job_resume))(snum, pjob);
706
707         if (ret != 0) {
708                 *errcode = WERR_INVALID_PARAM;
709                 return False;
710         }
711
712         /* force update the database */
713         print_cache_flush(snum);
714
715         /* Send a printer notify message */
716
717         printer_name = PRINTERNAME(snum);
718
719         message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
720
721         return True;
722 }
723
724 /****************************************************************************
725 write to a print file
726 ****************************************************************************/
727 int print_job_write(int jobid, const char *buf, int size)
728 {
729         int fd;
730
731         fd = print_job_fd(jobid);
732         if (fd == -1) return -1;
733
734         return write(fd, buf, size);
735 }
736
737 /****************************************************************************
738  Check if the print queue has been updated recently enough.
739 ****************************************************************************/
740
741 static BOOL print_cache_expired(int snum)
742 {
743         fstring key;
744         time_t t2, t = time(NULL);
745
746         slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
747         t2 = tdb_fetch_int(tdb, key);
748         if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) {
749                 DEBUG(3, ("print cache expired\n"));
750                 return True;
751         }
752         return False;
753 }
754
755 /****************************************************************************
756  Get the queue status - do not update if db is out of date.
757 ****************************************************************************/
758 static int get_queue_status(int snum, print_status_struct *status)
759 {
760         fstring keystr;
761         TDB_DATA data, key;
762
763         ZERO_STRUCTP(status);
764         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
765         key.dptr = keystr;
766         key.dsize = strlen(keystr);
767         data = tdb_fetch(tdb, key);
768         if (data.dptr) {
769                 if (data.dsize == sizeof(print_status_struct)) {
770                         memcpy(status, data.dptr, sizeof(print_status_struct));
771                 }
772                 free(data.dptr);
773         }
774         return status->qcount;
775 }
776
777 /****************************************************************************
778  Determine the number of jobs in a queue.
779 ****************************************************************************/
780 static int print_queue_length(int snum)
781 {
782         print_status_struct status;
783
784         /* make sure the database is up to date */
785         if (print_cache_expired(snum)) print_queue_update(snum);
786
787         /* also fetch the queue status */
788         return get_queue_status(snum, &status);
789 }
790
791 /****************************************************************************
792  Determine the number of jobs in all queues.
793 ****************************************************************************/
794 static int get_total_jobs(int snum)
795 {
796         int total_jobs;
797
798         /* make sure the database is up to date */
799         if (print_cache_expired(snum)) print_queue_update(snum);
800
801         total_jobs = tdb_fetch_int(tdb, "INFO/total_jobs");
802         if (total_jobs >0)
803                 return total_jobs;
804         else
805                 return 0;
806 }
807
808 /***************************************************************************
809 start spooling a job - return the jobid
810 ***************************************************************************/
811 int print_job_start(struct current_user *user, int snum, char *jobname)
812 {
813         int jobid;
814         char *path;
815         struct printjob pjob;
816         int next_jobid;
817         user_struct *vuser;
818
819         errno = 0;
820
821         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
822                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
823                 return -1;
824         }
825
826         if (!print_time_access_check(snum)) {
827                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
828                 return -1;
829         }
830
831         path = lp_pathname(snum);
832
833         /* see if we have sufficient disk space */
834         if (lp_minprintspace(snum)) {
835                 SMB_BIG_UINT dspace, dsize;
836                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
837                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
838                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
839                         errno = ENOSPC;
840                         return -1;
841                 }
842         }
843
844         /* for autoloaded printers, check that the printcap entry still exists */
845         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
846                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_servicename(snum) ));
847                 errno = ENOENT;
848                 return -1;
849         }
850
851         /* Insure the maximum queue size is not violated */
852         if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) {
853                 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n",
854                         print_queue_length(snum), lp_maxprintjobs(snum) ));
855                 errno = ENOSPC;
856                 return -1;
857         }
858
859         /* Insure the maximum print jobs in the system is not violated */
860         if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) {
861                 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n",
862                         print_queue_length(snum), lp_totalprintjobs() ));
863                 errno = ENOSPC;
864                 return -1;
865         }
866
867         /* create the database entry */
868         ZERO_STRUCT(pjob);
869         pjob.pid = local_pid;
870         pjob.sysjob = -1;
871         pjob.fd = -1;
872         pjob.starttime = time(NULL);
873         pjob.status = LPQ_SPOOLING;
874         pjob.size = 0;
875         pjob.spooled = False;
876         pjob.smbjob = True;
877
878         fstrcpy(pjob.jobname, jobname);
879
880         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
881                 fstrcpy(pjob.user, vuser->user.smb_name);
882         } else {
883                 fstrcpy(pjob.user, uidtoname(user->uid));
884         }
885
886         fstrcpy(pjob.qname, lp_servicename(snum));
887
888         /* lock the database */
889         tdb_lock_bystring(tdb, "INFO/nextjob");
890
891         next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
892         if (next_jobid == -1)
893                 next_jobid = 1;
894
895         for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
896                 if (!print_job_exists(jobid))
897                         break;
898         }
899         if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
900                 DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or print_job_store failed.\n",
901                                 jobid, next_jobid ));
902                 jobid = -1;
903                 goto fail;
904         }
905
906         tdb_store_int(tdb, "INFO/nextjob", jobid);
907
908         /* we have a job entry - now create the spool file */
909         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX", 
910                  path, PRINT_SPOOL_PREFIX, jobid);
911         pjob.fd = smb_mkstemp(pjob.filename);
912
913         if (pjob.fd == -1) {
914                 if (errno == EACCES) {
915                         /* Common setup error, force a report. */
916                         DEBUG(0, ("print_job_start: insufficient permissions \
917 to open spool file %s.\n", pjob.filename));
918                 } else {
919                         /* Normal case, report at level 3 and above. */
920                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
921                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
922                 }
923                 goto fail;
924         }
925
926         print_job_store(jobid, &pjob);
927
928         tdb_unlock_bystring(tdb, "INFO/nextjob");
929
930         /*
931          * If the printer is marked as postscript output a leading
932          * file identifier to ensure the file is treated as a raw
933          * postscript file.
934          * This has a similar effect as CtrlD=0 in WIN.INI file.
935          * tim@fsg.com 09/06/94
936          */
937         if (lp_postscript(snum)) {
938                 print_job_write(jobid, "%!\n",3);
939         }
940
941         return jobid;
942
943  fail:
944         if (jobid != -1) {
945                 tdb_delete(tdb, print_key(jobid));
946         }
947
948         tdb_unlock_bystring(tdb, "INFO/nextjob");
949
950         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
951         return -1;
952 }
953
954 /****************************************************************************
955  Print a file - called on closing the file. This spools the job.
956  If normal close is false then we're tearing down the jobs - treat as an
957  error.
958 ****************************************************************************/
959
960 BOOL print_job_end(int jobid, BOOL normal_close)
961 {
962         struct printjob *pjob = print_job_find(jobid);
963         int snum, ret;
964         SMB_STRUCT_STAT sbuf;
965
966         if (!pjob)
967                 return False;
968
969         if (pjob->spooled || pjob->pid != local_pid)
970                 return False;
971
972         snum = print_job_snum(jobid);
973
974         if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
975                 pjob->size = sbuf.st_size;
976                 close(pjob->fd);
977                 pjob->fd = -1;
978         } else {
979
980                 /* 
981                  * Not a normal close or we couldn't stat the job file,
982                  * so something has gone wrong. Cleanup.
983                  */
984                 close(pjob->fd);
985                 pjob->fd = -1;
986                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
987                 goto fail;
988         }
989
990         /* Technically, this is not quit right. If the printer has a separator
991          * page turned on, the NT spooler prints the separator page even if the
992          * print job is 0 bytes. 010215 JRR */
993         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
994                 /* don't bother spooling empty files or something being deleted. */
995                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
996                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
997                 unlink(pjob->filename);
998                 tdb_delete(tdb, print_key(jobid));
999                 return True;
1000         }
1001
1002         ret = (*(current_printif->job_submit))(snum, pjob);
1003
1004         if (ret)
1005                 goto fail;
1006
1007         /* The print job has been sucessfully handed over to the back-end */
1008         
1009         pjob->spooled = True;
1010         pjob->status = LPQ_QUEUED;
1011         print_job_store(jobid, pjob);
1012         
1013         /* make sure the database is up to date */
1014         if (print_cache_expired(snum))
1015                 print_queue_update(snum);
1016         
1017         return True;
1018
1019 fail:
1020
1021         /* The print job was not succesfully started. Cleanup */
1022         /* Still need to add proper error return propagation! 010122:JRR */
1023         unlink(pjob->filename);
1024         tdb_delete(tdb, print_key(jobid));
1025         return False;
1026 }
1027
1028 /* utility fn to enumerate the print queue */
1029 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1030 {
1031         struct traverse_struct *ts = (struct traverse_struct *)state;
1032         struct printjob pjob;
1033         int i, jobid;
1034
1035         if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1036         memcpy(&jobid, key.dptr, sizeof(jobid));
1037         memcpy(&pjob,  data.dptr, sizeof(pjob));
1038
1039         /* maybe it isn't for this queue */
1040         if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1041
1042         if (ts->qcount >= ts->maxcount) return 0;
1043
1044         i = ts->qcount;
1045
1046         ts->queue[i].job = jobid;
1047         ts->queue[i].size = pjob.size;
1048         ts->queue[i].status = pjob.status;
1049         ts->queue[i].priority = 1;
1050         ts->queue[i].time = pjob.starttime;
1051         fstrcpy(ts->queue[i].user, pjob.user);
1052         fstrcpy(ts->queue[i].file, pjob.jobname);
1053
1054         ts->qcount++;
1055
1056         return 0;
1057 }
1058
1059 struct traverse_count_struct {
1060         int snum, count;
1061 };
1062
1063 /* utility fn to count the number of entries in the print queue */
1064 static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1065 {
1066         struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
1067         struct printjob pjob;
1068         int jobid;
1069
1070         if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1071         memcpy(&jobid, key.dptr, sizeof(jobid));
1072         memcpy(&pjob,  data.dptr, sizeof(pjob));
1073
1074         /* maybe it isn't for this queue */
1075         if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1076
1077         ts->count++;
1078
1079         return 0;
1080 }
1081
1082 /* Sort print jobs by submittal time */
1083
1084 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1085 {
1086         /* Silly cases */
1087
1088         if (!j1 && !j2) return 0;
1089         if (!j1) return -1;
1090         if (!j2) return 1;
1091
1092         /* Sort on job start time */
1093
1094         if (j1->time == j2->time) return 0;
1095         return (j1->time > j2->time) ? 1 : -1;
1096 }
1097
1098 /****************************************************************************
1099 get a printer queue listing
1100 ****************************************************************************/
1101 int print_queue_status(int snum, 
1102                        print_queue_struct **queue,
1103                        print_status_struct *status)
1104 {
1105         struct traverse_struct tstruct;
1106         struct traverse_count_struct tsc;
1107         fstring keystr;
1108         TDB_DATA data, key;
1109
1110         /* make sure the database is up to date */
1111         if (print_cache_expired(snum)) print_queue_update(snum);
1112
1113         *queue = NULL;
1114         
1115         /*
1116          * Fetch the queue status.  We must do this first, as there may
1117          * be no jobs in the queue.
1118          */
1119         ZERO_STRUCTP(status);
1120         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
1121         key.dptr = keystr;
1122         key.dsize = strlen(keystr);
1123         data = tdb_fetch(tdb, key);
1124         if (data.dptr) {
1125                 if (data.dsize == sizeof(*status)) {
1126                         memcpy(status, data.dptr, sizeof(*status));
1127                 }
1128                 free(data.dptr);
1129         }
1130
1131         /*
1132          * Now, fetch the print queue information.  We first count the number
1133          * of entries, and then only retrieve the queue if necessary.
1134          */
1135         tsc.count = 0;
1136         tsc.snum = snum;
1137         
1138         tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc);
1139
1140         if (tsc.count == 0)
1141                 return 0;
1142
1143         /* Allocate the queue size. */
1144         if ((tstruct.queue = (print_queue_struct *)
1145              malloc(sizeof(print_queue_struct)*tsc.count))
1146                                 == NULL)
1147                 return 0;
1148
1149         /*
1150          * Fill in the queue.
1151          * We need maxcount as the queue size may have changed between
1152          * the two calls to tdb_traverse.
1153          */
1154         tstruct.qcount = 0;
1155         tstruct.maxcount = tsc.count;
1156         tstruct.snum = snum;
1157
1158         tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
1159
1160         /* Sort the queue by submission time otherwise they are displayed
1161            in hash order. */
1162
1163         qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
1164               QSORT_CAST(printjob_comp));
1165
1166         *queue = tstruct.queue;
1167         return tstruct.qcount;
1168 }
1169
1170
1171 /****************************************************************************
1172 turn a queue name into a snum
1173 ****************************************************************************/
1174 int print_queue_snum(char *qname)
1175 {
1176         int snum = lp_servicenumber(qname);
1177         if (snum == -1 || !lp_print_ok(snum)) return -1;
1178         return snum;
1179 }
1180
1181
1182 /****************************************************************************
1183  pause a queue
1184 ****************************************************************************/
1185 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
1186 {
1187         char *printer_name;
1188         int ret;
1189         
1190         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1191                 *errcode = WERR_ACCESS_DENIED;
1192                 return False;
1193         }
1194
1195         ret = (*(current_printif->queue_pause))(snum);
1196
1197         if (ret != 0) {
1198                 *errcode = WERR_INVALID_PARAM;
1199                 return False;
1200         }
1201
1202         /* force update the database */
1203         print_cache_flush(snum);
1204
1205         /* Send a printer notify message */
1206
1207         printer_name = PRINTERNAME(snum);
1208
1209         message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1210
1211         return True;
1212 }
1213
1214 /****************************************************************************
1215  resume a queue
1216 ****************************************************************************/
1217 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
1218 {
1219         char *printer_name;
1220         int ret;
1221
1222         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1223                 *errcode = WERR_ACCESS_DENIED;
1224                 return False;
1225         }
1226
1227         ret = (*(current_printif->queue_resume))(snum);
1228
1229         if (ret != 0) {
1230                 *errcode = WERR_INVALID_PARAM;
1231                 return False;
1232         }
1233
1234         /* make sure the database is up to date */
1235         if (print_cache_expired(snum)) print_queue_update(snum);
1236
1237         /* Send a printer notify message */
1238
1239         printer_name = PRINTERNAME(snum);
1240
1241         message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1242
1243         return True;
1244 }
1245
1246 /****************************************************************************
1247  purge a queue - implemented by deleting all jobs that we can delete
1248 ****************************************************************************/
1249 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
1250 {
1251         print_queue_struct *queue;
1252         print_status_struct status;
1253         char *printer_name;
1254         int njobs, i;
1255         BOOL can_job_admin;
1256
1257         /* Force and update so the count is accurate (i.e. not a cached count) */
1258         print_queue_update(snum);
1259         
1260         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
1261         njobs = print_queue_status(snum, &queue, &status);
1262
1263         for (i=0;i<njobs;i++) {
1264                 BOOL owner = is_owner(user, queue[i].job);
1265
1266                 if (owner || can_job_admin) {
1267                         print_job_delete1(queue[i].job);
1268                 }
1269         }
1270
1271         safe_free(queue);
1272
1273         /* Send a printer notify message */
1274
1275         printer_name = PRINTERNAME(snum);
1276
1277         message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1278
1279         return True;
1280 }