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