Removed version number from file header.
[Samba/ekacnet.git] / source / printing / printing.c
blob10466cd5f22bbc865676ab82c6e9d48d844623a7
1 /*
2 Unix SMB/CIFS implementation.
3 printing backend routines
4 Copyright (C) Andrew Tridgell 1992-2000
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "printing.h"
23 /* Current printer interface */
24 struct printif *current_printif = &generic_printif;
26 /*
27 the printing backend revolves around a tdb database that stores the
28 SMB view of the print queue
30 The key for this database is a jobid - a internally generated number that
31 uniquely identifies a print job
33 reading the print queue involves two steps:
34 - possibly running lpq and updating the internal database from that
35 - reading entries from the database
37 jobids are assigned when a job starts spooling.
40 /* the open printing.tdb database */
41 static TDB_CONTEXT *tdb;
42 static pid_t local_pid;
44 static int get_queue_status(int, print_status_struct *);
46 /****************************************************************************
47 Initialise the printing backend. Called once at startup.
48 Does not survive a fork
49 ****************************************************************************/
51 BOOL print_backend_init(void)
53 char *sversion = "INFO/version";
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;
62 local_pid = sys_getpid();
64 /* handle a Samba upgrade */
65 tdb_lock_bystring(tdb, sversion);
66 if (tdb_fetch_int32(tdb, sversion) != PRINT_DATABASE_VERSION) {
67 tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
68 tdb_store_int32(tdb, sversion, PRINT_DATABASE_VERSION);
70 tdb_unlock_bystring(tdb, sversion);
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 */
78 /* do NT print initialization... */
79 return nt_printing_init();
82 /****************************************************************************
83 useful function to generate a tdb key
84 ****************************************************************************/
85 static TDB_DATA print_key(int jobid)
87 static int j;
88 TDB_DATA ret;
90 j = jobid;
91 ret.dptr = (void *)&j;
92 ret.dsize = sizeof(j);
93 return ret;
96 /****************************************************************************
97 useful function to find a print job in the database
98 ****************************************************************************/
99 static struct printjob *print_job_find(int jobid)
101 static struct printjob pjob;
102 TDB_DATA ret;
104 ret = tdb_fetch(tdb, print_key(jobid));
105 if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
107 memcpy(&pjob, ret.dptr, sizeof(pjob));
108 free(ret.dptr);
109 return &pjob;
112 /****************************************************************************
113 store a job structure back to the database
114 ****************************************************************************/
115 static BOOL print_job_store(int jobid, struct printjob *pjob)
117 TDB_DATA d;
118 d.dptr = (void *)pjob;
119 d.dsize = sizeof(*pjob);
121 return (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0);
124 /****************************************************************************
125 parse a file name from the system spooler to generate a jobid
126 ****************************************************************************/
127 static int print_parse_jobid(char *fname)
129 int jobid;
131 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1;
132 fname += strlen(PRINT_SPOOL_PREFIX);
134 jobid = atoi(fname);
135 if (jobid <= 0) return -1;
137 return jobid;
141 /****************************************************************************
142 list a unix job in the print database
143 ****************************************************************************/
144 static void print_unix_job(int snum, print_queue_struct *q)
146 int jobid = q->job + UNIX_JOB_START;
147 struct printjob pj, *old_pj;
149 /* Preserve the timestamp on an existing unix print job */
151 old_pj = print_job_find(jobid);
153 ZERO_STRUCT(pj);
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));
168 print_job_store(jobid, &pj);
172 struct traverse_struct {
173 print_queue_struct *queue;
174 int qcount, snum, maxcount, total_jobs;
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)
180 struct traverse_struct *ts = (struct traverse_struct *)state;
181 struct printjob pjob;
182 int i, jobid;
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));
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;
194 if (!pjob.smbjob) {
195 /* remove a unix job if it isn't in the system queue any more */
197 for (i=0;i<ts->qcount;i++) {
198 if (jobid == ts->queue[i].job + UNIX_JOB_START) break;
200 if (i == ts->qcount)
201 tdb_delete(tdb, key);
202 else
203 ts->total_jobs++;
204 return 0;
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;
219 for (i=0;i<ts->qcount;i++) {
220 int qid = print_parse_jobid(ts->queue[i].file);
221 if (jobid == qid) break;
224 /* The job isn't in the system queue - we have to assume it has
225 completed, so delete the database entry. */
227 if (i == ts->qcount) {
228 time_t cur_t = time(NULL);
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. */
238 if ((cur_t - pjob.starttime) > lp_lpqcachetime())
239 tdb_delete(t, key);
240 else
241 ts->total_jobs++;
243 else
244 ts->total_jobs++;
246 return 0;
250 * Send PRINTER NOTIFY to all processes.
252 void broadcast_printer_notify(const char *printer_name)
254 /* include NUL */
255 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name,
256 strlen(printer_name) + 1, False, NULL);
259 /****************************************************************************
260 check if the print queue has been updated recently enough
261 ****************************************************************************/
262 static void print_cache_flush(int snum)
264 fstring key;
265 slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
266 tdb_store_int32(tdb, key, -1);
269 /****************************************************************************
270 Check if someone already thinks they are doing the update.
271 ****************************************************************************/
273 static pid_t get_updating_pid(fstring printer_name)
275 fstring keystr;
276 TDB_DATA data, key;
277 pid_t updating_pid;
279 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
280 key.dptr = keystr;
281 key.dsize = strlen(keystr);
283 data = tdb_fetch(tdb, key);
284 if (!data.dptr || data.dsize != sizeof(pid_t))
285 return (pid_t)-1;
287 memcpy(&updating_pid, data.dptr, sizeof(pid_t));
288 free(data.dptr);
290 if (process_exists(updating_pid))
291 return updating_pid;
293 return (pid_t)-1;
296 /****************************************************************************
297 Set the fact that we're doing the update, or have finished doing the update
298 in th tdb.
299 ****************************************************************************/
301 static void set_updating_pid(fstring printer_name, BOOL delete)
303 fstring keystr;
304 TDB_DATA key;
305 TDB_DATA data;
306 pid_t updating_pid = getpid();
308 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
309 key.dptr = keystr;
310 key.dsize = strlen(keystr);
312 if (delete) {
313 tdb_delete(tdb, key);
314 return;
317 data.dptr = (void *)&updating_pid;
318 data.dsize = sizeof(pid_t);
320 tdb_store(tdb, key, data, TDB_REPLACE);
323 /****************************************************************************
324 update the internal database from the system print queue for a queue in the background
325 ****************************************************************************/
327 static void print_queue_update_background(int snum)
329 int i, qcount;
330 print_queue_struct *queue = NULL;
331 print_status_struct status;
332 print_status_struct old_status;
333 struct printjob *pjob;
334 struct traverse_struct tstruct;
335 fstring keystr, printer_name, cachestr;
336 TDB_DATA data, key;
338 fstrcpy(printer_name, lp_servicename(snum));
341 * Check to see if someone else is doing this update.
342 * This is essentially a mutex on the update.
345 if (get_updating_pid(printer_name) != -1)
346 return;
348 /* Lock the queue for the database update */
350 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
351 tdb_lock_bystring(tdb, keystr);
354 * Ensure that no one else got in here.
355 * If the updating pid is still -1 then we are
356 * the winner.
359 if (get_updating_pid(printer_name) != -1) {
361 * Someone else is doing the update, exit.
363 tdb_unlock_bystring(tdb, keystr);
364 return;
368 * We're going to do the update ourselves.
371 /* Tell others we're doing the update. */
372 set_updating_pid(printer_name, False);
375 * Allow others to enter and notice we're doing
376 * the update.
379 tdb_unlock_bystring(tdb, keystr);
382 * Update the cache time FIRST ! Stops others even
383 * attempting to get the lock and doing this
384 * if the lpq takes a long time.
387 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
388 tdb_store_int32(tdb, cachestr, (int)time(NULL));
390 /* get the current queue using the appropriate interface */
391 ZERO_STRUCT(status);
393 qcount = (*(current_printif->queue_get))(snum, &queue, &status);
395 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
396 "s" : "", printer_name));
399 any job in the internal database that is marked as spooled
400 and doesn't exist in the system queue is considered finished
401 and removed from the database
403 any job in the system database but not in the internal database
404 is added as a unix job
406 fill in any system job numbers as we go
408 for (i=0; i<qcount; i++) {
409 int jobid = print_parse_jobid(queue[i].file);
411 if (jobid == -1) {
412 /* assume its a unix print job */
413 print_unix_job(snum, &queue[i]);
414 continue;
417 /* we have an active SMB print job - update its status */
418 pjob = print_job_find(jobid);
419 if (!pjob) {
420 /* err, somethings wrong. Probably smbd was restarted
421 with jobs in the queue. All we can do is treat them
422 like unix jobs. Pity. */
423 print_unix_job(snum, &queue[i]);
424 continue;
427 pjob->sysjob = queue[i].job;
428 pjob->status = queue[i].status;
430 print_job_store(jobid, pjob);
433 /* now delete any queued entries that don't appear in the
434 system queue */
435 tstruct.queue = queue;
436 tstruct.qcount = qcount;
437 tstruct.snum = snum;
438 tstruct.total_jobs = 0;
440 tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
442 safe_free(tstruct.queue);
444 tdb_store_int32(tdb, "INFO/total_jobs", tstruct.total_jobs);
447 * Get the old print status. We will use this to compare the
448 * number of jobs. If they have changed we need to send a
449 * "changed" message to the smbds.
452 if( qcount != get_queue_status(snum, &old_status)) {
453 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
454 old_status.qcount, qcount, printer_name ));
455 broadcast_printer_notify(printer_name);
458 /* store the new queue status structure */
459 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
460 key.dptr = keystr;
461 key.dsize = strlen(keystr);
463 status.qcount = qcount;
464 data.dptr = (void *)&status;
465 data.dsize = sizeof(status);
466 tdb_store(tdb, key, data, TDB_REPLACE);
469 * Update the cache time again. We want to do this call
470 * as little as possible...
473 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
474 tdb_store_int32(tdb, keystr, (int)time(NULL));
476 /* Delete our pid from the db. */
477 set_updating_pid(printer_name, True);
480 /****************************************************************************
481 this is the receive function of the background lpq updater
482 ****************************************************************************/
483 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
485 int snum;
486 snum=*((int *)buf);
487 print_queue_update_background(snum);
490 static pid_t background_lpq_updater_pid;
492 /****************************************************************************
493 main thread of the background lpq updater
494 ****************************************************************************/
495 void start_background_queue(void)
497 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
498 background_lpq_updater_pid = sys_fork();
500 if (background_lpq_updater_pid == -1) {
501 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
502 exit(1);
505 if(background_lpq_updater_pid == 0) {
506 /* Child. */
507 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
509 claim_connection(NULL,"smbd lpq backend",0,False);
511 if (!locking_init(0))
512 exit(1);
514 if (!print_backend_init())
515 exit(1);
517 message_register(MSG_PRINTER_UPDATE, print_queue_receive);
519 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
520 while (1) {
521 pause();
522 DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
523 message_dispatch();
528 /****************************************************************************
529 update the internal database from the system print queue for a queue
530 ****************************************************************************/
531 static void print_queue_update(int snum)
533 message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False);
536 /****************************************************************************
537 check if a jobid is valid. It is valid if it exists in the database
538 ****************************************************************************/
539 BOOL print_job_exists(int jobid)
541 return tdb_exists(tdb, print_key(jobid));
545 /****************************************************************************
546 work out which service a jobid is for
547 note that we have to look up by queue name to ensure that it works for
548 other than the process that started the job
549 ****************************************************************************/
550 int print_job_snum(int jobid)
552 struct printjob *pjob = print_job_find(jobid);
553 if (!pjob) return -1;
555 return lp_servicenumber(pjob->qname);
558 /****************************************************************************
559 give the fd used for a jobid
560 ****************************************************************************/
561 int print_job_fd(int jobid)
563 struct printjob *pjob = print_job_find(jobid);
564 if (!pjob) return -1;
565 /* don't allow another process to get this info - it is meaningless */
566 if (pjob->pid != local_pid) return -1;
567 return pjob->fd;
570 /****************************************************************************
571 give the filename used for a jobid
572 only valid for the process doing the spooling and when the job
573 has not been spooled
574 ****************************************************************************/
575 char *print_job_fname(int jobid)
577 struct printjob *pjob = print_job_find(jobid);
578 if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL;
579 return pjob->filename;
583 /****************************************************************************
584 set the place in the queue for a job
585 ****************************************************************************/
586 BOOL print_job_set_place(int jobid, int place)
588 DEBUG(2,("print_job_set_place not implemented yet\n"));
589 return False;
592 /****************************************************************************
593 set the name of a job. Only possible for owner
594 ****************************************************************************/
595 BOOL print_job_set_name(int jobid, char *name)
597 struct printjob *pjob = print_job_find(jobid);
598 if (!pjob || pjob->pid != local_pid) return False;
600 fstrcpy(pjob->jobname, name);
601 return print_job_store(jobid, pjob);
605 /****************************************************************************
606 delete a print job - don't update queue
607 ****************************************************************************/
608 static BOOL print_job_delete1(int jobid)
610 struct printjob *pjob = print_job_find(jobid);
611 int snum, result = 0;
613 if (!pjob) return False;
616 * If already deleting just return.
619 if (pjob->status == LPQ_DELETING)
620 return True;
622 snum = print_job_snum(jobid);
624 /* Hrm - we need to be able to cope with deleting a job before it
625 has reached the spooler. */
627 if (pjob->sysjob == -1) {
628 DEBUG(5, ("attempt to delete job %d not seen by lpr\n",
629 jobid));
632 /* Set the tdb entry to be deleting. */
634 pjob->status = LPQ_DELETING;
635 print_job_store(jobid, pjob);
637 if (pjob->spooled && pjob->sysjob != -1)
638 result = (*(current_printif->job_delete))(snum, pjob);
640 /* Delete the tdb entry if the delete suceeded or the job hasn't
641 been spooled. */
643 if (result == 0) {
644 tdb_delete(tdb, print_key(jobid));
647 return (result == 0);
650 /****************************************************************************
651 return true if the current user owns the print job
652 ****************************************************************************/
653 static BOOL is_owner(struct current_user *user, int jobid)
655 struct printjob *pjob = print_job_find(jobid);
656 user_struct *vuser;
658 if (!pjob || !user) return False;
660 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
661 return strequal(pjob->user, vuser->user.smb_name);
662 } else {
663 return strequal(pjob->user, uidtoname(user->uid));
667 /****************************************************************************
668 delete a print job
669 ****************************************************************************/
670 BOOL print_job_delete(struct current_user *user, int jobid, WERROR *errcode)
672 int snum = print_job_snum(jobid);
673 char *printer_name;
674 BOOL owner;
676 owner = is_owner(user, jobid);
678 /* Check access against security descriptor or whether the user
679 owns their job. */
681 if (!owner &&
682 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
683 DEBUG(3, ("delete denied by security descriptor\n"));
684 *errcode = WERR_ACCESS_DENIED;
685 return False;
688 if (!print_job_delete1(jobid)) return False;
690 /* force update the database and say the delete failed if the
691 job still exists */
693 print_queue_update(snum);
695 /* Send a printer notify message */
697 printer_name = PRINTERNAME(snum);
699 broadcast_printer_notify(printer_name);
701 return !print_job_exists(jobid);
705 /****************************************************************************
706 pause a job
707 ****************************************************************************/
708 BOOL print_job_pause(struct current_user *user, int jobid, WERROR *errcode)
710 struct printjob *pjob = print_job_find(jobid);
711 int snum, ret = -1;
712 char *printer_name;
714 if (!pjob || !user) return False;
716 if (!pjob->spooled || pjob->sysjob == -1) return False;
718 snum = print_job_snum(jobid);
720 if (!is_owner(user, jobid) &&
721 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
722 DEBUG(3, ("pause denied by security descriptor\n"));
723 *errcode = WERR_ACCESS_DENIED;
724 return False;
727 /* need to pause the spooled entry */
728 ret = (*(current_printif->job_pause))(snum, pjob);
730 if (ret != 0) {
731 *errcode = WERR_INVALID_PARAM;
732 return False;
735 /* force update the database */
736 print_cache_flush(snum);
738 /* Send a printer notify message */
740 printer_name = PRINTERNAME(snum);
742 broadcast_printer_notify(printer_name);
744 /* how do we tell if this succeeded? */
746 return True;
749 /****************************************************************************
750 resume a job
751 ****************************************************************************/
752 BOOL print_job_resume(struct current_user *user, int jobid, WERROR *errcode)
754 struct printjob *pjob = print_job_find(jobid);
755 char *printer_name;
756 int snum, ret;
758 if (!pjob || !user) return False;
760 if (!pjob->spooled || pjob->sysjob == -1) return False;
762 snum = print_job_snum(jobid);
764 if (!is_owner(user, jobid) &&
765 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
766 DEBUG(3, ("resume denied by security descriptor\n"));
767 *errcode = WERR_ACCESS_DENIED;
768 return False;
771 ret = (*(current_printif->job_resume))(snum, pjob);
773 if (ret != 0) {
774 *errcode = WERR_INVALID_PARAM;
775 return False;
778 /* force update the database */
779 print_cache_flush(snum);
781 /* Send a printer notify message */
783 printer_name = PRINTERNAME(snum);
785 broadcast_printer_notify(printer_name);
787 return True;
790 /****************************************************************************
791 write to a print file
792 ****************************************************************************/
793 int print_job_write(int jobid, const char *buf, int size)
795 int fd;
797 fd = print_job_fd(jobid);
798 if (fd == -1) return -1;
800 return write(fd, buf, size);
803 /****************************************************************************
804 Check if the print queue has been updated recently enough.
805 ****************************************************************************/
807 static BOOL print_cache_expired(int snum)
809 fstring key;
810 time_t t2, t = time(NULL);
812 slprintf(key, sizeof(key)-1, "CACHE/%s", lp_servicename(snum));
813 t2 = tdb_fetch_int32(tdb, key);
814 if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) {
815 DEBUG(3, ("print cache expired for queue %s \
816 (last_cache = %d, time now = %d, qcachetime = %d)\n", lp_servicename(snum),
817 (int)t2, (int)t, (int)lp_lpqcachetime() ));
818 return True;
820 return False;
823 /****************************************************************************
824 Get the queue status - do not update if db is out of date.
825 ****************************************************************************/
826 static int get_queue_status(int snum, print_status_struct *status)
828 fstring keystr;
829 TDB_DATA data, key;
831 ZERO_STRUCTP(status);
832 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
833 key.dptr = keystr;
834 key.dsize = strlen(keystr);
835 data = tdb_fetch(tdb, key);
836 if (data.dptr) {
837 if (data.dsize == sizeof(print_status_struct)) {
838 memcpy(status, data.dptr, sizeof(print_status_struct));
840 free(data.dptr);
842 return status->qcount;
845 /****************************************************************************
846 Determine the number of jobs in a queue.
847 ****************************************************************************/
849 int print_queue_length(int snum, print_status_struct *pstatus)
851 print_status_struct status;
852 int len;
854 /* make sure the database is up to date */
855 if (print_cache_expired(snum))
856 print_queue_update(snum);
858 /* also fetch the queue status */
859 memset(&status, 0, sizeof(status));
860 len = get_queue_status(snum, &status);
861 if (pstatus)
862 *pstatus = status;
863 return len;
866 /****************************************************************************
867 Determine the number of jobs in all queues.
868 ****************************************************************************/
869 static int get_total_jobs(int snum)
871 int total_jobs;
873 /* make sure the database is up to date */
874 if (print_cache_expired(snum)) print_queue_update(snum);
876 total_jobs = tdb_fetch_int32(tdb, "INFO/total_jobs");
877 if (total_jobs >0)
878 return total_jobs;
879 else
880 return 0;
883 /***************************************************************************
884 start spooling a job - return the jobid
885 ***************************************************************************/
886 int print_job_start(struct current_user *user, int snum, char *jobname)
888 int jobid;
889 char *path;
890 struct printjob pjob;
891 int next_jobid;
892 user_struct *vuser;
893 int njobs = 0;
895 errno = 0;
897 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
898 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
899 return -1;
902 if (!print_time_access_check(snum)) {
903 DEBUG(3, ("print_job_start: job start denied by time check\n"));
904 return -1;
907 path = lp_pathname(snum);
909 /* see if we have sufficient disk space */
910 if (lp_minprintspace(snum)) {
911 SMB_BIG_UINT dspace, dsize;
912 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
913 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
914 DEBUG(3, ("print_job_start: disk space check failed.\n"));
915 errno = ENOSPC;
916 return -1;
920 /* for autoloaded printers, check that the printcap entry still exists */
921 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
922 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_servicename(snum) ));
923 errno = ENOENT;
924 return -1;
927 /* Insure the maximum queue size is not violated */
928 if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
929 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n",
930 njobs, lp_maxprintjobs(snum) ));
931 errno = ENOSPC;
932 return -1;
935 /* Insure the maximum print jobs in the system is not violated */
936 if (lp_totalprintjobs() && get_total_jobs(snum) > lp_totalprintjobs()) {
937 DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per system (%d).\n",
938 njobs, lp_totalprintjobs() ));
939 errno = ENOSPC;
940 return -1;
943 /* create the database entry */
944 ZERO_STRUCT(pjob);
945 pjob.pid = local_pid;
946 pjob.sysjob = -1;
947 pjob.fd = -1;
948 pjob.starttime = time(NULL);
949 pjob.status = LPQ_SPOOLING;
950 pjob.size = 0;
951 pjob.spooled = False;
952 pjob.smbjob = True;
954 fstrcpy(pjob.jobname, jobname);
956 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
957 fstrcpy(pjob.user, vuser->user.smb_name);
958 } else {
959 fstrcpy(pjob.user, uidtoname(user->uid));
962 fstrcpy(pjob.qname, lp_servicename(snum));
964 /* lock the database */
965 tdb_lock_bystring(tdb, "INFO/nextjob");
967 next_jobid = tdb_fetch_int32(tdb, "INFO/nextjob");
968 if (next_jobid == -1)
969 next_jobid = 1;
971 for (jobid = NEXT_JOBID(next_jobid); jobid != next_jobid; jobid = NEXT_JOBID(jobid)) {
972 if (!print_job_exists(jobid))
973 break;
975 if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
976 DEBUG(3, ("print_job_start: either jobid (%d)==next_jobid(%d) or print_job_store failed.\n",
977 jobid, next_jobid ));
978 jobid = -1;
979 goto fail;
982 tdb_store_int32(tdb, "INFO/nextjob", jobid);
984 /* we have a job entry - now create the spool file */
985 slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.6d.XXXXXX",
986 path, PRINT_SPOOL_PREFIX, jobid);
987 pjob.fd = smb_mkstemp(pjob.filename);
989 if (pjob.fd == -1) {
990 if (errno == EACCES) {
991 /* Common setup error, force a report. */
992 DEBUG(0, ("print_job_start: insufficient permissions \
993 to open spool file %s.\n", pjob.filename));
994 } else {
995 /* Normal case, report at level 3 and above. */
996 DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
997 DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
999 goto fail;
1002 print_job_store(jobid, &pjob);
1004 tdb_unlock_bystring(tdb, "INFO/nextjob");
1007 * If the printer is marked as postscript output a leading
1008 * file identifier to ensure the file is treated as a raw
1009 * postscript file.
1010 * This has a similar effect as CtrlD=0 in WIN.INI file.
1011 * tim@fsg.com 09/06/94
1013 if (lp_postscript(snum)) {
1014 print_job_write(jobid, "%!\n",3);
1017 return jobid;
1019 fail:
1020 if (jobid != -1) {
1021 tdb_delete(tdb, print_key(jobid));
1024 tdb_unlock_bystring(tdb, "INFO/nextjob");
1026 DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
1027 return -1;
1030 /****************************************************************************
1031 Print a file - called on closing the file. This spools the job.
1032 If normal close is false then we're tearing down the jobs - treat as an
1033 error.
1034 ****************************************************************************/
1036 BOOL print_job_end(int jobid, BOOL normal_close)
1038 struct printjob *pjob = print_job_find(jobid);
1039 int snum, ret;
1040 SMB_STRUCT_STAT sbuf;
1042 if (!pjob)
1043 return False;
1045 if (pjob->spooled || pjob->pid != local_pid)
1046 return False;
1048 snum = print_job_snum(jobid);
1050 if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
1051 pjob->size = sbuf.st_size;
1052 close(pjob->fd);
1053 pjob->fd = -1;
1054 } else {
1057 * Not a normal close or we couldn't stat the job file,
1058 * so something has gone wrong. Cleanup.
1060 close(pjob->fd);
1061 pjob->fd = -1;
1062 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
1063 goto fail;
1066 /* Technically, this is not quit right. If the printer has a separator
1067 * page turned on, the NT spooler prints the separator page even if the
1068 * print job is 0 bytes. 010215 JRR */
1069 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
1070 /* don't bother spooling empty files or something being deleted. */
1071 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
1072 pjob->filename, pjob->size ? "deleted" : "zero length" ));
1073 unlink(pjob->filename);
1074 tdb_delete(tdb, print_key(jobid));
1075 return True;
1078 ret = (*(current_printif->job_submit))(snum, pjob);
1080 if (ret)
1081 goto fail;
1083 /* The print job has been sucessfully handed over to the back-end */
1085 pjob->spooled = True;
1086 pjob->status = LPQ_QUEUED;
1087 print_job_store(jobid, pjob);
1089 /* make sure the database is up to date */
1090 if (print_cache_expired(snum))
1091 print_queue_update(snum);
1093 return True;
1095 fail:
1097 /* The print job was not succesfully started. Cleanup */
1098 /* Still need to add proper error return propagation! 010122:JRR */
1099 unlink(pjob->filename);
1100 tdb_delete(tdb, print_key(jobid));
1101 return False;
1104 /* utility fn to enumerate the print queue */
1105 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1107 struct traverse_struct *ts = (struct traverse_struct *)state;
1108 struct printjob pjob;
1109 int i, jobid;
1111 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1112 memcpy(&jobid, key.dptr, sizeof(jobid));
1113 memcpy(&pjob, data.dptr, sizeof(pjob));
1115 /* maybe it isn't for this queue */
1116 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1118 if (ts->qcount >= ts->maxcount) return 0;
1120 i = ts->qcount;
1122 ts->queue[i].job = jobid;
1123 ts->queue[i].size = pjob.size;
1124 ts->queue[i].status = pjob.status;
1125 ts->queue[i].priority = 1;
1126 ts->queue[i].time = pjob.starttime;
1127 fstrcpy(ts->queue[i].user, pjob.user);
1128 fstrcpy(ts->queue[i].file, pjob.jobname);
1130 ts->qcount++;
1132 return 0;
1135 struct traverse_count_struct {
1136 int snum, count;
1139 /* utility fn to count the number of entries in the print queue */
1140 static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1142 struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
1143 struct printjob pjob;
1144 int jobid;
1146 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1147 memcpy(&jobid, key.dptr, sizeof(jobid));
1148 memcpy(&pjob, data.dptr, sizeof(pjob));
1150 /* maybe it isn't for this queue */
1151 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1153 ts->count++;
1155 return 0;
1158 /* Sort print jobs by submittal time */
1160 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1162 /* Silly cases */
1164 if (!j1 && !j2) return 0;
1165 if (!j1) return -1;
1166 if (!j2) return 1;
1168 /* Sort on job start time */
1170 if (j1->time == j2->time) return 0;
1171 return (j1->time > j2->time) ? 1 : -1;
1174 /****************************************************************************
1175 get a printer queue listing
1176 ****************************************************************************/
1177 int print_queue_status(int snum,
1178 print_queue_struct **queue,
1179 print_status_struct *status)
1181 struct traverse_struct tstruct;
1182 struct traverse_count_struct tsc;
1183 fstring keystr;
1184 TDB_DATA data, key;
1186 /* make sure the database is up to date */
1187 if (print_cache_expired(snum)) print_queue_update(snum);
1189 *queue = NULL;
1192 * Fetch the queue status. We must do this first, as there may
1193 * be no jobs in the queue.
1195 ZERO_STRUCTP(status);
1196 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", lp_servicename(snum));
1197 key.dptr = keystr;
1198 key.dsize = strlen(keystr);
1199 data = tdb_fetch(tdb, key);
1200 if (data.dptr) {
1201 if (data.dsize == sizeof(*status)) {
1202 memcpy(status, data.dptr, sizeof(*status));
1204 free(data.dptr);
1208 * Now, fetch the print queue information. We first count the number
1209 * of entries, and then only retrieve the queue if necessary.
1211 tsc.count = 0;
1212 tsc.snum = snum;
1214 tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc);
1216 if (tsc.count == 0)
1217 return 0;
1219 /* Allocate the queue size. */
1220 if ((tstruct.queue = (print_queue_struct *)
1221 malloc(sizeof(print_queue_struct)*tsc.count))
1222 == NULL)
1223 return 0;
1226 * Fill in the queue.
1227 * We need maxcount as the queue size may have changed between
1228 * the two calls to tdb_traverse.
1230 tstruct.qcount = 0;
1231 tstruct.maxcount = tsc.count;
1232 tstruct.snum = snum;
1234 tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
1236 /* Sort the queue by submission time otherwise they are displayed
1237 in hash order. */
1239 qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
1240 QSORT_CAST(printjob_comp));
1242 *queue = tstruct.queue;
1243 return tstruct.qcount;
1247 /****************************************************************************
1248 turn a queue name into a snum
1249 ****************************************************************************/
1250 int print_queue_snum(char *qname)
1252 int snum = lp_servicenumber(qname);
1253 if (snum == -1 || !lp_print_ok(snum)) return -1;
1254 return snum;
1258 /****************************************************************************
1259 pause a queue
1260 ****************************************************************************/
1261 BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
1263 char *printer_name;
1264 int ret;
1266 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1267 *errcode = WERR_ACCESS_DENIED;
1268 return False;
1271 ret = (*(current_printif->queue_pause))(snum);
1273 if (ret != 0) {
1274 *errcode = WERR_INVALID_PARAM;
1275 return False;
1278 /* force update the database */
1279 print_cache_flush(snum);
1281 /* Send a printer notify message */
1283 printer_name = PRINTERNAME(snum);
1285 broadcast_printer_notify(printer_name);
1287 return True;
1290 /****************************************************************************
1291 resume a queue
1292 ****************************************************************************/
1293 BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
1295 char *printer_name;
1296 int ret;
1298 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1299 *errcode = WERR_ACCESS_DENIED;
1300 return False;
1303 ret = (*(current_printif->queue_resume))(snum);
1305 if (ret != 0) {
1306 *errcode = WERR_INVALID_PARAM;
1307 return False;
1310 /* make sure the database is up to date */
1311 if (print_cache_expired(snum)) print_queue_update(snum);
1313 /* Send a printer notify message */
1315 printer_name = PRINTERNAME(snum);
1317 broadcast_printer_notify(printer_name);
1319 return True;
1322 /****************************************************************************
1323 purge a queue - implemented by deleting all jobs that we can delete
1324 ****************************************************************************/
1325 BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
1327 print_queue_struct *queue;
1328 print_status_struct status;
1329 char *printer_name;
1330 int njobs, i;
1331 BOOL can_job_admin;
1333 /* Force and update so the count is accurate (i.e. not a cached count) */
1334 print_queue_update(snum);
1336 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
1337 njobs = print_queue_status(snum, &queue, &status);
1339 for (i=0;i<njobs;i++) {
1340 BOOL owner = is_owner(user, queue[i].job);
1342 if (owner || can_job_admin) {
1343 print_job_delete1(queue[i].job);
1347 safe_free(queue);
1349 /* Send a printer notify message */
1351 printer_name = PRINTERNAME(snum);
1353 broadcast_printer_notify(printer_name);
1355 return True;