2
Unix SMB/Netbios implementation.
4
printing backend routines
5
Copyright (C) Andrew Tridgell 1992-2000
6
Copyright (C) Jeremy Allison 2002
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 3 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, see <http://www.gnu.org/licenses/>.
25
extern struct current_user current_user;
26
extern userdom_struct current_user_info;
28
/* Current printer interface */
29
static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
32
the printing backend revolves around a tdb database that stores the
33
SMB view of the print queue
35
The key for this database is a jobid - a internally generated number that
36
uniquely identifies a print job
38
reading the print queue involves two steps:
39
- possibly running lpq and updating the internal database from that
40
- reading entries from the database
42
jobids are assigned when a job starts spooling.
45
static TDB_CONTEXT *rap_tdb;
46
static uint16 next_rap_jobid;
47
struct rap_jobid_key {
52
/***************************************************************************
53
Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
54
bit RPC jobids.... JRA.
55
***************************************************************************/
57
uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
61
struct rap_jobid_key jinfo;
64
DEBUG(10,("pjobid_to_rap: called.\n"));
67
/* Create the in-memory tdb. */
68
rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
74
fstrcpy( jinfo.sharename, sharename );
76
key.dptr = (uint8 *)&jinfo;
77
key.dsize = sizeof(jinfo);
79
data = tdb_fetch(rap_tdb, key);
80
if (data.dptr && data.dsize == sizeof(uint16)) {
81
rap_jobid = SVAL(data.dptr, 0);
83
DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
84
(unsigned int)jobid, (unsigned int)rap_jobid));
88
/* Not found - create and store mapping. */
89
rap_jobid = ++next_rap_jobid;
91
rap_jobid = ++next_rap_jobid;
92
SSVAL(buf,0,rap_jobid);
94
data.dsize = sizeof(rap_jobid);
95
tdb_store(rap_tdb, key, data, TDB_REPLACE);
96
tdb_store(rap_tdb, data, key, TDB_REPLACE);
98
DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
99
(unsigned int)jobid, (unsigned int)rap_jobid));
103
bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
108
DEBUG(10,("rap_to_pjobid called.\n"));
113
SSVAL(buf,0,rap_jobid);
115
key.dsize = sizeof(rap_jobid);
116
data = tdb_fetch(rap_tdb, key);
117
if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
119
struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
120
if (sharename != NULL) {
121
fstrcpy( sharename, jinfo->sharename );
123
*pjobid = jinfo->jobid;
124
DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
125
(unsigned int)*pjobid, (unsigned int)rap_jobid));
126
SAFE_FREE(data.dptr);
130
DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
131
(unsigned int)rap_jobid));
132
SAFE_FREE(data.dptr);
136
static void rap_jobid_delete(const char* sharename, uint32 jobid)
140
struct rap_jobid_key jinfo;
143
DEBUG(10,("rap_jobid_delete: called.\n"));
148
ZERO_STRUCT( jinfo );
149
fstrcpy( jinfo.sharename, sharename );
151
key.dptr = (uint8 *)&jinfo;
152
key.dsize = sizeof(jinfo);
154
data = tdb_fetch(rap_tdb, key);
155
if (!data.dptr || (data.dsize != sizeof(uint16))) {
156
DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
157
(unsigned int)jobid ));
158
SAFE_FREE(data.dptr);
162
DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
163
(unsigned int)jobid ));
165
rap_jobid = SVAL(data.dptr, 0);
166
SAFE_FREE(data.dptr);
167
SSVAL(buf,0,rap_jobid);
169
data.dsize = sizeof(rap_jobid);
170
tdb_delete(rap_tdb, key);
171
tdb_delete(rap_tdb, data);
174
static int get_queue_status(const char* sharename, print_status_struct *);
176
/****************************************************************************
177
Initialise the printing backend. Called once at startup before the fork().
178
****************************************************************************/
180
bool print_backend_init(struct messaging_context *msg_ctx)
182
const char *sversion = "INFO/version";
183
int services = lp_numservices();
186
unlink(cache_path("printing.tdb"));
187
mkdir(cache_path("printing"),0755);
189
/* handle a Samba upgrade */
191
for (snum = 0; snum < services; snum++) {
192
struct tdb_print_db *pdb;
193
if (!lp_print_ok(snum))
196
pdb = get_print_db_byname(lp_const_servicename(snum));
199
if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
200
DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
201
release_print_db(pdb);
204
if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
205
tdb_wipe_all(pdb->tdb);
206
tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
208
tdb_unlock_bystring(pdb->tdb, sversion);
209
release_print_db(pdb);
212
close_all_print_db(); /* Don't leave any open. */
214
/* do NT print initialization... */
215
return nt_printing_init(msg_ctx);
218
/****************************************************************************
219
Shut down printing backend. Called once at shutdown to close the tdb.
220
****************************************************************************/
222
void printing_end(void)
224
close_all_print_db(); /* Don't leave any open. */
227
/****************************************************************************
228
Retrieve the set of printing functions for a given service. This allows
229
us to set the printer function table based on the value of the 'printing'
232
Use the generic interface as the default and only use cups interface only
233
when asked for (and only when supported)
234
****************************************************************************/
236
static struct printif *get_printer_fns_from_type( enum printing_types type )
238
struct printif *printer_fns = &generic_printif;
241
if ( type == PRINT_CUPS ) {
242
printer_fns = &cups_printif;
244
#endif /* HAVE_CUPS */
247
if ( type == PRINT_IPRINT ) {
248
printer_fns = &iprint_printif;
250
#endif /* HAVE_IPRINT */
252
printer_fns->type = type;
257
static struct printif *get_printer_fns( int snum )
259
return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
263
/****************************************************************************
264
Useful function to generate a tdb key.
265
****************************************************************************/
267
static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
271
SIVAL(tmp, 0, jobid);
272
ret.dptr = (uint8 *)tmp;
273
ret.dsize = sizeof(*tmp);
277
/***********************************************************************
278
unpack a pjob from a tdb buffer
279
***********************************************************************/
281
int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
285
uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
286
uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
291
len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
309
if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
315
pjob->sysjob = pjsysjob;
317
pjob->starttime = pjstarttime;
318
pjob->status = pjstatus;
320
pjob->page_count = pjpage_count;
321
pjob->spooled = pjspooled;
322
pjob->smbjob = pjsmbjob;
328
/****************************************************************************
329
Useful function to find a print job in the database.
330
****************************************************************************/
332
static struct printjob *print_job_find(const char *sharename, uint32 jobid)
334
static struct printjob pjob;
337
struct tdb_print_db *pdb = get_print_db_byname(sharename);
339
DEBUG(10,("print_job_find: looking up job %u for share %s\n",
340
(unsigned int)jobid, sharename ));
346
ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
347
release_print_db(pdb);
350
DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
354
if ( pjob.nt_devmode ) {
355
free_nt_devicemode( &pjob.nt_devmode );
360
if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
361
DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
368
DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
369
(int)pjob.sysjob, (unsigned int)jobid ));
374
/* Convert a unix jobid to a smb jobid */
376
struct unixjob_traverse_state {
378
uint32 sysjob_to_jobid_value;
381
static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
382
TDB_DATA data, void *private_data)
384
struct printjob *pjob;
385
struct unixjob_traverse_state *state =
386
(struct unixjob_traverse_state *)private_data;
388
if (!data.dptr || data.dsize == 0)
391
pjob = (struct printjob *)data.dptr;
392
if (key.dsize != sizeof(uint32))
395
if (state->sysjob == pjob->sysjob) {
396
uint32 jobid = IVAL(key.dptr,0);
398
state->sysjob_to_jobid_value = jobid;
405
/****************************************************************************
406
This is a *horribly expensive call as we have to iterate through all the
407
current printer tdb's. Don't do this often ! JRA.
408
****************************************************************************/
410
uint32 sysjob_to_jobid(int unix_jobid)
412
int services = lp_numservices();
414
struct unixjob_traverse_state state;
416
state.sysjob = unix_jobid;
417
state.sysjob_to_jobid_value = (uint32)-1;
419
for (snum = 0; snum < services; snum++) {
420
struct tdb_print_db *pdb;
421
if (!lp_print_ok(snum))
423
pdb = get_print_db_byname(lp_const_servicename(snum));
427
tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
428
release_print_db(pdb);
429
if (state.sysjob_to_jobid_value != (uint32)-1)
430
return state.sysjob_to_jobid_value;
435
/****************************************************************************
436
Send notifications based on what has changed after a pjob_store.
437
****************************************************************************/
439
static const struct {
441
uint32 spoolss_status;
442
} lpq_to_spoolss_status_map[] = {
443
{ LPQ_QUEUED, JOB_STATUS_QUEUED },
444
{ LPQ_PAUSED, JOB_STATUS_PAUSED },
445
{ LPQ_SPOOLING, JOB_STATUS_SPOOLING },
446
{ LPQ_PRINTING, JOB_STATUS_PRINTING },
447
{ LPQ_DELETING, JOB_STATUS_DELETING },
448
{ LPQ_OFFLINE, JOB_STATUS_OFFLINE },
449
{ LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
450
{ LPQ_PRINTED, JOB_STATUS_PRINTED },
451
{ LPQ_DELETED, JOB_STATUS_DELETED },
452
{ LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
453
{ LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
457
/* Convert a lpq status value stored in printing.tdb into the
458
appropriate win32 API constant. */
460
static uint32 map_to_spoolss_status(uint32 lpq_status)
464
while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
465
if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
466
return lpq_to_spoolss_status_map[i].spoolss_status;
473
static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
474
struct printjob *new_data)
476
bool new_job = False;
481
/* Job attributes that can't be changed. We only send
482
notification for these on a new job. */
484
/* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
485
NOTIFY_INFO_DATA buffer, we *have* to send the job submission
486
time first or else we'll end up with potential alignment
487
errors. I don't think the systemtime should be spooled as
488
a string, but this gets us around that error.
489
--jerry (i'll feel dirty for this) */
492
notify_job_submitted(sharename, jobid, new_data->starttime);
493
notify_job_username(sharename, jobid, new_data->user);
496
if (new_job || !strequal(old_data->jobname, new_data->jobname))
497
notify_job_name(sharename, jobid, new_data->jobname);
499
/* Job attributes of a new job or attributes that can be
502
if (new_job || !strequal(old_data->jobname, new_data->jobname))
503
notify_job_name(sharename, jobid, new_data->jobname);
505
if (new_job || old_data->status != new_data->status)
506
notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
508
if (new_job || old_data->size != new_data->size)
509
notify_job_total_bytes(sharename, jobid, new_data->size);
511
if (new_job || old_data->page_count != new_data->page_count)
512
notify_job_total_pages(sharename, jobid, new_data->page_count);
515
/****************************************************************************
516
Store a job structure back to the database.
517
****************************************************************************/
519
static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
522
TDB_DATA old_data, new_data;
524
struct tdb_print_db *pdb = get_print_db_byname(sharename);
526
int len, newlen, buflen;
534
old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
536
/* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
543
len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
545
(uint32)pjob->sysjob,
547
(uint32)pjob->starttime,
548
(uint32)pjob->status,
550
(uint32)pjob->page_count,
551
(uint32)pjob->spooled,
552
(uint32)pjob->smbjob,
558
len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
561
buf = (uint8 *)SMB_REALLOC(buf, len);
563
DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
568
} while ( buflen != len );
574
new_data.dsize = len;
575
ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
578
release_print_db(pdb);
580
/* Send notify updates for what has changed */
583
struct printjob old_pjob;
585
if ( old_data.dsize )
587
if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
589
pjob_store_notify( sharename, jobid, &old_pjob , pjob );
590
free_nt_devicemode( &old_pjob.nt_devmode );
595
pjob_store_notify( sharename, jobid, NULL, pjob );
600
SAFE_FREE( old_data.dptr );
606
/****************************************************************************
607
Remove a job structure from the database.
608
****************************************************************************/
610
void pjob_delete(const char* sharename, uint32 jobid)
613
struct printjob *pjob;
614
uint32 job_status = 0;
615
struct tdb_print_db *pdb;
617
pdb = get_print_db_byname( sharename );
622
pjob = print_job_find( sharename, jobid );
625
DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
626
(unsigned int)jobid));
627
release_print_db(pdb);
631
/* We must cycle through JOB_STATUS_DELETING and
632
JOB_STATUS_DELETED for the port monitor to delete the job
635
job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
636
notify_job_status(sharename, jobid, job_status);
638
/* Remove from printing.tdb */
640
tdb_delete(pdb->tdb, print_key(jobid, &tmp));
641
remove_from_jobs_changed(sharename, jobid);
642
release_print_db( pdb );
643
rap_jobid_delete(sharename, jobid);
646
/****************************************************************************
647
List a unix job in the print database.
648
****************************************************************************/
650
static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
652
struct printjob pj, *old_pj;
654
if (jobid == (uint32)-1)
655
jobid = q->job + UNIX_JOB_START;
657
/* Preserve the timestamp on an existing unix print job */
659
old_pj = print_job_find(sharename, jobid);
666
pj.starttime = old_pj ? old_pj->starttime : q->time;
667
pj.status = q->status;
670
fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
671
if (jobid < UNIX_JOB_START) {
673
fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
676
fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
678
fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
679
fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
681
pjob_store(sharename, jobid, &pj);
685
struct traverse_struct {
686
print_queue_struct *queue;
687
int qcount, snum, maxcount, total_jobs;
688
const char *sharename;
690
const char *lprm_command;
691
struct printif *print_if;
694
/****************************************************************************
695
Utility fn to delete any jobs that are no longer active.
696
****************************************************************************/
698
static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
700
struct traverse_struct *ts = (struct traverse_struct *)state;
701
struct printjob pjob;
705
if ( key.dsize != sizeof(jobid) )
708
jobid = IVAL(key.dptr, 0);
709
if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
711
free_nt_devicemode( &pjob.nt_devmode );
715
/* remove a unix job if it isn't in the system queue any more */
717
for (i=0;i<ts->qcount;i++) {
718
uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
719
if (jobid == u_jobid)
722
if (i == ts->qcount) {
723
DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
724
(unsigned int)jobid ));
725
pjob_delete(ts->sharename, jobid);
729
/* need to continue the the bottom of the function to
730
save the correct attributes */
733
/* maybe it hasn't been spooled yet */
735
/* if a job is not spooled and the process doesn't
736
exist then kill it. This cleans up after smbd
738
if (!process_exists_by_pid(pjob.pid)) {
739
DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
740
(unsigned int)jobid, (unsigned int)pjob.pid ));
741
pjob_delete(ts->sharename, jobid);
747
/* this check only makes sense for jobs submitted from Windows clients */
750
for (i=0;i<ts->qcount;i++) {
753
if ( pjob.status == LPQ_DELETED )
756
curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
758
if (jobid == curr_jobid) {
760
/* try to clean up any jobs that need to be deleted */
762
if ( pjob.status == LPQ_DELETING ) {
765
result = (*(ts->print_if->job_delete))(
766
ts->sharename, ts->lprm_command, &pjob );
769
/* if we can't delete, then reset the job status */
770
pjob.status = LPQ_QUEUED;
771
pjob_store(ts->sharename, jobid, &pjob);
774
/* if we deleted the job, the remove the tdb record */
775
pjob_delete(ts->sharename, jobid);
776
pjob.status = LPQ_DELETED;
786
/* The job isn't in the system queue - we have to assume it has
787
completed, so delete the database entry. */
789
if (i == ts->qcount) {
791
/* A race can occur between the time a job is spooled and
792
when it appears in the lpq output. This happens when
793
the job is added to printing.tdb when another smbd
794
running print_queue_update() has completed a lpq and
795
is currently traversing the printing tdb and deleting jobs.
796
Don't delete the job if it was submitted after the lpq_time. */
798
if (pjob.starttime < ts->lpq_time) {
799
DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
801
(unsigned int)pjob.starttime,
802
(unsigned int)ts->lpq_time ));
803
pjob_delete(ts->sharename, jobid);
809
/* Save the pjob attributes we will store.
810
FIXME!!! This is the only place where queue->job
811
represents the SMB jobid --jerry */
813
ts->queue[i].job = jobid;
814
ts->queue[i].size = pjob.size;
815
ts->queue[i].page_count = pjob.page_count;
816
ts->queue[i].status = pjob.status;
817
ts->queue[i].priority = 1;
818
ts->queue[i].time = pjob.starttime;
819
fstrcpy(ts->queue[i].fs_user, pjob.user);
820
fstrcpy(ts->queue[i].fs_file, pjob.jobname);
827
/****************************************************************************
828
Check if the print queue has been updated recently enough.
829
****************************************************************************/
831
static void print_cache_flush(const char *sharename)
834
struct tdb_print_db *pdb = get_print_db_byname(sharename);
838
slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
839
tdb_store_int32(pdb->tdb, key, -1);
840
release_print_db(pdb);
843
/****************************************************************************
844
Check if someone already thinks they are doing the update.
845
****************************************************************************/
847
static pid_t get_updating_pid(const char *sharename)
852
struct tdb_print_db *pdb = get_print_db_byname(sharename);
856
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
857
key = string_tdb_data(keystr);
859
data = tdb_fetch(pdb->tdb, key);
860
release_print_db(pdb);
861
if (!data.dptr || data.dsize != sizeof(pid_t)) {
862
SAFE_FREE(data.dptr);
866
updating_pid = IVAL(data.dptr, 0);
867
SAFE_FREE(data.dptr);
869
if (process_exists_by_pid(updating_pid))
875
/****************************************************************************
876
Set the fact that we're doing the update, or have finished doing the update
878
****************************************************************************/
880
static void set_updating_pid(const fstring sharename, bool updating)
885
pid_t updating_pid = sys_getpid();
888
struct tdb_print_db *pdb = get_print_db_byname(sharename);
893
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
894
key = string_tdb_data(keystr);
896
DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
897
updating ? "" : "not ",
901
tdb_delete(pdb->tdb, key);
902
release_print_db(pdb);
906
SIVAL( buffer, 0, updating_pid);
908
data.dsize = 4; /* we always assume this is a 4 byte value */
910
tdb_store(pdb->tdb, key, data, TDB_REPLACE);
911
release_print_db(pdb);
914
/****************************************************************************
915
Sort print jobs by submittal time.
916
****************************************************************************/
918
static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
929
/* Sort on job start time */
931
if (j1->time == j2->time)
933
return (j1->time > j2->time) ? 1 : -1;
936
/****************************************************************************
937
Store the sorted queue representation for later portmon retrieval.
939
****************************************************************************/
941
static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
944
int max_reported_jobs = lp_max_reported_jobs(pts->snum);
945
print_queue_struct *queue = pts->queue;
950
if (max_reported_jobs && (max_reported_jobs < pts->qcount))
951
pts->qcount = max_reported_jobs;
954
/* Work out the size. */
956
data.dsize += tdb_pack(NULL, 0, "d", qcount);
958
for (i = 0; i < pts->qcount; i++) {
959
if ( queue[i].status == LPQ_DELETED )
963
data.dsize += tdb_pack(NULL, 0, "ddddddff",
964
(uint32)queue[i].job,
965
(uint32)queue[i].size,
966
(uint32)queue[i].page_count,
967
(uint32)queue[i].status,
968
(uint32)queue[i].priority,
969
(uint32)queue[i].time,
974
if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
978
len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
979
for (i = 0; i < pts->qcount; i++) {
980
if ( queue[i].status == LPQ_DELETED )
983
len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
984
(uint32)queue[i].job,
985
(uint32)queue[i].size,
986
(uint32)queue[i].page_count,
987
(uint32)queue[i].status,
988
(uint32)queue[i].priority,
989
(uint32)queue[i].time,
994
tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
996
SAFE_FREE(data.dptr);
1000
static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1006
data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1007
if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1008
SAFE_FREE(data.dptr);
1015
static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1018
unsigned int job_count = data.dsize / 4;
1020
for (i = 0; i < job_count; i++) {
1023
ch_jobid = IVAL(data.dptr, i*4);
1024
if (ch_jobid == jobid)
1025
remove_from_jobs_changed(sharename, jobid);
1029
/****************************************************************************
1030
Check if the print queue has been updated recently enough.
1031
****************************************************************************/
1033
static bool print_cache_expired(const char *sharename, bool check_pending)
1036
time_t last_qscan_time, time_now = time(NULL);
1037
struct tdb_print_db *pdb = get_print_db_byname(sharename);
1038
bool result = False;
1043
snprintf(key, sizeof(key), "CACHE/%s", sharename);
1044
last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1047
* Invalidate the queue for 3 reasons.
1048
* (1). last queue scan time == -1.
1049
* (2). Current time - last queue scan time > allowed cache time.
1050
* (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1051
* This last test picks up machines for which the clock has been moved
1052
* forward, an lpq scan done and then the clock moved back. Otherwise
1053
* that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1056
if (last_qscan_time == ((time_t)-1)
1057
|| (time_now - last_qscan_time) >= lp_lpqcachetime()
1058
|| last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1061
time_t msg_pending_time;
1063
DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1064
"(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1065
sharename, (int)last_qscan_time, (int)time_now,
1066
(int)lp_lpqcachetime() ));
1068
/* check if another smbd has already sent a message to update the
1069
queue. Give the pending message one minute to clear and
1070
then send another message anyways. Make sure to check for
1071
clocks that have been run forward and then back again. */
1073
snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1076
&& tdb_fetch_uint32( pdb->tdb, key, &u )
1077
&& (msg_pending_time=u) > 0
1078
&& msg_pending_time <= time_now
1079
&& (time_now - msg_pending_time) < 60 )
1081
DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1090
release_print_db(pdb);
1094
/****************************************************************************
1095
main work for updating the lpq cahe for a printer queue
1096
****************************************************************************/
1098
static void print_queue_update_internal( const char *sharename,
1099
struct printif *current_printif,
1100
char *lpq_command, char *lprm_command )
1103
print_queue_struct *queue = NULL;
1104
print_status_struct status;
1105
print_status_struct old_status;
1106
struct printjob *pjob;
1107
struct traverse_struct tstruct;
1110
fstring keystr, cachestr;
1111
struct tdb_print_db *pdb = get_print_db_byname(sharename);
1117
DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1118
sharename, current_printif->type, lpq_command));
1121
* Update the cache time FIRST ! Stops others even
1122
* attempting to get the lock and doing this
1123
* if the lpq takes a long time.
1126
slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1127
tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1129
/* get the current queue using the appropriate interface */
1130
ZERO_STRUCT(status);
1132
qcount = (*(current_printif->queue_get))(sharename,
1133
current_printif->type,
1134
lpq_command, &queue, &status);
1136
DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1137
qcount, (qcount != 1) ? "s" : "", sharename));
1139
/* Sort the queue by submission time otherwise they are displayed
1142
qsort(queue, qcount, sizeof(print_queue_struct),
1143
QSORT_CAST(printjob_comp));
1146
any job in the internal database that is marked as spooled
1147
and doesn't exist in the system queue is considered finished
1148
and removed from the database
1150
any job in the system database but not in the internal database
1151
is added as a unix job
1153
fill in any system job numbers as we go
1156
jcdata = get_jobs_changed_data(pdb);
1158
for (i=0; i<qcount; i++) {
1159
uint32 jobid = print_parse_jobid(queue[i].fs_file);
1161
if (jobid == (uint32)-1) {
1162
/* assume its a unix print job */
1163
print_unix_job(sharename, &queue[i], jobid);
1167
/* we have an active SMB print job - update its status */
1168
pjob = print_job_find(sharename, jobid);
1170
/* err, somethings wrong. Probably smbd was restarted
1171
with jobs in the queue. All we can do is treat them
1172
like unix jobs. Pity. */
1173
print_unix_job(sharename, &queue[i], jobid);
1177
pjob->sysjob = queue[i].job;
1179
/* don't reset the status on jobs to be deleted */
1181
if ( pjob->status != LPQ_DELETING )
1182
pjob->status = queue[i].status;
1184
pjob_store(sharename, jobid, pjob);
1186
check_job_changed(sharename, jcdata, jobid);
1189
SAFE_FREE(jcdata.dptr);
1191
/* now delete any queued entries that don't appear in the
1193
tstruct.queue = queue;
1194
tstruct.qcount = qcount;
1196
tstruct.total_jobs = 0;
1197
tstruct.lpq_time = time(NULL);
1198
tstruct.sharename = sharename;
1199
tstruct.lprm_command = lprm_command;
1200
tstruct.print_if = current_printif;
1202
tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1204
/* Store the linearised queue, max jobs only. */
1205
store_queue_struct(pdb, &tstruct);
1207
SAFE_FREE(tstruct.queue);
1209
DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1210
sharename, tstruct.total_jobs ));
1212
tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1214
get_queue_status(sharename, &old_status);
1215
if (old_status.qcount != qcount)
1216
DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1217
old_status.qcount, qcount, sharename));
1219
/* store the new queue status structure */
1220
slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1221
key = string_tdb_data(keystr);
1223
status.qcount = qcount;
1224
data.dptr = (uint8 *)&status;
1225
data.dsize = sizeof(status);
1226
tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1229
* Update the cache time again. We want to do this call
1230
* as little as possible...
1233
slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1234
tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1236
/* clear the msg pending record for this queue */
1238
snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1240
if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1241
/* log a message but continue on */
1243
DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1247
release_print_db( pdb );
1252
/****************************************************************************
1253
Update the internal database from the system print queue for a queue.
1254
obtain a lock on the print queue before proceeding (needed when mutiple
1255
smbd processes maytry to update the lpq cache concurrently).
1256
****************************************************************************/
1258
static void print_queue_update_with_lock( const char *sharename,
1259
struct printif *current_printif,
1260
char *lpq_command, char *lprm_command )
1263
struct tdb_print_db *pdb;
1265
DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1266
pdb = get_print_db_byname(sharename);
1270
if ( !print_cache_expired(sharename, False) ) {
1271
DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1272
release_print_db(pdb);
1277
* Check to see if someone else is doing this update.
1278
* This is essentially a mutex on the update.
1281
if (get_updating_pid(sharename) != -1) {
1282
release_print_db(pdb);
1286
/* Lock the queue for the database update */
1288
slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1289
/* Only wait 10 seconds for this. */
1290
if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1291
DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1292
release_print_db(pdb);
1297
* Ensure that no one else got in here.
1298
* If the updating pid is still -1 then we are
1302
if (get_updating_pid(sharename) != -1) {
1304
* Someone else is doing the update, exit.
1306
tdb_unlock_bystring(pdb->tdb, keystr);
1307
release_print_db(pdb);
1312
* We're going to do the update ourselves.
1315
/* Tell others we're doing the update. */
1316
set_updating_pid(sharename, True);
1319
* Allow others to enter and notice we're doing
1323
tdb_unlock_bystring(pdb->tdb, keystr);
1325
/* do the main work now */
1327
print_queue_update_internal( sharename, current_printif,
1328
lpq_command, lprm_command );
1330
/* Delete our pid from the db. */
1331
set_updating_pid(sharename, False);
1332
release_print_db(pdb);
1335
/****************************************************************************
1336
this is the receive function of the background lpq updater
1337
****************************************************************************/
1338
static void print_queue_receive(struct messaging_context *msg,
1341
struct server_id server_id,
1345
char *lpqcommand = NULL, *lprmcommand = NULL;
1349
len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1356
SAFE_FREE(lpqcommand);
1357
SAFE_FREE(lprmcommand);
1358
DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1362
print_queue_update_with_lock(sharename,
1363
get_printer_fns_from_type((enum printing_types)printing_type),
1364
lpqcommand, lprmcommand );
1366
SAFE_FREE(lpqcommand);
1367
SAFE_FREE(lprmcommand);
1371
static void printing_pause_fd_handler(struct tevent_context *ev,
1372
struct tevent_fd *fde,
1377
* If pause_pipe[1] is closed it means the parent smbd
1378
* and children exited or aborted.
1380
exit_server_cleanly(NULL);
1383
static pid_t background_lpq_updater_pid = -1;
1385
/****************************************************************************
1386
main thread of the background lpq updater
1387
****************************************************************************/
1388
void start_background_queue(void)
1390
/* Use local variables for this as we don't
1391
* need to save the parent side of this, just
1392
* ensure it closes when the process exits.
1396
DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1398
if (pipe(pause_pipe) == -1) {
1399
DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1403
background_lpq_updater_pid = sys_fork();
1405
if (background_lpq_updater_pid == -1) {
1406
DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1410
if(background_lpq_updater_pid == 0) {
1411
struct tevent_fd *fde;
1415
DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1417
close(pause_pipe[0]);
1420
if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
1421
smbd_event_context(),
1423
DEBUG(0,("reinit_after_fork() failed\n"));
1424
smb_panic("reinit_after_fork() failed");
1427
smbd_setup_sig_term_handler();
1428
smbd_setup_sig_hup_handler();
1430
claim_connection( NULL, "smbd lpq backend",
1431
FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1433
if (!locking_init()) {
1437
messaging_register(smbd_messaging_context(), NULL,
1438
MSG_PRINTER_UPDATE, print_queue_receive);
1440
fde = tevent_add_fd(smbd_event_context(), smbd_event_context(),
1441
pause_pipe[1], TEVENT_FD_READ,
1442
printing_pause_fd_handler,
1445
DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1446
smb_panic("tevent_add_fd() failed for pause_pipe");
1449
DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1450
ret = tevent_loop_wait(smbd_event_context());
1451
/* should not be reached */
1452
DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1453
ret, (ret == 0) ? "out of events" : strerror(errno)));
1457
close(pause_pipe[1]);
1460
/****************************************************************************
1461
update the internal database from the system print queue for a queue
1462
****************************************************************************/
1464
static void print_queue_update(int snum, bool force)
1468
char *lpqcommand = NULL;
1469
char *lprmcommand = NULL;
1470
uint8 *buffer = NULL;
1473
struct tdb_print_db *pdb;
1475
struct printif *current_printif;
1476
TALLOC_CTX *ctx = talloc_tos();
1478
fstrcpy( sharename, lp_const_servicename(snum));
1480
/* don't strip out characters like '$' from the printername */
1482
lpqcommand = talloc_string_sub2(ctx,
1483
lp_lpqcommand(snum),
1486
false, false, false);
1490
lpqcommand = talloc_sub_advanced(ctx,
1491
lp_servicename(snum),
1492
current_user_info.unix_name,
1494
current_user.ut.gid,
1495
get_current_username(),
1496
current_user_info.domain,
1502
lprmcommand = talloc_string_sub2(ctx,
1503
lp_lprmcommand(snum),
1506
false, false, false);
1510
lprmcommand = talloc_sub_advanced(ctx,
1511
lp_servicename(snum),
1512
current_user_info.unix_name,
1514
current_user.ut.gid,
1515
get_current_username(),
1516
current_user_info.domain,
1523
* Make sure that the background queue process exists.
1524
* Otherwise just do the update ourselves
1527
if ( force || background_lpq_updater_pid == -1 ) {
1528
DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1529
current_printif = get_printer_fns( snum );
1530
print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1535
type = lp_printing(snum);
1537
/* get the length */
1539
len = tdb_pack( NULL, 0, "fdPP",
1545
buffer = SMB_XMALLOC_ARRAY( uint8, len );
1547
/* now pack the buffer */
1548
newlen = tdb_pack( buffer, len, "fdPP",
1554
SMB_ASSERT( newlen == len );
1556
DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1557
"type = %d, lpq command = [%s] lprm command = [%s]\n",
1558
sharename, type, lpqcommand, lprmcommand ));
1560
/* here we set a msg pending record for other smbd processes
1561
to throttle the number of duplicate print_queue_update msgs
1564
pdb = get_print_db_byname(sharename);
1570
snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1572
if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1573
/* log a message but continue on */
1575
DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1579
release_print_db( pdb );
1581
/* finally send the message */
1583
messaging_send_buf(smbd_messaging_context(),
1584
pid_to_procid(background_lpq_updater_pid),
1585
MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1587
SAFE_FREE( buffer );
1592
/****************************************************************************
1593
Create/Update an entry in the print tdb that will allow us to send notify
1594
updates only to interested smbd's.
1595
****************************************************************************/
1597
bool print_notify_register_pid(int snum)
1600
struct tdb_print_db *pdb = NULL;
1601
TDB_CONTEXT *tdb = NULL;
1602
const char *printername;
1603
uint32 mypid = (uint32)sys_getpid();
1607
/* if (snum == -1), then the change notify request was
1608
on a print server handle and we need to register on
1613
int num_services = lp_numservices();
1616
for ( idx=0; idx<num_services; idx++ ) {
1617
if (lp_snum_ok(idx) && lp_print_ok(idx) )
1618
print_notify_register_pid(idx);
1623
else /* register for a specific printer */
1625
printername = lp_const_servicename(snum);
1626
pdb = get_print_db_byname(printername);
1632
if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1633
DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1636
release_print_db(pdb);
1640
data = get_printer_notify_pid_list( tdb, printername, True );
1642
/* Add ourselves and increase the refcount. */
1644
for (i = 0; i < data.dsize; i += 8) {
1645
if (IVAL(data.dptr,i) == mypid) {
1646
uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1647
SIVAL(data.dptr, i+4, new_refcount);
1652
if (i == data.dsize) {
1653
/* We weren't in the list. Realloc. */
1654
data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1656
DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1661
SIVAL(data.dptr,data.dsize - 8,mypid);
1662
SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1665
/* Store back the record. */
1666
if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1667
DEBUG(0,("print_notify_register_pid: Failed to update pid \
1668
list for printer %s\n", printername));
1676
tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1678
release_print_db(pdb);
1679
SAFE_FREE(data.dptr);
1683
/****************************************************************************
1684
Update an entry in the print tdb that will allow us to send notify
1685
updates only to interested smbd's.
1686
****************************************************************************/
1688
bool print_notify_deregister_pid(int snum)
1691
struct tdb_print_db *pdb = NULL;
1692
TDB_CONTEXT *tdb = NULL;
1693
const char *printername;
1694
uint32 mypid = (uint32)sys_getpid();
1698
/* if ( snum == -1 ), we are deregister a print server handle
1699
which means to deregister on all print queues */
1703
int num_services = lp_numservices();
1706
for ( idx=0; idx<num_services; idx++ ) {
1707
if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1708
print_notify_deregister_pid(idx);
1713
else /* deregister a specific printer */
1715
printername = lp_const_servicename(snum);
1716
pdb = get_print_db_byname(printername);
1722
if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1723
DEBUG(0,("print_notify_register_pid: Failed to lock \
1724
printer %s database\n", printername));
1726
release_print_db(pdb);
1730
data = get_printer_notify_pid_list( tdb, printername, True );
1732
/* Reduce refcount. Remove ourselves if zero. */
1734
for (i = 0; i < data.dsize; ) {
1735
if (IVAL(data.dptr,i) == mypid) {
1736
uint32 refcount = IVAL(data.dptr, i+4);
1740
if (refcount == 0) {
1741
if (data.dsize - i > 8)
1742
memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1746
SIVAL(data.dptr, i+4, refcount);
1752
if (data.dsize == 0)
1753
SAFE_FREE(data.dptr);
1755
/* Store back the record. */
1756
if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1757
DEBUG(0,("print_notify_register_pid: Failed to update pid \
1758
list for printer %s\n", printername));
1766
tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1768
release_print_db(pdb);
1769
SAFE_FREE(data.dptr);
1773
/****************************************************************************
1774
Check if a jobid is valid. It is valid if it exists in the database.
1775
****************************************************************************/
1777
bool print_job_exists(const char* sharename, uint32 jobid)
1779
struct tdb_print_db *pdb = get_print_db_byname(sharename);
1785
ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
1786
release_print_db(pdb);
1790
/****************************************************************************
1791
Give the fd used for a jobid.
1792
****************************************************************************/
1794
int print_job_fd(const char* sharename, uint32 jobid)
1796
struct printjob *pjob = print_job_find(sharename, jobid);
1799
/* don't allow another process to get this info - it is meaningless */
1800
if (pjob->pid != sys_getpid())
1805
/****************************************************************************
1806
Give the filename used for a jobid.
1807
Only valid for the process doing the spooling and when the job
1808
has not been spooled.
1809
****************************************************************************/
1811
char *print_job_fname(const char* sharename, uint32 jobid)
1813
struct printjob *pjob = print_job_find(sharename, jobid);
1814
if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1816
return pjob->filename;
1820
/****************************************************************************
1821
Give the filename used for a jobid.
1822
Only valid for the process doing the spooling and when the job
1823
has not been spooled.
1824
****************************************************************************/
1826
NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1828
struct printjob *pjob = print_job_find(sharename, jobid);
1833
return pjob->nt_devmode;
1836
/****************************************************************************
1837
Set the place in the queue for a job.
1838
****************************************************************************/
1840
bool print_job_set_place(const char *sharename, uint32 jobid, int place)
1842
DEBUG(2,("print_job_set_place not implemented yet\n"));
1846
/****************************************************************************
1847
Set the name of a job. Only possible for owner.
1848
****************************************************************************/
1850
bool print_job_set_name(const char *sharename, uint32 jobid, char *name)
1852
struct printjob *pjob;
1854
pjob = print_job_find(sharename, jobid);
1855
if (!pjob || pjob->pid != sys_getpid())
1858
fstrcpy(pjob->jobname, name);
1859
return pjob_store(sharename, jobid, pjob);
1862
/***************************************************************************
1863
Remove a jobid from the 'jobs changed' list.
1864
***************************************************************************/
1866
static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
1868
struct tdb_print_db *pdb = get_print_db_byname(sharename);
1870
size_t job_count, i;
1872
bool gotlock = False;
1880
key = string_tdb_data("INFO/jobs_changed");
1882
if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1887
data = tdb_fetch(pdb->tdb, key);
1889
if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1892
job_count = data.dsize / 4;
1893
for (i = 0; i < job_count; i++) {
1896
ch_jobid = IVAL(data.dptr, i*4);
1897
if (ch_jobid == jobid) {
1898
if (i < job_count -1 )
1899
memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1901
if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1911
tdb_chainunlock(pdb->tdb, key);
1912
SAFE_FREE(data.dptr);
1913
release_print_db(pdb);
1915
DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1917
DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1921
/****************************************************************************
1922
Delete a print job - don't update queue.
1923
****************************************************************************/
1925
static bool print_job_delete1(int snum, uint32 jobid)
1927
const char* sharename = lp_const_servicename(snum);
1928
struct printjob *pjob = print_job_find(sharename, jobid);
1930
struct printif *current_printif = get_printer_fns( snum );
1936
* If already deleting just return.
1939
if (pjob->status == LPQ_DELETING)
1942
/* Hrm - we need to be able to cope with deleting a job before it
1943
has reached the spooler. Just mark it as LPQ_DELETING and
1944
let the print_queue_update() code rmeove the record */
1947
if (pjob->sysjob == -1) {
1948
DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1951
/* Set the tdb entry to be deleting. */
1953
pjob->status = LPQ_DELETING;
1954
pjob_store(sharename, jobid, pjob);
1956
if (pjob->spooled && pjob->sysjob != -1)
1958
result = (*(current_printif->job_delete))(
1960
lp_lprmcommand(snum),
1963
/* Delete the tdb entry if the delete succeeded or the job hasn't
1967
struct tdb_print_db *pdb = get_print_db_byname(sharename);
1972
pjob_delete(sharename, jobid);
1973
/* Ensure we keep a rough count of the number of total jobs... */
1974
tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1975
release_print_db(pdb);
1979
remove_from_jobs_changed( sharename, jobid );
1981
return (result == 0);
1984
/****************************************************************************
1985
Return true if the current user owns the print job.
1986
****************************************************************************/
1988
static bool is_owner(struct auth_serversupplied_info *server_info,
1989
const char *servicename,
1992
struct printjob *pjob = print_job_find(servicename, jobid);
1994
if (!pjob || !server_info)
1997
return strequal(pjob->user, server_info->sanitized_username);
2000
/****************************************************************************
2002
****************************************************************************/
2004
bool print_job_delete(struct auth_serversupplied_info *server_info, int snum,
2005
uint32 jobid, WERROR *errcode)
2007
const char* sharename = lp_const_servicename( snum );
2008
struct printjob *pjob;
2014
owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2016
/* Check access against security descriptor or whether the user
2020
!print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
2021
DEBUG(3, ("delete denied by security descriptor\n"));
2022
*errcode = WERR_ACCESS_DENIED;
2024
/* BEGIN_ADMIN_LOG */
2025
sys_adminlog( LOG_ERR,
2026
"Permission denied-- user not allowed to delete, \
2027
pause, or resume print job. User name: %s. Printer name: %s.",
2028
uidtoname(server_info->utok.uid),
2029
PRINTERNAME(snum) );
2036
* get the spooled filename of the print job
2037
* if this works, then the file has not been spooled
2038
* to the underlying print system. Just delete the
2039
* spool file & return.
2042
if ( (fname = print_job_fname( sharename, jobid )) != NULL )
2044
/* remove the spool file */
2045
DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
2046
if ( unlink( fname ) == -1 ) {
2047
*errcode = map_werror_from_unix(errno);
2052
if (!print_job_delete1(snum, jobid)) {
2053
*errcode = WERR_ACCESS_DENIED;
2057
/* force update the database and say the delete failed if the
2060
print_queue_update(snum, True);
2062
pjob = print_job_find(sharename, jobid);
2063
if ( pjob && (pjob->status != LPQ_DELETING) )
2064
*errcode = WERR_ACCESS_DENIED;
2066
return (pjob == NULL );
2069
/****************************************************************************
2071
****************************************************************************/
2073
bool print_job_pause(struct auth_serversupplied_info *server_info, int snum,
2074
uint32 jobid, WERROR *errcode)
2076
const char* sharename = lp_const_servicename(snum);
2077
struct printjob *pjob;
2079
struct printif *current_printif = get_printer_fns( snum );
2081
pjob = print_job_find(sharename, jobid);
2083
if (!pjob || !server_info) {
2084
DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2085
(unsigned int)jobid ));
2089
if (!pjob->spooled || pjob->sysjob == -1) {
2090
DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2091
(int)pjob->sysjob, (unsigned int)jobid ));
2095
if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2096
!print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
2097
DEBUG(3, ("pause denied by security descriptor\n"));
2099
/* BEGIN_ADMIN_LOG */
2100
sys_adminlog( LOG_ERR,
2101
"Permission denied-- user not allowed to delete, \
2102
pause, or resume print job. User name: %s. Printer name: %s.",
2103
uidtoname(server_info->utok.uid),
2104
PRINTERNAME(snum) );
2107
*errcode = WERR_ACCESS_DENIED;
2111
/* need to pause the spooled entry */
2112
ret = (*(current_printif->job_pause))(snum, pjob);
2115
*errcode = WERR_INVALID_PARAM;
2119
/* force update the database */
2120
print_cache_flush(lp_const_servicename(snum));
2122
/* Send a printer notify message */
2124
notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
2126
/* how do we tell if this succeeded? */
2131
/****************************************************************************
2133
****************************************************************************/
2135
bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
2136
uint32 jobid, WERROR *errcode)
2138
const char *sharename = lp_const_servicename(snum);
2139
struct printjob *pjob;
2141
struct printif *current_printif = get_printer_fns( snum );
2143
pjob = print_job_find(sharename, jobid);
2145
if (!pjob || !server_info) {
2146
DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2147
(unsigned int)jobid ));
2151
if (!pjob->spooled || pjob->sysjob == -1) {
2152
DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2153
(int)pjob->sysjob, (unsigned int)jobid ));
2157
if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2158
!print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
2159
DEBUG(3, ("resume denied by security descriptor\n"));
2160
*errcode = WERR_ACCESS_DENIED;
2162
/* BEGIN_ADMIN_LOG */
2163
sys_adminlog( LOG_ERR,
2164
"Permission denied-- user not allowed to delete, \
2165
pause, or resume print job. User name: %s. Printer name: %s.",
2166
uidtoname(server_info->utok.uid),
2167
PRINTERNAME(snum) );
2172
ret = (*(current_printif->job_resume))(snum, pjob);
2175
*errcode = WERR_INVALID_PARAM;
2179
/* force update the database */
2180
print_cache_flush(lp_const_servicename(snum));
2182
/* Send a printer notify message */
2184
notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2189
/****************************************************************************
2190
Write to a print file.
2191
****************************************************************************/
2193
ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2195
const char* sharename = lp_const_servicename(snum);
2197
struct printjob *pjob;
2199
pjob = print_job_find(sharename, jobid);
2203
/* don't allow another process to get this info - it is meaningless */
2204
if (pjob->pid != sys_getpid())
2207
return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2209
if (return_code>0) {
2211
pjob_store(sharename, jobid, pjob);
2216
/****************************************************************************
2217
Get the queue status - do not update if db is out of date.
2218
****************************************************************************/
2220
static int get_queue_status(const char* sharename, print_status_struct *status)
2224
struct tdb_print_db *pdb = get_print_db_byname(sharename);
2228
ZERO_STRUCTP(status);
2235
fstr_sprintf(keystr, "STATUS/%s", sharename);
2236
data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2238
if (data.dsize == sizeof(print_status_struct))
2239
/* this memcpy is ok since the status struct was
2240
not packed before storing it in the tdb */
2241
memcpy(status, data.dptr, sizeof(print_status_struct));
2242
SAFE_FREE(data.dptr);
2245
len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2246
release_print_db(pdb);
2247
return (len == -1 ? 0 : len);
2250
/****************************************************************************
2251
Determine the number of jobs in a queue.
2252
****************************************************************************/
2254
int print_queue_length(int snum, print_status_struct *pstatus)
2256
const char* sharename = lp_const_servicename( snum );
2257
print_status_struct status;
2260
ZERO_STRUCT( status );
2262
/* make sure the database is up to date */
2263
if (print_cache_expired(lp_const_servicename(snum), True))
2264
print_queue_update(snum, False);
2266
/* also fetch the queue status */
2267
memset(&status, 0, sizeof(status));
2268
len = get_queue_status(sharename, &status);
2276
/***************************************************************************
2277
Allocate a jobid. Hold the lock for as short a time as possible.
2278
***************************************************************************/
2280
static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2285
*pjobid = (uint32)-1;
2287
for (i = 0; i < 3; i++) {
2288
/* Lock the database - only wait 20 seconds. */
2289
if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) {
2290
DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2294
if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2295
if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2296
DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2298
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2301
DEBUG(10,("allocate_print_jobid: no existing jobid in %s\n", sharename));
2305
DEBUG(10,("allocate_print_jobid: read jobid %u from %s\n", jobid, sharename));
2307
jobid = NEXT_JOBID(jobid);
2309
if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2310
DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2311
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2315
/* We've finished with the INFO/nextjob lock. */
2316
tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2318
if (!print_job_exists(sharename, jobid)) {
2321
DEBUG(10,("allocate_print_jobid: found jobid %u in %s\n", jobid, sharename));
2325
DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2327
/* Probably full... */
2332
/* Store a dummy placeholder. */
2338
if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2339
TDB_INSERT) == -1) {
2340
DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2350
/***************************************************************************
2351
Append a jobid to the 'jobs changed' list.
2352
***************************************************************************/
2354
static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2359
SIVAL(&store_jobid, 0, jobid);
2360
data.dptr = (uint8 *)&store_jobid;
2363
DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2365
return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2369
/***************************************************************************
2370
Start spooling a job - return the jobid.
2371
***************************************************************************/
2373
uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum,
2374
const char *jobname, NT_DEVICEMODE *nt_devmode )
2378
struct printjob pjob;
2379
const char *sharename = lp_const_servicename(snum);
2380
struct tdb_print_db *pdb = get_print_db_byname(sharename);
2388
if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) {
2389
DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2390
release_print_db(pdb);
2394
if (!print_time_access_check(lp_servicename(snum))) {
2395
DEBUG(3, ("print_job_start: job start denied by time check\n"));
2396
release_print_db(pdb);
2400
path = lp_pathname(snum);
2402
/* see if we have sufficient disk space */
2403
if (lp_minprintspace(snum)) {
2404
uint64_t dspace, dsize;
2405
if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2406
dspace < 2*(uint64_t)lp_minprintspace(snum)) {
2407
DEBUG(3, ("print_job_start: disk space check failed.\n"));
2408
release_print_db(pdb);
2414
/* for autoloaded printers, check that the printcap entry still exists */
2415
if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2416
DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2417
release_print_db(pdb);
2422
/* Insure the maximum queue size is not violated */
2423
if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2424
DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2425
sharename, njobs, lp_maxprintjobs(snum) ));
2426
release_print_db(pdb);
2431
DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2432
sharename, njobs, lp_maxprintjobs(snum) ));
2434
if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2437
/* create the database entry */
2441
pjob.pid = sys_getpid();
2444
pjob.starttime = time(NULL);
2445
pjob.status = LPQ_SPOOLING;
2447
pjob.spooled = False;
2449
pjob.nt_devmode = nt_devmode;
2451
fstrcpy(pjob.jobname, jobname);
2453
fstrcpy(pjob.user, lp_printjob_username(snum));
2454
standard_sub_advanced(sharename, server_info->sanitized_username,
2455
path, server_info->utok.gid,
2456
server_info->sanitized_username,
2457
pdb_get_domain(server_info->sam_account),
2458
pjob.user, sizeof(pjob.user)-1);
2459
/* ensure NULL termination */
2460
pjob.user[sizeof(pjob.user)-1] = '\0';
2462
fstrcpy(pjob.queuename, lp_const_servicename(snum));
2464
/* we have a job entry - now create the spool file */
2465
slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2466
path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2467
pjob.fd = smb_mkstemp(pjob.filename);
2469
if (pjob.fd == -1) {
2470
if (errno == EACCES) {
2471
/* Common setup error, force a report. */
2472
DEBUG(0, ("print_job_start: insufficient permissions \
2473
to open spool file %s.\n", pjob.filename));
2475
/* Normal case, report at level 3 and above. */
2476
DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2477
DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2482
pjob_store(sharename, jobid, &pjob);
2484
/* Update the 'jobs changed' entry used by print_queue_status. */
2485
add_to_jobs_changed(pdb, jobid);
2487
/* Ensure we keep a rough count of the number of total jobs... */
2488
tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2490
release_print_db(pdb);
2496
pjob_delete(sharename, jobid);
2498
release_print_db(pdb);
2500
DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2504
/****************************************************************************
2505
Update the number of pages spooled to jobid
2506
****************************************************************************/
2508
void print_job_endpage(int snum, uint32 jobid)
2510
const char* sharename = lp_const_servicename(snum);
2511
struct printjob *pjob;
2513
pjob = print_job_find(sharename, jobid);
2516
/* don't allow another process to get this info - it is meaningless */
2517
if (pjob->pid != sys_getpid())
2521
pjob_store(sharename, jobid, pjob);
2524
/****************************************************************************
2525
Print a file - called on closing the file. This spools the job.
2526
If normal close is false then we're tearing down the jobs - treat as an
2528
****************************************************************************/
2530
bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
2532
const char* sharename = lp_const_servicename(snum);
2533
struct printjob *pjob;
2535
SMB_STRUCT_STAT sbuf;
2536
struct printif *current_printif = get_printer_fns( snum );
2538
pjob = print_job_find(sharename, jobid);
2543
if (pjob->spooled || pjob->pid != sys_getpid())
2546
if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
2547
(sys_fstat(pjob->fd, &sbuf) == 0)) {
2548
pjob->size = sbuf.st_size;
2554
* Not a normal close or we couldn't stat the job file,
2555
* so something has gone wrong. Cleanup.
2559
DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2563
/* Technically, this is not quite right. If the printer has a separator
2564
* page turned on, the NT spooler prints the separator page even if the
2565
* print job is 0 bytes. 010215 JRR */
2566
if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2567
/* don't bother spooling empty files or something being deleted. */
2568
DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2569
pjob->filename, pjob->size ? "deleted" : "zero length" ));
2570
unlink(pjob->filename);
2571
pjob_delete(sharename, jobid);
2575
ret = (*(current_printif->job_submit))(snum, pjob);
2580
/* The print job has been successfully handed over to the back-end */
2582
pjob->spooled = True;
2583
pjob->status = LPQ_QUEUED;
2584
pjob_store(sharename, jobid, pjob);
2586
/* make sure the database is up to date */
2587
if (print_cache_expired(lp_const_servicename(snum), True))
2588
print_queue_update(snum, False);
2594
/* The print job was not successfully started. Cleanup */
2595
/* Still need to add proper error return propagation! 010122:JRR */
2596
unlink(pjob->filename);
2597
pjob_delete(sharename, jobid);
2601
/****************************************************************************
2602
Get a snapshot of jobs in the system without traversing.
2603
****************************************************************************/
2605
static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2607
TDB_DATA data, cgdata;
2608
print_queue_struct *queue = NULL;
2610
uint32 extra_count = 0;
2611
int total_count = 0;
2614
int max_reported_jobs = lp_max_reported_jobs(snum);
2616
const char* sharename = lp_servicename(snum);
2618
/* make sure the database is up to date */
2619
if (print_cache_expired(lp_const_servicename(snum), True))
2620
print_queue_update(snum, False);
2626
ZERO_STRUCT(cgdata);
2628
/* Get the stored queue data. */
2629
data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2631
if (data.dptr && data.dsize >= sizeof(qcount))
2632
len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2634
/* Get the changed jobs list. */
2635
cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2636
if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2637
extra_count = cgdata.dsize/4;
2639
DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2641
/* Allocate the queue size. */
2642
if (qcount == 0 && extra_count == 0)
2645
if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2648
/* Retrieve the linearised queue data. */
2650
for( i = 0; i < qcount; i++) {
2651
uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2652
len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2661
queue[i].job = qjob;
2662
queue[i].size = qsize;
2663
queue[i].page_count = qpage_count;
2664
queue[i].status = qstatus;
2665
queue[i].priority = qpriority;
2666
queue[i].time = qtime;
2669
total_count = qcount;
2671
/* Add in the changed jobids. */
2672
for( i = 0; i < extra_count; i++) {
2674
struct printjob *pjob;
2676
jobid = IVAL(cgdata.dptr, i*4);
2677
DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2678
pjob = print_job_find(lp_const_servicename(snum), jobid);
2680
DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2681
remove_from_jobs_changed(sharename, jobid);
2685
queue[total_count].job = jobid;
2686
queue[total_count].size = pjob->size;
2687
queue[total_count].page_count = pjob->page_count;
2688
queue[total_count].status = pjob->status;
2689
queue[total_count].priority = 1;
2690
queue[total_count].time = pjob->starttime;
2691
fstrcpy(queue[total_count].fs_user, pjob->user);
2692
fstrcpy(queue[total_count].fs_file, pjob->jobname);
2696
/* Sort the queue by submission time otherwise they are displayed
2699
qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2701
DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2703
if (max_reported_jobs && total_count > max_reported_jobs)
2704
total_count = max_reported_jobs;
2707
*pcount = total_count;
2713
SAFE_FREE(data.dptr);
2714
SAFE_FREE(cgdata.dptr);
2718
/****************************************************************************
2719
Get a printer queue listing.
2720
set queue = NULL and status = NULL if you just want to update the cache
2721
****************************************************************************/
2723
int print_queue_status(int snum,
2724
print_queue_struct **ppqueue,
2725
print_status_struct *status)
2729
const char *sharename;
2730
struct tdb_print_db *pdb;
2733
/* make sure the database is up to date */
2735
if (print_cache_expired(lp_const_servicename(snum), True))
2736
print_queue_update(snum, False);
2738
/* return if we are done */
2739
if ( !ppqueue || !status )
2743
sharename = lp_const_servicename(snum);
2744
pdb = get_print_db_byname(sharename);
2750
* Fetch the queue status. We must do this first, as there may
2751
* be no jobs in the queue.
2754
ZERO_STRUCTP(status);
2755
slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2756
key = string_tdb_data(keystr);
2758
data = tdb_fetch(pdb->tdb, key);
2760
if (data.dsize == sizeof(*status)) {
2761
/* this memcpy is ok since the status struct was
2762
not packed before storing it in the tdb */
2763
memcpy(status, data.dptr, sizeof(*status));
2765
SAFE_FREE(data.dptr);
2769
* Now, fetch the print queue information. We first count the number
2770
* of entries, and then only retrieve the queue if necessary.
2773
if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2774
release_print_db(pdb);
2778
release_print_db(pdb);
2782
/****************************************************************************
2784
****************************************************************************/
2786
WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum)
2789
struct printif *current_printif = get_printer_fns( snum );
2791
if (!print_access_check(server_info, snum,
2792
PRINTER_ACCESS_ADMINISTER)) {
2793
return WERR_ACCESS_DENIED;
2799
ret = (*(current_printif->queue_pause))(snum);
2804
return WERR_INVALID_PARAM;
2807
/* force update the database */
2808
print_cache_flush(lp_const_servicename(snum));
2810
/* Send a printer notify message */
2812
notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2817
/****************************************************************************
2819
****************************************************************************/
2821
WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum)
2824
struct printif *current_printif = get_printer_fns( snum );
2826
if (!print_access_check(server_info, snum,
2827
PRINTER_ACCESS_ADMINISTER)) {
2828
return WERR_ACCESS_DENIED;
2833
ret = (*(current_printif->queue_resume))(snum);
2838
return WERR_INVALID_PARAM;
2841
/* make sure the database is up to date */
2842
if (print_cache_expired(lp_const_servicename(snum), True))
2843
print_queue_update(snum, True);
2845
/* Send a printer notify message */
2847
notify_printer_status(snum, PRINTER_STATUS_OK);
2852
/****************************************************************************
2853
Purge a queue - implemented by deleting all jobs that we can delete.
2854
****************************************************************************/
2856
WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum)
2858
print_queue_struct *queue;
2859
print_status_struct status;
2863
/* Force and update so the count is accurate (i.e. not a cached count) */
2864
print_queue_update(snum, True);
2866
can_job_admin = print_access_check(server_info, snum,
2867
JOB_ACCESS_ADMINISTER);
2868
njobs = print_queue_status(snum, &queue, &status);
2870
if ( can_job_admin )
2873
for (i=0;i<njobs;i++) {
2874
bool owner = is_owner(server_info, lp_const_servicename(snum),
2877
if (owner || can_job_admin) {
2878
print_job_delete1(snum, queue[i].job);
2882
if ( can_job_admin )
2885
/* update the cache */
2886
print_queue_update( snum, True );