3 Unix SMB/Netbios implementation.
5 printing backend routines
6 Copyright (C) Andrew Tridgell 1992-2000
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 extern int DEBUGLEVEL;
28 the printing backend revolves around a tdb database that stores the
29 SMB view of the print queue
31 The key for this database is a jobid - a internally generated number that
32 uniquely identifies a print job
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
38 jobids are assigned when a job starts spooling.
42 pid_t pid; /* which process launched the job */
43 int sysjob; /* the system (lp) job number */
44 int fd; /* file descriptor of open file if open */
45 time_t starttime; /* when the job started spooling */
46 int status; /* the status of this job */
47 size_t size; /* the size of the job so far */
48 BOOL spooled; /* has it been sent to the spooler yet? */
49 BOOL smbjob; /* set if the job is a SMB job */
50 fstring filename; /* the filename used to spool the file */
51 fstring jobname; /* the job name given to us by the client */
52 fstring user; /* the user who started the job */
53 fstring qname; /* name of the print queue the job was sent to */
56 /* the open printing.tdb database */
57 static TDB_CONTEXT *tdb;
58 static pid_t local_pid;
60 #define PRINT_MAX_JOBID 10000
61 #define UNIX_JOB_START PRINT_MAX_JOBID
63 #define PRINT_SPOOL_PREFIX "smbprn."
64 #define PRINT_DATABASE_VERSION 2
66 static int get_queue_status(int, print_status_struct *);
68 /****************************************************************************
69 initialise the printing backend. Called once at startup.
70 Does not survive a fork
71 ****************************************************************************/
72 BOOL print_backend_init(void)
74 char *sversion = "INFO/version";
76 if (tdb && local_pid == sys_getpid()) return True;
77 tdb = tdb_open(lock_path("printing.tdb"), 0, 0, O_RDWR|O_CREAT, 0600);
79 DEBUG(0,("Failed to open printing backend database\n"));
81 local_pid = sys_getpid();
83 /* handle a Samba upgrade */
84 tdb_lock_bystring(tdb, sversion);
85 if (tdb_fetch_int(tdb, sversion) != PRINT_DATABASE_VERSION) {
86 tdb_traverse(tdb, (tdb_traverse_func)tdb_delete, NULL);
87 tdb_store_int(tdb, sversion, PRINT_DATABASE_VERSION);
89 tdb_unlock_bystring(tdb, sversion);
91 return nt_printing_init();
94 /****************************************************************************
95 useful function to generate a tdb key
96 ****************************************************************************/
97 static TDB_DATA print_key(int jobid)
103 ret.dptr = (void *)&j;
104 ret.dsize = sizeof(j);
108 /****************************************************************************
109 useful function to find a print job in the database
110 ****************************************************************************/
111 static struct printjob *print_job_find(int jobid)
113 static struct printjob pjob;
116 ret = tdb_fetch(tdb, print_key(jobid));
117 if (!ret.dptr || ret.dsize != sizeof(pjob)) return NULL;
119 memcpy(&pjob, ret.dptr, sizeof(pjob));
124 /****************************************************************************
125 store a job structure back to the database
126 ****************************************************************************/
127 static BOOL print_job_store(int jobid, struct printjob *pjob)
130 d.dptr = (void *)pjob;
131 d.dsize = sizeof(*pjob);
133 return (tdb_store(tdb, print_key(jobid), d, TDB_REPLACE) == 0);
136 /****************************************************************************
137 run a given print command
138 a null terminated list of value/substitute pairs is provided
139 for local substitution strings
140 ****************************************************************************/
141 static int print_run_command(int snum,char *command,
150 if (!command || !*command) return -1;
152 if (!VALID_SNUM(snum)) {
153 DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
157 pstrcpy(syscmd, command);
159 va_start(ap, outfile);
160 while ((arg = va_arg(ap, char *))) {
161 char *value = va_arg(ap,char *);
162 pstring_sub(syscmd, arg, value);
166 p = PRINTERNAME(snum);
168 pstring_sub(syscmd, "%p", p);
169 standard_sub_snum(snum,syscmd);
171 /* Convert script args to unix-codepage */
172 dos_to_unix(syscmd, True);
173 ret = smbrun(syscmd,outfile,False);
175 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
181 /****************************************************************************
182 parse a file name from the system spooler to generate a jobid
183 ****************************************************************************/
184 static int print_parse_jobid(char *fname)
188 if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0) return -1;
189 fname += strlen(PRINT_SPOOL_PREFIX);
192 if (jobid <= 0) return -1;
198 /****************************************************************************
199 list a unix job in the print database
200 ****************************************************************************/
201 static void print_unix_job(int snum, print_queue_struct *q)
203 int jobid = q->job + UNIX_JOB_START;
204 struct printjob pj, *old_pj;
206 /* Preserve the timestamp on an existing unix print job */
208 old_pj = print_job_find(jobid);
215 pj.starttime = old_pj ? old_pj->starttime : q->time;
216 pj.status = q->status;
220 fstrcpy(pj.filename, "");
221 fstrcpy(pj.jobname, q->file);
222 fstrcpy(pj.user, q->user);
223 fstrcpy(pj.qname, lp_servicename(snum));
225 print_job_store(jobid, &pj);
229 struct traverse_struct {
230 print_queue_struct *queue;
231 int qcount, snum, maxcount;
234 /* utility fn to delete any jobs that are no longer active */
235 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
237 struct traverse_struct *ts = (struct traverse_struct *)state;
238 struct printjob pjob;
241 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
242 memcpy(&jobid, key.dptr, sizeof(jobid));
243 memcpy(&pjob, data.dptr, sizeof(pjob));
245 if (strcmp(lp_servicename(ts->snum), pjob.qname)) {
246 /* this isn't for the queue we are looking at */
251 /* remove a unix job if it isn't in the system queue
254 for (i=0;i<ts->qcount;i++) {
255 if (jobid == ts->queue[i].job + UNIX_JOB_START) break;
257 if (i == ts->qcount) tdb_delete(tdb, key);
261 /* maybe it hasn't been spooled yet */
263 /* if a job is not spooled and the process doesn't
264 exist then kill it. This cleans up after smbd
266 if (!process_exists(pjob.pid)) {
267 tdb_delete(tdb, key);
272 for (i=0;i<ts->qcount;i++) {
273 int qid = print_parse_jobid(ts->queue[i].file);
274 if (jobid == qid) break;
277 /* The job isn't in the system queue - we have to assume it has
278 completed, so delete the database entry. */
280 if (i == ts->qcount) {
281 time_t cur_t = time(NULL);
283 /* A race can occur between the time a job is spooled and
284 when it appears in the lpq output. This happens when
285 the job is added to printing.tdb when another smbd
286 running print_queue_update() has completed a lpq and
287 is currently traversing the printing tdb and deleting jobs.
288 A workaround is to not delete the job if it has been
289 submitted less than lp_lpqcachetime() seconds ago. */
291 if ((cur_t - pjob.starttime) > lp_lpqcachetime()) {
299 /****************************************************************************
300 check if the print queue has been updated recently enough
301 ****************************************************************************/
302 static void print_cache_flush(int snum)
305 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
306 dos_to_unix(key, True); /* Convert key to unix-codepage */
307 tdb_store_int(tdb, key, -1);
310 /****************************************************************************
311 update the internal database from the system print queue for a queue
312 ****************************************************************************/
313 static void print_queue_update(int snum)
315 char *path = lp_pathname(snum);
316 char *cmd = lp_lpqcommand(snum);
319 int numlines, 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;
328 /* Convert printer name (i.e. share name) to unix-codepage for all of the
329 * following tdb key generation */
330 fstrcpy(printer_name, lp_servicename(snum));
331 dos_to_unix(printer_name, True);
334 * Update the cache time FIRST ! Stops others doing this
335 * if the lpq takes a long time.
338 slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name);
339 tdb_store_int(tdb, keystr, (int)time(NULL));
341 slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid);
344 print_run_command(snum, cmd, tmp_file, NULL);
347 qlines = file_lines_load(tmp_file, &numlines, True);
350 /* turn the lpq output into a series of job structures */
354 queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1));
357 for (i=0; i<numlines; i++) {
359 if (parse_lpq_entry(snum,qlines[i],
360 &queue[qcount],&status,qcount==0)) {
365 file_lines_free(qlines);
367 DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
368 "s" : "", printer_name));
370 /* Lock the queue for the database update */
372 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
373 tdb_lock_bystring(tdb, keystr);
376 any job in the internal database that is marked as spooled
377 and doesn't exist in the system queue is considered finished
378 and removed from the database
380 any job in the system database but not in the internal database
381 is added as a unix job
383 fill in any system job numbers as we go
385 for (i=0; i<qcount; i++) {
386 int jobid = print_parse_jobid(queue[i].file);
389 /* assume its a unix print job */
390 print_unix_job(snum, &queue[i]);
394 /* we have an active SMB print job - update its status */
395 pjob = print_job_find(jobid);
397 /* err, somethings wrong. Probably smbd was restarted
398 with jobs in the queue. All we can do is treat them
399 like unix jobs. Pity. */
400 print_unix_job(snum, &queue[i]);
404 pjob->sysjob = queue[i].job;
405 pjob->status = queue[i].status;
407 print_job_store(jobid, pjob);
410 /* now delete any queued entries that don't appear in the
412 tstruct.queue = queue;
413 tstruct.qcount = qcount;
416 tdb_traverse(tdb, traverse_fn_delete, (void *)&tstruct);
418 safe_free(tstruct.queue);
421 * Get the old print status. We will use this to compare the
422 * number of jobs. If they have changed we need to send a
423 * "changed" message to the smbds.
426 if( qcount != get_queue_status(snum, &old_status)) {
427 DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
428 old_status.qcount, qcount, printer_name ));
429 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
432 /* store the new queue status structure */
433 slprintf(keystr, sizeof(keystr), "STATUS/%s", printer_name);
435 key.dsize = strlen(keystr);
437 status.qcount = qcount;
438 data.dptr = (void *)&status;
439 data.dsize = sizeof(status);
440 tdb_store(tdb, key, data, TDB_REPLACE);
442 /* Unlock for database update */
444 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
445 tdb_unlock_bystring(tdb, keystr);
448 * Update the cache time again. We want to do this call
449 * as little as possible...
452 slprintf(keystr, sizeof(keystr), "CACHE/%s", printer_name);
453 tdb_store_int(tdb, keystr, (int)time(NULL));
456 /****************************************************************************
457 check if a jobid is valid. It is valid if it exists in the database
458 ****************************************************************************/
459 BOOL print_job_exists(int jobid)
461 return tdb_exists(tdb, print_key(jobid));
465 /****************************************************************************
466 work out which service a jobid is for
467 note that we have to look up by queue name to ensure that it works for
468 other than the process that started the job
469 ****************************************************************************/
470 int print_job_snum(int jobid)
472 struct printjob *pjob = print_job_find(jobid);
473 if (!pjob) return -1;
475 return lp_servicenumber(pjob->qname);
478 /****************************************************************************
479 give the fd used for a jobid
480 ****************************************************************************/
481 int print_job_fd(int jobid)
483 struct printjob *pjob = print_job_find(jobid);
484 if (!pjob) return -1;
485 /* don't allow another process to get this info - it is meaningless */
486 if (pjob->pid != local_pid) return -1;
490 /****************************************************************************
491 give the filename used for a jobid
492 only valid for the process doing the spooling and when the job
494 ****************************************************************************/
495 char *print_job_fname(int jobid)
497 struct printjob *pjob = print_job_find(jobid);
498 if (!pjob || pjob->spooled || pjob->pid != local_pid) return NULL;
499 return pjob->filename;
503 /****************************************************************************
504 set the place in the queue for a job
505 ****************************************************************************/
506 BOOL print_job_set_place(int jobid, int place)
508 DEBUG(2,("print_job_set_place not implemented yet\n"));
512 /****************************************************************************
513 set the name of a job. Only possible for owner
514 ****************************************************************************/
515 BOOL print_job_set_name(int jobid, char *name)
517 struct printjob *pjob = print_job_find(jobid);
518 if (!pjob || pjob->pid != local_pid) return False;
520 fstrcpy(pjob->jobname, name);
521 return print_job_store(jobid, pjob);
525 /****************************************************************************
526 delete a print job - don't update queue
527 ****************************************************************************/
528 static BOOL print_job_delete1(int jobid)
530 struct printjob *pjob = print_job_find(jobid);
533 if (!pjob) return False;
535 snum = print_job_snum(jobid);
537 /* Hrm - we need to be able to cope with deleting a job before it
538 has reached the spooler. */
540 if (pjob->sysjob == -1) {
541 DEBUG(5, ("attempt to delete job %d not seen by lpr\n",
545 if (pjob->spooled && pjob->sysjob != -1) {
546 /* need to delete the spooled entry */
548 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
549 print_run_command(snum,
550 lp_lprmcommand(snum), NULL,
552 "%T", http_timestring(pjob->starttime),
559 /****************************************************************************
560 return true if the current user owns the print job
561 ****************************************************************************/
562 static BOOL is_owner(struct current_user *user, int jobid)
564 struct printjob *pjob = print_job_find(jobid);
567 if (!pjob || !user) return False;
569 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
570 return strequal(pjob->user, vuser->user.smb_name);
572 return strequal(pjob->user, uidtoname(user->uid));
576 /****************************************************************************
578 ****************************************************************************/
579 BOOL print_job_delete(struct current_user *user, int jobid, int *errcode)
581 int snum = print_job_snum(jobid);
585 owner = is_owner(user, jobid);
587 /* Check access against security descriptor or whether the user
591 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
592 DEBUG(3, ("delete denied by security descriptor\n"));
593 *errcode = ERROR_ACCESS_DENIED;
597 if (!print_job_delete1(jobid)) return False;
599 /* force update the database and say the delete failed if the
602 print_queue_update(snum);
604 /* Send a printer notify message */
606 printer_name = PRINTERNAME(snum);
608 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
610 return !print_job_exists(jobid);
614 /****************************************************************************
616 ****************************************************************************/
617 BOOL print_job_pause(struct current_user *user, int jobid, int *errcode)
619 struct printjob *pjob = print_job_find(jobid);
625 if (!pjob || !user) return False;
627 if (!pjob->spooled || pjob->sysjob == -1) return False;
629 snum = print_job_snum(jobid);
630 owner = is_owner(user, jobid);
633 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
634 DEBUG(3, ("pause denied by security descriptor\n"));
635 *errcode = ERROR_ACCESS_DENIED;
639 /* need to pause the spooled entry */
640 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
641 ret = print_run_command(snum,
642 lp_lppausecommand(snum), NULL,
647 *errcode = ERROR_INVALID_PARAMETER;
651 /* force update the database */
652 print_cache_flush(snum);
654 /* Send a printer notify message */
656 printer_name = PRINTERNAME(snum);
658 message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
660 /* how do we tell if this succeeded? */
665 /****************************************************************************
667 ****************************************************************************/
668 BOOL print_job_resume(struct current_user *user, int jobid, int *errcode)
670 struct printjob *pjob = print_job_find(jobid);
676 if (!pjob || !user) return False;
678 if (!pjob->spooled || pjob->sysjob == -1) return False;
680 snum = print_job_snum(jobid);
681 owner = is_owner(user, jobid);
683 if (!is_owner(user, jobid) &&
684 !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
685 DEBUG(3, ("resume denied by security descriptor\n"));
686 *errcode = ERROR_ACCESS_DENIED;
690 slprintf(jobstr, sizeof(jobstr), "%d", pjob->sysjob);
691 ret = print_run_command(snum,
692 lp_lpresumecommand(snum), NULL,
697 *errcode = ERROR_INVALID_PARAMETER;
701 /* force update the database */
702 print_cache_flush(snum);
704 /* Send a printer notify message */
706 printer_name = PRINTERNAME(snum);
708 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
713 /****************************************************************************
714 write to a print file
715 ****************************************************************************/
716 int print_job_write(int jobid, const char *buf, int size)
720 fd = print_job_fd(jobid);
721 if (fd == -1) return -1;
723 return write(fd, buf, size);
726 /****************************************************************************
727 Check if the print queue has been updated recently enough.
728 ****************************************************************************/
730 static BOOL print_cache_expired(int snum)
733 time_t t2, t = time(NULL);
735 slprintf(key, sizeof(key), "CACHE/%s", lp_servicename(snum));
736 dos_to_unix(key, True); /* Convert key to unix-codepage */
737 t2 = tdb_fetch_int(tdb, key);
738 if (t2 == ((time_t)-1) || (t - t2) >= lp_lpqcachetime()) {
739 DEBUG(3, ("print cache expired\n"));
745 /****************************************************************************
746 Get the queue status - do not update if db is out of date.
747 ****************************************************************************/
749 static int get_queue_status(int snum, print_status_struct *status)
754 ZERO_STRUCTP(status);
755 slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum));
756 dos_to_unix(keystr, True); /* Convert key to unix-codepage */
758 key.dsize = strlen(keystr);
759 data = tdb_fetch(tdb, key);
761 if (data.dsize == sizeof(print_status_struct)) {
762 memcpy(status, data.dptr, sizeof(print_status_struct));
766 return status->qcount;
769 /****************************************************************************
770 Determine the number of jobs in a queue.
771 ****************************************************************************/
773 static int print_queue_length(int snum)
775 print_status_struct status;
777 /* make sure the database is up to date */
778 if (print_cache_expired(snum)) print_queue_update(snum);
780 /* also fetch the queue status */
781 return get_queue_status(snum, &status);
784 /***************************************************************************
785 start spooling a job - return the jobid
786 ***************************************************************************/
787 int print_job_start(struct current_user *user, int snum, char *jobname)
791 struct printjob pjob;
797 if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
798 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
802 if (!print_time_access_check(snum)) {
803 DEBUG(3, ("print_job_start: job start denied by time check\n"));
807 path = lp_pathname(snum);
809 /* see if we have sufficient disk space */
810 if (lp_minprintspace(snum)) {
811 SMB_BIG_UINT dspace, dsize;
812 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
813 dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
819 /* for autoloaded printers, check that the printcap entry still exists */
820 if (lp_autoloaded(snum) && !pcap_printername_ok(lp_servicename(snum), NULL)) {
825 if (lp_maxprintjobs(snum) && print_queue_length(snum) > lp_maxprintjobs(snum)) {
830 /* create the database entry */
832 pjob.pid = local_pid;
835 pjob.starttime = time(NULL);
836 pjob.status = LPQ_QUEUED;
838 pjob.spooled = False;
841 fstrcpy(pjob.jobname, jobname);
843 if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
844 fstrcpy(pjob.user, vuser->user.smb_name);
846 fstrcpy(pjob.user, uidtoname(user->uid));
849 fstrcpy(pjob.qname, lp_servicename(snum));
851 /* lock the database */
852 tdb_lock_bystring(tdb, "INFO/nextjob");
855 next_jobid = tdb_fetch_int(tdb, "INFO/nextjob");
856 if (next_jobid == -1) next_jobid = 1;
858 for (jobid = next_jobid+1; jobid != next_jobid; ) {
859 if (!print_job_exists(jobid)) break;
860 jobid = (jobid + 1) % PRINT_MAX_JOBID;
861 if (jobid == 0) jobid = 1;
863 if (jobid == next_jobid || !print_job_store(jobid, &pjob)) {
868 tdb_store_int(tdb, "INFO/nextjob", jobid);
870 /* we have a job entry - now create the spool file
872 we unlink first to cope with old spool files and also to beat
873 a symlink security hole - it allows us to use O_EXCL
874 There may be old spool files owned by other users lying around.
876 slprintf(pjob.filename, sizeof(pjob.filename), "%s/%s%d",
877 path, PRINT_SPOOL_PREFIX, jobid);
878 if (unlink(pjob.filename) == -1 && errno != ENOENT) {
881 pjob.fd = sys_open(pjob.filename,O_WRONLY|O_CREAT|O_EXCL,0600);
882 if (pjob.fd == -1) goto fail;
884 print_job_store(jobid, &pjob);
886 tdb_unlock_bystring(tdb, "INFO/nextjob");
889 * If the printer is marked as postscript output a leading
890 * file identifier to ensure the file is treated as a raw
892 * This has a similar effect as CtrlD=0 in WIN.INI file.
893 * tim@fsg.com 09/06/94
895 if (lp_postscript(snum)) {
896 print_job_write(jobid, "%!\n",3);
903 tdb_delete(tdb, print_key(jobid));
906 tdb_unlock_bystring(tdb, "INFO/nextjob");
910 /****************************************************************************
911 Print a file - called on closing the file. This spools the job.
912 ****************************************************************************/
914 BOOL print_job_end(int jobid)
916 struct printjob *pjob = print_job_find(jobid);
918 SMB_STRUCT_STAT sbuf;
919 pstring current_directory;
920 pstring print_directory;
927 if (pjob->spooled || pjob->pid != local_pid)
930 snum = print_job_snum(jobid);
932 if (sys_fstat(pjob->fd, &sbuf) == 0) {
933 pjob->size = sbuf.st_size;
937 /* Couldn't stat the job file, so something has gone wrong. Cleanup */
938 unlink(pjob->filename);
939 tdb_delete(tdb, print_key(jobid));
943 if (pjob->size == 0) {
944 /* don't bother spooling empty files */
945 unlink(pjob->filename);
946 tdb_delete(tdb, print_key(jobid));
950 /* we print from the directory path to give the best chance of
951 parsing the lpq output */
952 wd = sys_getwd(current_directory);
956 pstrcpy(print_directory, pjob->filename);
957 p = strrchr(print_directory,'/');
962 if (chdir(print_directory) != 0)
965 pstrcpy(jobname, pjob->jobname);
966 pstring_sub(jobname, "'", "_");
968 /* send it to the system spooler */
969 ret = print_run_command(snum,
970 lp_printcommand(snum), NULL,
979 /* The print job has been sucessfully handed over to the back-end */
981 pjob->spooled = True;
982 print_job_store(jobid, pjob);
984 /* make sure the database is up to date */
985 if (print_cache_expired(snum)) print_queue_update(snum);
989 /* The print job was not succesfully started. Cleanup */
990 /* Still need to add proper error return propagation! 010122:JRR */
991 unlink(pjob->filename);
992 tdb_delete(tdb, print_key(jobid));
997 /* utility fn to enumerate the print queue */
998 static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1000 struct traverse_struct *ts = (struct traverse_struct *)state;
1001 struct printjob pjob;
1004 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1005 memcpy(&jobid, key.dptr, sizeof(jobid));
1006 memcpy(&pjob, data.dptr, sizeof(pjob));
1008 /* maybe it isn't for this queue */
1009 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1011 if (ts->qcount >= ts->maxcount) return 0;
1015 ts->queue[i].job = jobid;
1016 ts->queue[i].size = pjob.size;
1017 ts->queue[i].status = pjob.status;
1018 ts->queue[i].priority = 1;
1019 ts->queue[i].time = pjob.starttime;
1020 fstrcpy(ts->queue[i].user, pjob.user);
1021 fstrcpy(ts->queue[i].file, pjob.jobname);
1028 struct traverse_count_struct {
1032 /* utility fn to count the number of entries in the print queue */
1033 static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1035 struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
1036 struct printjob pjob;
1039 if (data.dsize != sizeof(pjob) || key.dsize != sizeof(int)) return 0;
1040 memcpy(&jobid, key.dptr, sizeof(jobid));
1041 memcpy(&pjob, data.dptr, sizeof(pjob));
1043 /* maybe it isn't for this queue */
1044 if (ts->snum != print_queue_snum(pjob.qname)) return 0;
1051 /* Sort print jobs by submittal time */
1053 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1057 if (!j1 && !j2) return 0;
1061 /* Sort on job start time */
1063 if (j1->time == j2->time) return 0;
1064 return (j1->time > j2->time) ? 1 : -1;
1067 /****************************************************************************
1068 get a printer queue listing
1069 ****************************************************************************/
1070 int print_queue_status(int snum,
1071 print_queue_struct **queue,
1072 print_status_struct *status)
1074 struct traverse_struct tstruct;
1075 struct traverse_count_struct tsc;
1079 /* make sure the database is up to date */
1080 if (print_cache_expired(snum)) print_queue_update(snum);
1085 * Fetch the queue status. We must do this first, as there may
1086 * be no jobs in the queue.
1088 ZERO_STRUCTP(status);
1089 slprintf(keystr, sizeof(keystr), "STATUS/%s", lp_servicename(snum));
1090 dos_to_unix(keystr, True); /* Convert key to unix-codepage */
1092 key.dsize = strlen(keystr);
1093 data = tdb_fetch(tdb, key);
1095 if (data.dsize == sizeof(*status)) {
1096 memcpy(status, data.dptr, sizeof(*status));
1102 * Now, fetch the print queue information. We first count the number
1103 * of entries, and then only retrieve the queue if necessary.
1108 tdb_traverse(tdb, traverse_count_fn_queue, (void *)&tsc);
1113 /* Allocate the queue size. */
1114 if ((tstruct.queue = (print_queue_struct *)
1115 malloc(sizeof(print_queue_struct)*tsc.count))
1120 * Fill in the queue.
1121 * We need maxcount as the queue size may have changed between
1122 * the two calls to tdb_traverse.
1125 tstruct.maxcount = tsc.count;
1126 tstruct.snum = snum;
1128 tdb_traverse(tdb, traverse_fn_queue, (void *)&tstruct);
1130 /* Sort the queue by submission time otherwise they are displayed
1133 qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
1134 QSORT_CAST(printjob_comp));
1136 *queue = tstruct.queue;
1137 return tstruct.qcount;
1141 /****************************************************************************
1142 turn a queue name into a snum
1143 ****************************************************************************/
1144 int print_queue_snum(char *qname)
1146 int snum = lp_servicenumber(qname);
1147 if (snum == -1 || !lp_print_ok(snum)) return -1;
1152 /****************************************************************************
1154 ****************************************************************************/
1155 BOOL print_queue_pause(struct current_user *user, int snum, int *errcode)
1160 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1161 *errcode = ERROR_ACCESS_DENIED;
1165 ret = print_run_command(snum, lp_queuepausecommand(snum), NULL,
1169 *errcode = ERROR_INVALID_PARAMETER;
1173 /* force update the database */
1174 print_cache_flush(snum);
1176 /* Send a printer notify message */
1178 printer_name = PRINTERNAME(snum);
1180 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1185 /****************************************************************************
1187 ****************************************************************************/
1188 BOOL print_queue_resume(struct current_user *user, int snum, int *errcode)
1193 if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
1194 *errcode = ERROR_ACCESS_DENIED;
1198 ret = print_run_command(snum, lp_queueresumecommand(snum), NULL,
1202 *errcode = ERROR_INVALID_PARAMETER;
1206 /* make sure the database is up to date */
1207 if (print_cache_expired(snum)) print_queue_update(snum);
1209 /* Send a printer notify message */
1211 printer_name = PRINTERNAME(snum);
1213 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);
1218 /****************************************************************************
1219 purge a queue - implemented by deleting all jobs that we can delete
1220 ****************************************************************************/
1221 BOOL print_queue_purge(struct current_user *user, int snum, int *errcode)
1223 print_queue_struct *queue;
1224 print_status_struct status;
1229 can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
1230 njobs = print_queue_status(snum, &queue, &status);
1232 for (i=0;i<njobs;i++) {
1233 BOOL owner = is_owner(user, queue[i].job);
1235 if (owner || can_job_admin) {
1236 print_job_delete1(queue[i].job);
1240 print_queue_update(snum);
1243 /* Send a printer notify message */
1245 printer_name = PRINTERNAME(snum);
1247 message_send_all(conn_tdb_ctx(),MSG_PRINTER_NOTIFY, printer_name, strlen(printer_name) + 1, False);