printing/printing.c

ソースコードを見る。

データ構造

struct  rap_jobid_key
struct  traverse_struct

関数

static BOOL remove_from_jobs_changed (const char *sharename, uint32 jobid)
uint16 pjobid_to_rap (const char *sharename, uint32 jobid)
BOOL rap_to_pjobid (uint16 rap_jobid, fstring sharename, uint32 *pjobid)
static void rap_jobid_delete (const char *sharename, uint32 jobid)
static int get_queue_status (const char *sharename, print_status_struct *)
BOOL print_backend_init (void)
void printing_end (void)
static struct printifget_printer_fns_from_type (enum printing_types type)
static struct printifget_printer_fns (int snum)
static TDB_DATA print_key (uint32 jobid)
int unpack_pjob (char *buf, int buflen, struct printjob *pjob)
static struct printjobprint_job_find (const char *sharename, uint32 jobid)
static int unixjob_traverse_fn (TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA data, void *state)
uint32 sysjob_to_jobid (int unix_jobid)
static uint32 map_to_spoolss_status (uint32 lpq_status)
static void pjob_store_notify (const char *sharename, uint32 jobid, struct printjob *old_data, struct printjob *new_data)
static BOOL pjob_store (const char *sharename, uint32 jobid, struct printjob *pjob)
void pjob_delete (const char *sharename, uint32 jobid)
static uint32 print_parse_jobid (char *fname)
static void print_unix_job (const char *sharename, print_queue_struct *q, uint32 jobid)
static int traverse_fn_delete (TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
static void print_cache_flush (const char *sharename)
static pid_t get_updating_pid (const char *sharename)
static void set_updating_pid (const fstring sharename, BOOL updating)
static int printjob_comp (print_queue_struct *j1, print_queue_struct *j2)
static void store_queue_struct (struct tdb_print_db *pdb, struct traverse_struct *pts)
static TDB_DATA get_jobs_changed_data (struct tdb_print_db *pdb)
static void check_job_changed (const char *sharename, TDB_DATA data, uint32 jobid)
static BOOL print_cache_expired (const char *sharename, BOOL check_pending)
static void print_queue_update_internal (const char *sharename, struct printif *current_printif, char *lpq_command, char *lprm_command)
static void print_queue_update_with_lock (const char *sharename, struct printif *current_printif, char *lpq_command, char *lprm_command)
static void print_queue_receive (int msg_type, struct process_id src, void *buf, size_t msglen, void *private_data)
void start_background_queue (void)
static void print_queue_update (int snum, BOOL force)
BOOL print_notify_register_pid (int snum)
BOOL print_notify_deregister_pid (int snum)
BOOL print_job_exists (const char *sharename, uint32 jobid)
int print_job_fd (const char *sharename, uint32 jobid)
char * print_job_fname (const char *sharename, uint32 jobid)
NT_DEVICEMODEprint_job_devmode (const char *sharename, uint32 jobid)
BOOL print_job_set_place (const char *sharename, uint32 jobid, int place)
BOOL print_job_set_name (const char *sharename, uint32 jobid, char *name)
static BOOL print_job_delete1 (int snum, uint32 jobid)
static BOOL is_owner (struct current_user *user, const char *servicename, uint32 jobid)
BOOL print_job_delete (struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
BOOL print_job_pause (struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
BOOL print_job_resume (struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
ssize_t print_job_write (int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
int print_queue_length (int snum, print_status_struct *pstatus)
static BOOL allocate_print_jobid (struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
static BOOL add_to_jobs_changed (struct tdb_print_db *pdb, uint32 jobid)
uint32 print_job_start (struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode)
void print_job_endpage (int snum, uint32 jobid)
BOOL print_job_end (int snum, uint32 jobid, enum file_close_type close_type)
static BOOL get_stored_queue_info (struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
int print_queue_status (int snum, print_queue_struct **ppqueue, print_status_struct *status)
BOOL print_queue_pause (struct current_user *user, int snum, WERROR *errcode)
BOOL print_queue_resume (struct current_user *user, int snum, WERROR *errcode)
BOOL print_queue_purge (struct current_user *user, int snum, WERROR *errcode)

変数

SIG_ATOMIC_T got_sig_term
SIG_ATOMIC_T reload_after_sighup
current_user current_user
userdom_struct current_user_info
static TDB_CONTEXTrap_tdb
static uint16 next_rap_jobid
static uint32 sysjob_to_jobid_value
struct {
   uint32   lpq_status
   uint32   spoolss_status
lpq_to_spoolss_status_map []
static pid_t background_lpq_updater_pid = -1


関数

static BOOL remove_from_jobs_changed ( const char *  sharename,
uint32  jobid 
) [static]

printing.c1821 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeget_print_db_byname()release_print_db()string_tdb_data()tdb_print_db::tdbtdb_chainlock_with_timeout()tdb_chainunlock()tdb_fetch()tdb_store().

参照元 check_job_changed()get_stored_queue_info()pjob_delete()print_job_delete1().

01822 {
01823         struct tdb_print_db *pdb = get_print_db_byname(sharename);
01824         TDB_DATA data, key;
01825         size_t job_count, i;
01826         BOOL ret = False;
01827         BOOL gotlock = False;
01828 
01829         if (!pdb) {
01830                 return False;
01831         }
01832 
01833         ZERO_STRUCT(data);
01834 
01835         key = string_tdb_data("INFO/jobs_changed");
01836 
01837         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
01838                 goto out;
01839 
01840         gotlock = True;
01841 
01842         data = tdb_fetch(pdb->tdb, key);
01843 
01844         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
01845                 goto out;
01846 
01847         job_count = data.dsize / 4;
01848         for (i = 0; i < job_count; i++) {
01849                 uint32 ch_jobid;
01850 
01851                 ch_jobid = IVAL(data.dptr, i*4);
01852                 if (ch_jobid == jobid) {
01853                         if (i < job_count -1 )
01854                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
01855                         data.dsize -= 4;
01856                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
01857                                 goto out;
01858                         break;
01859                 }
01860         }
01861 
01862         ret = True;
01863   out:
01864 
01865         if (gotlock)
01866                 tdb_chainunlock(pdb->tdb, key);
01867         SAFE_FREE(data.dptr);
01868         release_print_db(pdb);
01869         if (ret)
01870                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
01871         else
01872                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
01873         return ret;
01874 }

uint16 pjobid_to_rap ( const char *  sharename,
uint32  jobid 
)

printing.c60 行で定義されています。

参照先 bufTDB_DATA::dptrTDB_DATA::dsizerap_jobid_key::jobidnext_rap_jobidrap_tdbrap_jobid_key::sharenametdb_fetch()tdb_open_log()tdb_store().

参照元 fill_printjob_info()print_fsp_open().

00061 {
00062         uint16 rap_jobid;
00063         TDB_DATA data, key;
00064         struct rap_jobid_key jinfo;
00065         uint8 buf[2];
00066 
00067         DEBUG(10,("pjobid_to_rap: called.\n"));
00068 
00069         if (!rap_tdb) {
00070                 /* Create the in-memory tdb. */
00071                 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
00072                 if (!rap_tdb)
00073                         return 0;
00074         }
00075 
00076         ZERO_STRUCT( jinfo );
00077         fstrcpy( jinfo.sharename, sharename );
00078         jinfo.jobid = jobid;
00079         key.dptr = (char*)&jinfo;
00080         key.dsize = sizeof(jinfo);
00081 
00082         data = tdb_fetch(rap_tdb, key);
00083         if (data.dptr && data.dsize == sizeof(uint16)) {
00084                 rap_jobid = SVAL(data.dptr, 0);
00085                 SAFE_FREE(data.dptr);
00086                 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
00087                         (unsigned int)jobid, (unsigned int)rap_jobid));
00088                 return rap_jobid;
00089         }
00090         SAFE_FREE(data.dptr);
00091         /* Not found - create and store mapping. */
00092         rap_jobid = ++next_rap_jobid;
00093         if (rap_jobid == 0)
00094                 rap_jobid = ++next_rap_jobid;
00095         SSVAL(buf,0,rap_jobid);
00096         data.dptr = (char*)buf;
00097         data.dsize = sizeof(rap_jobid);
00098         tdb_store(rap_tdb, key, data, TDB_REPLACE);
00099         tdb_store(rap_tdb, data, key, TDB_REPLACE);
00100 
00101         DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
00102                 (unsigned int)jobid, (unsigned int)rap_jobid));
00103         return rap_jobid;
00104 }

BOOL rap_to_pjobid ( uint16  rap_jobid,
fstring  sharename,
uint32 *  pjobid 
)

printing.c106 行で定義されています。

参照先 bufTDB_DATA::dptrTDB_DATA::dsizerap_jobid_key::jobidrap_tdbrap_jobid_key::sharenametdb_fetch().

参照元 api_PrintJobInfo()api_RDosPrintJobDel()api_WPrintJobGetInfo()print_fsp_end()write_file().

00107 {
00108         TDB_DATA data, key;
00109         uint8 buf[2];
00110 
00111         DEBUG(10,("rap_to_pjobid called.\n"));
00112 
00113         if (!rap_tdb)
00114                 return False;
00115 
00116         SSVAL(buf,0,rap_jobid);
00117         key.dptr = (char*)buf;
00118         key.dsize = sizeof(rap_jobid);
00119         data = tdb_fetch(rap_tdb, key);
00120         if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) 
00121         {
00122                 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
00123                 fstrcpy( sharename, jinfo->sharename );
00124                 *pjobid = jinfo->jobid;
00125                 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
00126                         (unsigned int)*pjobid, (unsigned int)rap_jobid));
00127                 SAFE_FREE(data.dptr);
00128                 return True;
00129         }
00130 
00131         DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
00132                 (unsigned int)rap_jobid));
00133         SAFE_FREE(data.dptr);
00134         return False;
00135 }

static void rap_jobid_delete ( const char *  sharename,
uint32  jobid 
) [static]

printing.c137 行で定義されています。

参照先 bufTDB_DATA::dptrTDB_DATA::dsizerap_jobid_key::jobidrap_tdbrap_jobid_key::sharenametdb_delete()tdb_fetch().

参照元 pjob_delete().

00138 {
00139         TDB_DATA key, data;
00140         uint16 rap_jobid;
00141         struct rap_jobid_key jinfo;
00142         uint8 buf[2];
00143 
00144         DEBUG(10,("rap_jobid_delete: called.\n"));
00145 
00146         if (!rap_tdb)
00147                 return;
00148 
00149         ZERO_STRUCT( jinfo );
00150         fstrcpy( jinfo.sharename, sharename );
00151         jinfo.jobid = jobid;
00152         key.dptr = (char*)&jinfo;
00153         key.dsize = sizeof(jinfo);
00154 
00155         data = tdb_fetch(rap_tdb, key);
00156         if (!data.dptr || (data.dsize != sizeof(uint16))) {
00157                 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
00158                         (unsigned int)jobid ));
00159                 SAFE_FREE(data.dptr);
00160                 return;
00161         }
00162 
00163         DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
00164                 (unsigned int)jobid ));
00165 
00166         rap_jobid = SVAL(data.dptr, 0);
00167         SAFE_FREE(data.dptr);
00168         SSVAL(buf,0,rap_jobid);
00169         data.dptr = (char*)buf;
00170         data.dsize = sizeof(rap_jobid);
00171         tdb_delete(rap_tdb, key);
00172         tdb_delete(rap_tdb, data);
00173 }

static int get_queue_status ( const char *  sharename,
print_status_struct  
) [static]

printing.c2173 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizefstr_sprintf()get_print_db_byname()lenrelease_print_db()statusstring_tdb_data()tdb_print_db::tdbtdb_fetch()tdb_fetch_int32().

参照元 print_queue_length()print_queue_update_internal().

02174 {
02175         fstring keystr;
02176         TDB_DATA data;
02177         struct tdb_print_db *pdb = get_print_db_byname(sharename);
02178         int len;
02179 
02180         if (status) {
02181                 ZERO_STRUCTP(status);
02182         }
02183 
02184         if (!pdb)
02185                 return 0;
02186 
02187         if (status) {
02188                 fstr_sprintf(keystr, "STATUS/%s", sharename);
02189                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
02190                 if (data.dptr) {
02191                         if (data.dsize == sizeof(print_status_struct))
02192                                 /* this memcpy is ok since the status struct was 
02193                                    not packed before storing it in the tdb */
02194                                 memcpy(status, data.dptr, sizeof(print_status_struct));
02195                         SAFE_FREE(data.dptr);
02196                 }
02197         }
02198         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
02199         release_print_db(pdb);
02200         return (len == -1 ? 0 : len);
02201 }

BOOL print_backend_init ( void   ) 

printing.c181 行で定義されています。

参照先 close_all_print_db()get_print_db_byname()lock_path()nt_printing_init()release_print_db()tdb_fetch_int32()tdb_lock_bystring()tdb_store_int32()tdb_traverse()tdb_traverse_delete_fn()tdb_unlock_bystring().

参照元 main().

00182 {
00183         const char *sversion = "INFO/version";
00184         pstring printing_path;
00185         int services = lp_numservices();
00186         int snum;
00187 
00188         unlink(lock_path("printing.tdb"));
00189         pstrcpy(printing_path,lock_path("printing"));
00190         mkdir(printing_path,0755);
00191 
00192         /* handle a Samba upgrade */
00193 
00194         for (snum = 0; snum < services; snum++) {
00195                 struct tdb_print_db *pdb;
00196                 if (!lp_print_ok(snum))
00197                         continue;
00198 
00199                 pdb = get_print_db_byname(lp_const_servicename(snum));
00200                 if (!pdb)
00201                         continue;
00202                 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
00203                         DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
00204                         release_print_db(pdb);
00205                         return False;
00206                 }
00207                 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
00208                         tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
00209                         tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
00210                 }
00211                 tdb_unlock_bystring(pdb->tdb, sversion);
00212                 release_print_db(pdb);
00213         }
00214 
00215         close_all_print_db(); /* Don't leave any open. */
00216 
00217         /* do NT print initialization... */
00218         return nt_printing_init();
00219 }

void printing_end ( void   ) 

printing.c225 行で定義されています。

参照先 close_all_print_db().

参照元 exit_server_common().

00226 {
00227         close_all_print_db(); /* Don't leave any open. */
00228 }

static struct printif* get_printer_fns_from_type ( enum printing_types  type  )  [static]

printing.c239 行で定義されています。

参照先 cups_printifgeneric_printifiprint_printifPRINT_CUPSprintif::type.

参照元 get_printer_fns()print_queue_receive().

00240 {
00241         struct printif *printer_fns = &generic_printif;
00242 
00243 #ifdef HAVE_CUPS
00244         if ( type == PRINT_CUPS ) {
00245                 printer_fns = &cups_printif;
00246         }
00247 #endif /* HAVE_CUPS */
00248 
00249 #ifdef HAVE_IPRINT
00250         if ( type == PRINT_IPRINT ) {
00251                 printer_fns = &iprint_printif;
00252         }
00253 #endif /* HAVE_IPRINT */
00254 
00255         printer_fns->type = type;
00256         
00257         return printer_fns;
00258 }

static struct printif* get_printer_fns ( int  snum  )  [static]

printing.c260 行で定義されています。

参照先 get_printer_fns_from_type().

参照元 print_job_delete1()print_job_end()print_job_pause()print_job_resume()print_queue_pause()print_queue_resume()print_queue_update().

00261 {
00262         return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
00263 }

static TDB_DATA print_key ( uint32  jobid  )  [static]

printing.c270 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsize.

参照元 do_command()pjob_delete()pjob_store()print_job_exists()print_job_find().

00271 {
00272         static uint32 j;
00273         TDB_DATA ret;
00274 
00275         SIVAL(&j, 0, jobid);
00276         ret.dptr = (char *)&j;
00277         ret.dsize = sizeof(j);
00278         return ret;
00279 }

int unpack_pjob ( char *  buf,
int  buflen,
struct printjob pjob 
)

printing.c285 行で定義されています。

参照先 printjob::fdprintjob::filenameprintjob::jobnamelenprintjob::nt_devmodeprintjob::page_countprintjob::pidprintjob::queuenameprintjob::sizeprintjob::smbjobprintjob::spooledprintjob::starttimeprintjob::statusprintjob::sysjobtdb_unpack()unpack_devicemode()printjob::user.

参照元 pjob_store()print_job_find()traverse_fn_delete().

00286 {
00287         int     len = 0;
00288         int     used;
00289         uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
00290         uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
00291 
00292         if ( !buf || !pjob )
00293                 return -1;
00294                 
00295         len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
00296                                 &pjpid,
00297                                 &pjsysjob,
00298                                 &pjfd,
00299                                 &pjstarttime,
00300                                 &pjstatus,
00301                                 &pjsize,
00302                                 &pjpage_count,
00303                                 &pjspooled,
00304                                 &pjsmbjob,
00305                                 pjob->filename,
00306                                 pjob->jobname,
00307                                 pjob->user,
00308                                 pjob->queuename);
00309                                 
00310         if ( len == -1 )
00311                 return -1;
00312                 
00313         if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
00314                 return -1;
00315         
00316         len += used;
00317 
00318         pjob->pid = pjpid;
00319         pjob->sysjob = pjsysjob;
00320         pjob->fd = pjfd;
00321         pjob->starttime = pjstarttime;
00322         pjob->status = pjstatus;
00323         pjob->size = pjsize;
00324         pjob->page_count = pjpage_count;
00325         pjob->spooled = pjspooled;
00326         pjob->smbjob = pjsmbjob;
00327         
00328         return len;
00329 
00330 }

static struct printjob* print_job_find ( const char *  sharename,
uint32  jobid 
) [static]

printing.c336 行で定義されています。

参照先 free_nt_devicemode()get_print_db_byname()printjob::nt_devmodeprint_key()release_print_db()printjob::sysjobtdb_print_db::tdbtdb_fetch()unpack_pjob().

参照元 get_stored_queue_info()is_owner()pjob_delete()print_job_delete()print_job_delete1()print_job_devmode()print_job_end()print_job_endpage()print_job_fd()print_job_fname()print_job_pause()print_job_resume()print_job_set_name()print_job_write()print_queue_update_internal()print_unix_job().

00337 {
00338         static struct printjob  pjob;
00339         TDB_DATA                ret;
00340         struct tdb_print_db     *pdb = get_print_db_byname(sharename);
00341         
00342         DEBUG(10,("print_job_find: looking up job %u for share %s\n",
00343                         (unsigned int)jobid, sharename ));
00344 
00345         if (!pdb) {
00346                 return NULL;
00347         }
00348 
00349         ret = tdb_fetch(pdb->tdb, print_key(jobid));
00350         release_print_db(pdb);
00351 
00352         if (!ret.dptr) {
00353                 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
00354                 return NULL;
00355         }
00356         
00357         if ( pjob.nt_devmode ) {
00358                 free_nt_devicemode( &pjob.nt_devmode );
00359         }
00360                 
00361         ZERO_STRUCT( pjob );
00362         
00363         if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
00364                 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
00365                 SAFE_FREE(ret.dptr);
00366                 return NULL;
00367         }
00368         
00369         SAFE_FREE(ret.dptr);
00370 
00371         DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
00372                         (int)pjob.sysjob, (unsigned int)jobid ));
00373 
00374         return &pjob;
00375 }

static int unixjob_traverse_fn ( TDB_CONTEXT the_tdb,
TDB_DATA  key,
TDB_DATA  data,
void *  state 
) [static]

printing.c381 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeprintjob::sysjobsysjob_to_jobid_value.

参照元 sysjob_to_jobid().

00383 {
00384         struct printjob *pjob;
00385         int *sysjob = (int *)state;
00386 
00387         if (!data.dptr || data.dsize == 0)
00388                 return 0;
00389 
00390         pjob = (struct printjob *)data.dptr;
00391         if (key.dsize != sizeof(uint32))
00392                 return 0;
00393 
00394         if (*sysjob == pjob->sysjob) {
00395                 uint32 jobid = IVAL(key.dptr,0);
00396 
00397                 sysjob_to_jobid_value = jobid;
00398                 return 1;
00399         }
00400 
00401         return 0;
00402 }

uint32 sysjob_to_jobid ( int  unix_jobid  ) 

printing.c409 行で定義されています。

参照先 get_print_db_byname()release_print_db()sysjob_to_jobid_valuetdb_traverse()unixjob_traverse_fn().

参照元 send_notify2_changes().

00410 {
00411         int services = lp_numservices();
00412         int snum;
00413 
00414         sysjob_to_jobid_value = (uint32)-1;
00415 
00416         for (snum = 0; snum < services; snum++) {
00417                 struct tdb_print_db *pdb;
00418                 if (!lp_print_ok(snum))
00419                         continue;
00420                 pdb = get_print_db_byname(lp_const_servicename(snum));
00421                 if (!pdb) {
00422                         continue;
00423                 }
00424                 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
00425                 release_print_db(pdb);
00426                 if (sysjob_to_jobid_value != (uint32)-1)
00427                         return sysjob_to_jobid_value;
00428         }
00429         return (uint32)-1;
00430 }

static uint32 map_to_spoolss_status ( uint32  lpq_status  )  [static]

printing.c457 行で定義されています。

参照先 lpq_to_spoolss_status_map.

参照元 pjob_store_notify().

00458 {
00459         int i = 0;
00460 
00461         while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
00462                 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
00463                         return lpq_to_spoolss_status_map[i].spoolss_status;
00464                 i++;
00465         }
00466 
00467         return 0;
00468 }

static void pjob_store_notify ( const char *  sharename,
uint32  jobid,
struct printjob old_data,
struct printjob new_data 
) [static]

printing.c470 行で定義されています。

参照先 printjob::jobnamemap_to_spoolss_status()notify_job_name()notify_job_status()notify_job_submitted()notify_job_total_bytes()notify_job_total_pages()notify_job_username()printjob::page_countprintjob::sizeprintjob::starttimeprintjob::statusstrequal()printjob::user.

参照元 pjob_store().

00472 {
00473         BOOL new_job = False;
00474 
00475         if (!old_data)
00476                 new_job = True;
00477 
00478         /* Job attributes that can't be changed.  We only send
00479            notification for these on a new job. */
00480 
00481         /* ACHTUNG!  Due to a bug in Samba's spoolss parsing of the 
00482            NOTIFY_INFO_DATA buffer, we *have* to send the job submission 
00483            time first or else we'll end up with potential alignment 
00484            errors.  I don't think the systemtime should be spooled as 
00485            a string, but this gets us around that error.   
00486            --jerry (i'll feel dirty for this) */
00487  
00488         if (new_job) {
00489                 notify_job_submitted(sharename, jobid, new_data->starttime);
00490                 notify_job_username(sharename, jobid, new_data->user);
00491         }
00492 
00493         if (new_job || !strequal(old_data->jobname, new_data->jobname))
00494                 notify_job_name(sharename, jobid, new_data->jobname);
00495 
00496         /* Job attributes of a new job or attributes that can be
00497            modified. */
00498 
00499         if (new_job || !strequal(old_data->jobname, new_data->jobname))
00500                 notify_job_name(sharename, jobid, new_data->jobname);
00501 
00502         if (new_job || old_data->status != new_data->status)
00503                 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
00504 
00505         if (new_job || old_data->size != new_data->size)
00506                 notify_job_total_bytes(sharename, jobid, new_data->size);
00507 
00508         if (new_job || old_data->page_count != new_data->page_count)
00509                 notify_job_total_pages(sharename, jobid, new_data->page_count);
00510 }

static BOOL pjob_store ( const char *  sharename,
uint32  jobid,
struct printjob pjob 
) [static]

printing.c516 行で定義されています。

参照先 bufTDB_DATA::dptrTDB_DATA::dsizeprintjob::fdprintjob::filenamefree_nt_devicemode()get_print_db_byname()printjob::jobnamelenprintjob::nt_devmodepack_devicemode()printjob::page_countprintjob::pidpjob_store_notify()print_key()printjob::queuenamerelease_print_db()printjob::sizeprintjob::smbjobprintjob::spooledprintjob::starttimeprintjob::statusprintjob::sysjobtdb_print_db::tdbtdb_fetch()tdb_pack()tdb_store()unpack_pjob()printjob::user.

参照元 print_job_delete1()print_job_end()print_job_endpage()print_job_set_name()print_job_start()print_job_write()print_queue_update_internal()print_unix_job().

00517 {
00518         TDB_DATA                old_data, new_data;
00519         BOOL                    ret = False;
00520         struct tdb_print_db     *pdb = get_print_db_byname(sharename);
00521         char                    *buf = NULL;
00522         int                     len, newlen, buflen;
00523         
00524 
00525         if (!pdb)
00526                 return False;
00527 
00528         /* Get old data */
00529 
00530         old_data = tdb_fetch(pdb->tdb, print_key(jobid));
00531 
00532         /* Doh!  Now we have to pack/unpack data since the NT_DEVICEMODE was added */
00533 
00534         newlen = 0;
00535         
00536         do {
00537                 len = 0;
00538                 buflen = newlen;
00539                 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
00540                                 (uint32)pjob->pid,
00541                                 (uint32)pjob->sysjob,
00542                                 (uint32)pjob->fd,
00543                                 (uint32)pjob->starttime,
00544                                 (uint32)pjob->status,
00545                                 (uint32)pjob->size,
00546                                 (uint32)pjob->page_count,
00547                                 (uint32)pjob->spooled,
00548                                 (uint32)pjob->smbjob,
00549                                 pjob->filename,
00550                                 pjob->jobname,
00551                                 pjob->user,
00552                                 pjob->queuename);
00553 
00554                 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
00555         
00556                 if (buflen != len) {
00557                         buf = (char *)SMB_REALLOC(buf, len);
00558                         if (!buf) {
00559                                 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
00560                                 goto done;
00561                         }
00562                         newlen = len;
00563                 }
00564         } while ( buflen != len );
00565                 
00566         
00567         /* Store new data */
00568 
00569         new_data.dptr = buf;
00570         new_data.dsize = len;
00571         ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
00572 
00573         release_print_db(pdb);
00574 
00575         /* Send notify updates for what has changed */
00576 
00577         if ( ret ) {
00578                 struct printjob old_pjob;
00579 
00580                 if ( old_data.dsize )
00581                 {
00582                         if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
00583                         {
00584                                 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
00585                                 free_nt_devicemode( &old_pjob.nt_devmode );
00586                         }
00587                 }
00588                 else {
00589                         /* new job */
00590                         pjob_store_notify( sharename, jobid, NULL, pjob );
00591                 }
00592         }
00593 
00594 done:
00595         SAFE_FREE( old_data.dptr );
00596         SAFE_FREE( buf );
00597 
00598         return ret;
00599 }

void pjob_delete ( const char *  sharename,
uint32  jobid 
)

printing.c605 行で定義されています。

参照先 get_print_db_byname()notify_job_status()print_job_find()print_key()rap_jobid_delete()release_print_db()remove_from_jobs_changed()tdb_print_db::tdbtdb_delete().

参照元 print_fsp_open()print_job_delete1()print_job_end()print_job_start()traverse_fn_delete().

00606 {
00607         struct printjob *pjob;
00608         uint32 job_status = 0;
00609         struct tdb_print_db *pdb;
00610 
00611         pdb = get_print_db_byname( sharename );
00612 
00613         if (!pdb)
00614                 return;
00615 
00616         pjob = print_job_find( sharename, jobid );
00617 
00618         if (!pjob) {
00619                 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
00620                                         (unsigned int)jobid));
00621                 release_print_db(pdb);
00622                 return;
00623         }
00624 
00625         /* We must cycle through JOB_STATUS_DELETING and
00626            JOB_STATUS_DELETED for the port monitor to delete the job
00627            properly. */
00628         
00629         job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
00630         notify_job_status(sharename, jobid, job_status);
00631         
00632         /* Remove from printing.tdb */
00633 
00634         tdb_delete(pdb->tdb, print_key(jobid));
00635         remove_from_jobs_changed(sharename, jobid);
00636         release_print_db( pdb );
00637         rap_jobid_delete(sharename, jobid);
00638 }

static uint32 print_parse_jobid ( char *  fname  )  [static]

printing.c644 行で定義されています。

参照元 print_queue_update_internal().

00645 {
00646         int jobid;
00647 
00648         if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
00649                 return (uint32)-1;
00650         fname += strlen(PRINT_SPOOL_PREFIX);
00651 
00652         jobid = atoi(fname);
00653         if (jobid <= 0)
00654                 return (uint32)-1;
00655 
00656         return (uint32)jobid;
00657 }

static void print_unix_job ( const char *  sharename,
print_queue_struct q,
uint32  jobid 
) [static]

printing.c663 行で定義されています。

参照先 printjob::fdprintjob::filename_print_queue_struct::fs_file_print_queue_struct::fs_user_print_queue_struct::jobprintjob::jobnameprintjob::pidpjob_store()print_job_find()printjob::queuename_print_queue_struct::sizeprintjob::sizeprintjob::smbjobprintjob::spooledprintjob::starttime_print_queue_struct::statusprintjob::statusprintjob::sysjob_print_queue_struct::timeprintjob::user.

参照元 print_queue_update_internal().

00664 {
00665         struct printjob pj, *old_pj;
00666 
00667         if (jobid == (uint32)-1) 
00668                 jobid = q->job + UNIX_JOB_START;
00669 
00670         /* Preserve the timestamp on an existing unix print job */
00671 
00672         old_pj = print_job_find(sharename, jobid);
00673 
00674         ZERO_STRUCT(pj);
00675 
00676         pj.pid = (pid_t)-1;
00677         pj.sysjob = q->job;
00678         pj.fd = -1;
00679         pj.starttime = old_pj ? old_pj->starttime : q->time;
00680         pj.status = q->status;
00681         pj.size = q->size;
00682         pj.spooled = True;
00683         fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
00684         if (jobid < UNIX_JOB_START) {
00685                 pj.smbjob = True;
00686                 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
00687         } else {
00688                 pj.smbjob = False;
00689                 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
00690         }
00691         fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
00692         fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
00693 
00694         pjob_store(sharename, jobid, &pj);
00695 }

static int traverse_fn_delete ( TDB_CONTEXT t,
TDB_DATA  key,
TDB_DATA  data,
void *  state 
) [static]

printing.c711 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizefree_nt_devicemode()_print_queue_struct::jobprintjob::nt_devmodepjob_delete()traverse_struct::qcounttraverse_struct::queuetraverse_struct::sharenameprintjob::smbjobunpack_pjob().

参照元 print_queue_update_internal().

00712 {
00713         struct traverse_struct *ts = (struct traverse_struct *)state;
00714         struct printjob pjob;
00715         uint32 jobid;
00716         int i = 0;
00717 
00718         if (  key.dsize != sizeof(jobid) )
00719                 return 0;
00720                 
00721         jobid = IVAL(key.dptr, 0);
00722         if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
00723                 return 0;
00724         free_nt_devicemode( &pjob.nt_devmode );
00725 
00726 
00727         if (!pjob.smbjob) {
00728                 /* remove a unix job if it isn't in the system queue any more */
00729 
00730                 for (i=0;i<ts->qcount;i++) {
00731                         uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
00732                         if (jobid == u_jobid)
00733                                 break;
00734                 }
00735                 if (i == ts->qcount) {
00736                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
00737                                                 (unsigned int)jobid ));
00738                         pjob_delete(ts->sharename, jobid);
00739                         return 0;
00740                 } 
00741 
00742                 /* need to continue the the bottom of the function to
00743                    save the correct attributes */
00744         }
00745 
00746         /* maybe it hasn't been spooled yet */
00747         if (!pjob.spooled) {
00748                 /* if a job is not spooled and the process doesn't
00749                    exist then kill it. This cleans up after smbd
00750                    deaths */
00751                 if (!process_exists_by_pid(pjob.pid)) {
00752                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
00753                                                 (unsigned int)jobid, (unsigned int)pjob.pid ));
00754                         pjob_delete(ts->sharename, jobid);
00755                 } else
00756                         ts->total_jobs++;
00757                 return 0;
00758         }
00759 
00760         /* this check only makes sense for jobs submitted from Windows clients */
00761         
00762         if ( pjob.smbjob ) {
00763                 for (i=0;i<ts->qcount;i++) {
00764                         uint32 curr_jobid;
00765 
00766                         if ( pjob.status == LPQ_DELETED )
00767                                 continue;
00768 
00769                         curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
00770 
00771                         if (jobid == curr_jobid) {
00772 
00773                                 /* try to clean up any jobs that need to be deleted */
00774 
00775                                 if ( pjob.status == LPQ_DELETING ) {
00776                                         int result;
00777 
00778                                         result = (*(ts->print_if->job_delete))( 
00779                                                 ts->sharename, ts->lprm_command, &pjob );
00780 
00781                                         if ( result != 0 ) {
00782                                                 /* if we can't delete, then reset the job status */
00783                                                 pjob.status = LPQ_QUEUED;
00784                                                 pjob_store(ts->sharename, jobid, &pjob);
00785                                         }
00786                                         else {
00787                                                 /* if we deleted the job, the remove the tdb record */
00788                                                 pjob_delete(ts->sharename, jobid);
00789                                                 pjob.status = LPQ_DELETED;
00790                                         }
00791                                                 
00792                                 }
00793 
00794                                 break;
00795                         }
00796                 }
00797         }
00798         
00799         /* The job isn't in the system queue - we have to assume it has
00800            completed, so delete the database entry. */
00801 
00802         if (i == ts->qcount) {
00803 
00804                 /* A race can occur between the time a job is spooled and
00805                    when it appears in the lpq output.  This happens when
00806                    the job is added to printing.tdb when another smbd
00807                    running print_queue_update() has completed a lpq and
00808                    is currently traversing the printing tdb and deleting jobs.
00809                    Don't delete the job if it was submitted after the lpq_time. */
00810 
00811                 if (pjob.starttime < ts->lpq_time) {
00812                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
00813                                                 (unsigned int)jobid,
00814                                                 (unsigned int)pjob.starttime,
00815                                                 (unsigned int)ts->lpq_time ));
00816                         pjob_delete(ts->sharename, jobid);
00817                 } else
00818                         ts->total_jobs++;
00819                 return 0;
00820         }
00821 
00822         /* Save the pjob attributes we will store. 
00823            FIXME!!! This is the only place where queue->job 
00824            represents the SMB jobid      --jerry */
00825 
00826         ts->queue[i].job = jobid;               
00827         ts->queue[i].size = pjob.size;
00828         ts->queue[i].page_count = pjob.page_count;
00829         ts->queue[i].status = pjob.status;
00830         ts->queue[i].priority = 1;
00831         ts->queue[i].time = pjob.starttime;
00832         fstrcpy(ts->queue[i].fs_user, pjob.user);
00833         fstrcpy(ts->queue[i].fs_file, pjob.jobname);
00834 
00835         ts->total_jobs++;
00836 
00837         return 0;
00838 }

static void print_cache_flush ( const char *  sharename  )  [static]

printing.c844 行で定義されています。

参照先 get_print_db_byname()release_print_db()tdb_print_db::tdbtdb_store_int32().

参照元 print_job_pause()print_job_resume()print_queue_pause().

00845 {
00846         fstring key;
00847         struct tdb_print_db *pdb = get_print_db_byname(sharename);
00848 
00849         if (!pdb)
00850                 return;
00851         slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
00852         tdb_store_int32(pdb->tdb, key, -1);
00853         release_print_db(pdb);
00854 }

static pid_t get_updating_pid ( const char *  sharename  )  [static]

printing.c860 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeget_print_db_byname()process_exists_by_pid()release_print_db()tdb_print_db::tdbtdb_fetch().

参照元 print_queue_update_with_lock().

00861 {
00862         fstring keystr;
00863         TDB_DATA data, key;
00864         pid_t updating_pid;
00865         struct tdb_print_db *pdb = get_print_db_byname(sharename);
00866 
00867         if (!pdb)
00868                 return (pid_t)-1;
00869         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
00870         key.dptr = keystr;
00871         key.dsize = strlen(keystr);
00872 
00873         data = tdb_fetch(pdb->tdb, key);
00874         release_print_db(pdb);
00875         if (!data.dptr || data.dsize != sizeof(pid_t)) {
00876                 SAFE_FREE(data.dptr);
00877                 return (pid_t)-1;
00878         }
00879 
00880         updating_pid = IVAL(data.dptr, 0);
00881         SAFE_FREE(data.dptr);
00882 
00883         if (process_exists_by_pid(updating_pid))
00884                 return updating_pid;
00885 
00886         return (pid_t)-1;
00887 }

static void set_updating_pid ( const fstring  sharename,
BOOL  updating 
) [static]

printing.c894 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeget_print_db_byname()release_print_db()sys_getpid()tdb_print_db::tdbtdb_delete()tdb_store().

参照元 print_queue_update_with_lock().

00895 {
00896         fstring keystr;
00897         TDB_DATA key;
00898         TDB_DATA data;
00899         pid_t updating_pid = sys_getpid();
00900         uint8 buffer[4];
00901         
00902         struct tdb_print_db *pdb = get_print_db_byname(sharename);
00903 
00904         if (!pdb)
00905                 return;
00906 
00907         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
00908         key.dptr = keystr;
00909         key.dsize = strlen(keystr);
00910         
00911         DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n", 
00912                 updating ? "" : "not ",
00913                 sharename ));
00914 
00915         if ( !updating ) {
00916                 tdb_delete(pdb->tdb, key);
00917                 release_print_db(pdb);
00918                 return;
00919         }
00920         
00921         SIVAL( buffer, 0, updating_pid);
00922         data.dptr = (char *)buffer;
00923         data.dsize = 4;         /* we always assume this is a 4 byte value */
00924 
00925         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
00926         release_print_db(pdb);
00927 }

static int printjob_comp ( print_queue_struct j1,
print_queue_struct j2 
) [static]

printing.c933 行で定義されています。

参照先 _print_queue_struct::time.

参照元 get_stored_queue_info()print_queue_update_internal().

00934 {
00935         /* Silly cases */
00936 
00937         if (!j1 && !j2)
00938                 return 0;
00939         if (!j1)
00940                 return -1;
00941         if (!j2)
00942                 return 1;
00943 
00944         /* Sort on job start time */
00945 
00946         if (j1->time == j2->time)
00947                 return 0;
00948         return (j1->time > j2->time) ? 1 : -1;
00949 }

static void store_queue_struct ( struct tdb_print_db pdb,
struct traverse_struct pts 
) [static]

printing.c956 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsize_print_queue_struct::fs_file_print_queue_struct::fs_user_print_queue_struct::joblenLPQ_DELETED_print_queue_struct::page_count_print_queue_struct::prioritytraverse_struct::qcounttraverse_struct::queue_print_queue_struct::sizesizetraverse_struct::snum_print_queue_struct::statusstatusstring_tdb_data()tdb_print_db::tdbtdb_pack()tdb_store()_print_queue_struct::time.

参照元 print_queue_update_internal().

00957 {
00958         TDB_DATA data;
00959         int max_reported_jobs = lp_max_reported_jobs(pts->snum);
00960         print_queue_struct *queue = pts->queue;
00961         size_t len;
00962         size_t i;
00963         uint qcount;
00964 
00965         if (max_reported_jobs && (max_reported_jobs < pts->qcount))
00966                 pts->qcount = max_reported_jobs;
00967         qcount = 0;
00968 
00969         /* Work out the size. */
00970         data.dsize = 0;
00971         data.dsize += tdb_pack(NULL, 0, "d", qcount);
00972 
00973         for (i = 0; i < pts->qcount; i++) {
00974                 if ( queue[i].status == LPQ_DELETED )
00975                         continue;
00976 
00977                 qcount++;
00978                 data.dsize += tdb_pack(NULL, 0, "ddddddff",
00979                                 (uint32)queue[i].job,
00980                                 (uint32)queue[i].size,
00981                                 (uint32)queue[i].page_count,
00982                                 (uint32)queue[i].status,
00983                                 (uint32)queue[i].priority,
00984                                 (uint32)queue[i].time,
00985                                 queue[i].fs_user,
00986                                 queue[i].fs_file);
00987         }
00988 
00989         if ((data.dptr = (char *)SMB_MALLOC(data.dsize)) == NULL)
00990                 return;
00991 
00992         len = 0;
00993         len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
00994         for (i = 0; i < pts->qcount; i++) {
00995                 if ( queue[i].status == LPQ_DELETED )
00996                         continue;
00997 
00998                 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
00999                                 (uint32)queue[i].job,
01000                                 (uint32)queue[i].size,
01001                                 (uint32)queue[i].page_count,
01002                                 (uint32)queue[i].status,
01003                                 (uint32)queue[i].priority,
01004                                 (uint32)queue[i].time,
01005                                 queue[i].fs_user,
01006                                 queue[i].fs_file);
01007         }
01008 
01009         tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
01010                   TDB_REPLACE);
01011         SAFE_FREE(data.dptr);
01012         return;
01013 }

static TDB_DATA get_jobs_changed_data ( struct tdb_print_db pdb  )  [static]

printing.c1015 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizestring_tdb_data()tdb_print_db::tdbtdb_fetch().

参照元 print_queue_update_internal().

01016 {
01017         TDB_DATA data;
01018 
01019         ZERO_STRUCT(data);
01020 
01021         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
01022         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
01023                 SAFE_FREE(data.dptr);
01024                 ZERO_STRUCT(data);
01025         }
01026 
01027         return data;
01028 }

static void check_job_changed ( const char *  sharename,
TDB_DATA  data,
uint32  jobid 
) [static]

printing.c1030 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeremove_from_jobs_changed().

参照元 print_queue_update_internal().

01031 {
01032         unsigned int i;
01033         unsigned int job_count = data.dsize / 4;
01034 
01035         for (i = 0; i < job_count; i++) {
01036                 uint32 ch_jobid;
01037 
01038                 ch_jobid = IVAL(data.dptr, i*4);
01039                 if (ch_jobid == jobid)
01040                         remove_from_jobs_changed(sharename, jobid);
01041         }
01042 }

static BOOL print_cache_expired ( const char *  sharename,
BOOL  check_pending 
) [static]

printing.c1048 行で定義されています。

参照先 get_print_db_byname()release_print_db()resultsnprintf()tdb_print_db::tdbtdb_fetch_int32()tdb_fetch_uint32().

参照元 get_stored_queue_info()print_job_end()print_queue_length()print_queue_resume()print_queue_status()print_queue_update_with_lock().

01049 {
01050         fstring key;
01051         time_t last_qscan_time, time_now = time(NULL);
01052         struct tdb_print_db *pdb = get_print_db_byname(sharename);
01053         BOOL result = False;
01054 
01055         if (!pdb)
01056                 return False;
01057 
01058         snprintf(key, sizeof(key), "CACHE/%s", sharename);
01059         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
01060 
01061         /*
01062          * Invalidate the queue for 3 reasons.
01063          * (1). last queue scan time == -1.
01064          * (2). Current time - last queue scan time > allowed cache time.
01065          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
01066          * This last test picks up machines for which the clock has been moved
01067          * forward, an lpq scan done and then the clock moved back. Otherwise
01068          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
01069          */
01070 
01071         if (last_qscan_time == ((time_t)-1) 
01072                 || (time_now - last_qscan_time) >= lp_lpqcachetime() 
01073                 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) 
01074         {
01075                 uint32 u;
01076                 time_t msg_pending_time;
01077 
01078                 DEBUG(4, ("print_cache_expired: cache expired for queue %s " 
01079                         "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", 
01080                         sharename, (int)last_qscan_time, (int)time_now, 
01081                         (int)lp_lpqcachetime() ));
01082 
01083                 /* check if another smbd has already sent a message to update the 
01084                    queue.  Give the pending message one minute to clear and 
01085                    then send another message anyways.  Make sure to check for 
01086                    clocks that have been run forward and then back again. */
01087 
01088                 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
01089 
01090                 if ( check_pending 
01091                         && tdb_fetch_uint32( pdb->tdb, key, &u ) 
01092                         && (msg_pending_time=u) > 0
01093                         && msg_pending_time <= time_now 
01094                         && (time_now - msg_pending_time) < 60 ) 
01095                 {
01096                         DEBUG(4,("print_cache_expired: message already pending for %s.  Accepting cache\n",
01097                                 sharename));
01098                         goto done;
01099                 }
01100                 
01101                 result = True;
01102         }
01103 
01104 done:
01105         release_print_db(pdb);
01106         return result;
01107 }

static void print_queue_update_internal ( const char *  sharename,
struct printif current_printif,
char *  lpq_command,
char *  lprm_command 
) [static]

printing.c1113 行で定義されています。

参照先 check_job_changed()TDB_DATA::dptrget_jobs_changed_data()get_print_db_byname()get_queue_status()LPQ_DELETINGtraverse_struct::lpq_timetraverse_struct::lprm_commandpjob_store()traverse_struct::print_ifprint_job_find()print_parse_jobid()print_unix_job()printjob_comp()print_status_struct::qcounttraverse_struct::qcounttraverse_struct::queueprintif::queue_getrelease_print_db()traverse_struct::sharenamesnprintf()traverse_struct::snumprintjob::statusstatusstore_queue_struct()printjob::sysjobtdb_print_db::tdbtdb_store()tdb_store_int32()tdb_store_uint32()tdb_traverse()traverse_struct::total_jobstraverse_fn_delete()printif::type.

参照元 print_queue_update_with_lock().

01116 {
01117         int i, qcount;
01118         print_queue_struct *queue = NULL;
01119         print_status_struct status;
01120         print_status_struct old_status;
01121         struct printjob *pjob;
01122         struct traverse_struct tstruct;
01123         TDB_DATA data, key;
01124         TDB_DATA jcdata;
01125         fstring keystr, cachestr;
01126         struct tdb_print_db *pdb = get_print_db_byname(sharename);
01127 
01128         if (!pdb) {
01129                 return;
01130         }
01131         
01132         DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
01133                 sharename, current_printif->type, lpq_command));
01134 
01135         /*
01136          * Update the cache time FIRST ! Stops others even
01137          * attempting to get the lock and doing this
01138          * if the lpq takes a long time.
01139          */
01140          
01141         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
01142         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
01143 
01144         /* get the current queue using the appropriate interface */
01145         ZERO_STRUCT(status);
01146 
01147         qcount = (*(current_printif->queue_get))(sharename, 
01148                 current_printif->type, 
01149                 lpq_command, &queue, &status);
01150 
01151         DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n", 
01152                 qcount, (qcount != 1) ? "s" : "", sharename));
01153 
01154         /* Sort the queue by submission time otherwise they are displayed
01155            in hash order. */
01156 
01157         qsort(queue, qcount, sizeof(print_queue_struct),
01158                 QSORT_CAST(printjob_comp));
01159 
01160         /*
01161           any job in the internal database that is marked as spooled
01162           and doesn't exist in the system queue is considered finished
01163           and removed from the database
01164 
01165           any job in the system database but not in the internal database 
01166           is added as a unix job
01167 
01168           fill in any system job numbers as we go
01169         */
01170 
01171         jcdata = get_jobs_changed_data(pdb);
01172 
01173         for (i=0; i<qcount; i++) {
01174                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
01175 
01176                 if (jobid == (uint32)-1) {
01177                         /* assume its a unix print job */
01178                         print_unix_job(sharename, &queue[i], jobid);
01179                         continue;
01180                 }
01181 
01182                 /* we have an active SMB print job - update its status */
01183                 pjob = print_job_find(sharename, jobid);
01184                 if (!pjob) {
01185                         /* err, somethings wrong. Probably smbd was restarted
01186                            with jobs in the queue. All we can do is treat them
01187                            like unix jobs. Pity. */
01188                         print_unix_job(sharename, &queue[i], jobid);
01189                         continue;
01190                 }
01191 
01192                 pjob->sysjob = queue[i].job;
01193 
01194                 /* don't reset the status on jobs to be deleted */
01195 
01196                 if ( pjob->status != LPQ_DELETING )
01197                         pjob->status = queue[i].status;
01198 
01199                 pjob_store(sharename, jobid, pjob);
01200 
01201                 check_job_changed(sharename, jcdata, jobid);
01202         }
01203 
01204         SAFE_FREE(jcdata.dptr);
01205 
01206         /* now delete any queued entries that don't appear in the
01207            system queue */
01208         tstruct.queue = queue;
01209         tstruct.qcount = qcount;
01210         tstruct.snum = -1;
01211         tstruct.total_jobs = 0;
01212         tstruct.lpq_time = time(NULL);
01213         tstruct.sharename = sharename;
01214         tstruct.lprm_command = lprm_command;
01215         tstruct.print_if = current_printif;
01216 
01217         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
01218 
01219         /* Store the linearised queue, max jobs only. */
01220         store_queue_struct(pdb, &tstruct);
01221 
01222         SAFE_FREE(tstruct.queue);
01223 
01224         DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
01225                                 sharename, tstruct.total_jobs ));
01226 
01227         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
01228 
01229         get_queue_status(sharename, &old_status);
01230         if (old_status.qcount != qcount)
01231                 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
01232                                         old_status.qcount, qcount, sharename));
01233 
01234         /* store the new queue status structure */
01235         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
01236         key.dptr = keystr;
01237         key.dsize = strlen(keystr);
01238 
01239         status.qcount = qcount;
01240         data.dptr = (char *)&status;
01241         data.dsize = sizeof(status);
01242         tdb_store(pdb->tdb, key, data, TDB_REPLACE);    
01243 
01244         /*
01245          * Update the cache time again. We want to do this call
01246          * as little as possible...
01247          */
01248 
01249         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
01250         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
01251 
01252         /* clear the msg pending record for this queue */
01253 
01254         snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
01255 
01256         if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
01257                 /* log a message but continue on */
01258 
01259                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
01260                         sharename));
01261         }
01262 
01263         release_print_db( pdb );
01264 
01265         return;
01266 }

static void print_queue_update_with_lock ( const char *  sharename,
struct printif current_printif,
char *  lpq_command,
char *  lprm_command 
) [static]

printing.c1274 行で定義されています。

参照先 get_print_db_byname()get_updating_pid()print_cache_expired()print_queue_update_internal()release_print_db()set_updating_pid()tdb_print_db::tdbtdb_lock_bystring_with_timeout()tdb_unlock_bystring().

参照元 print_queue_receive()print_queue_update().

01277 {
01278         fstring keystr;
01279         struct tdb_print_db *pdb;
01280 
01281         DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
01282         pdb = get_print_db_byname(sharename);
01283         if (!pdb)
01284                 return;
01285 
01286         if ( !print_cache_expired(sharename, False) ) {
01287                 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
01288                 release_print_db(pdb);
01289                 return;
01290         }
01291         
01292         /*
01293          * Check to see if someone else is doing this update.
01294          * This is essentially a mutex on the update.
01295          */
01296 
01297         if (get_updating_pid(sharename) != -1) {
01298                 release_print_db(pdb);
01299                 return;
01300         }
01301 
01302         /* Lock the queue for the database update */
01303 
01304         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
01305         /* Only wait 10 seconds for this. */
01306         if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
01307                 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
01308                 release_print_db(pdb);
01309                 return;
01310         }
01311 
01312         /*
01313          * Ensure that no one else got in here.
01314          * If the updating pid is still -1 then we are
01315          * the winner.
01316          */
01317 
01318         if (get_updating_pid(sharename) != -1) {
01319                 /*
01320                  * Someone else is doing the update, exit.
01321                  */
01322                 tdb_unlock_bystring(pdb->tdb, keystr);
01323                 release_print_db(pdb);
01324                 return;
01325         }
01326 
01327         /*
01328          * We're going to do the update ourselves.
01329          */
01330 
01331         /* Tell others we're doing the update. */
01332         set_updating_pid(sharename, True);
01333 
01334         /*
01335          * Allow others to enter and notice we're doing
01336          * the update.
01337          */
01338 
01339         tdb_unlock_bystring(pdb->tdb, keystr);
01340 
01341         /* do the main work now */
01342         
01343         print_queue_update_internal( sharename, current_printif, 
01344                 lpq_command, lprm_command );
01345         
01346         /* Delete our pid from the db. */
01347         set_updating_pid(sharename, False);
01348         release_print_db(pdb);
01349 }

static void print_queue_receive ( int  msg_type,
struct process_id  src,
void *  buf,
size_t  msglen,
void *  private_data 
) [static]

printing.c1354 行で定義されています。

参照先 get_printer_fns_from_type()lenprint_queue_update_with_lock()tdb_unpack().

参照元 start_background_queue().

01357 {
01358         fstring sharename;
01359         pstring lpqcommand, lprmcommand;
01360         int printing_type;
01361         size_t len;
01362 
01363         len = tdb_unpack( (char *)buf, msglen, "fdPP",
01364                 sharename,
01365                 &printing_type,
01366                 lpqcommand,
01367                 lprmcommand );
01368 
01369         if ( len == -1 ) {
01370                 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
01371                 return;
01372         }
01373 
01374         print_queue_update_with_lock(sharename, 
01375                 get_printer_fns_from_type((enum printing_types)printing_type),
01376                 lpqcommand, lprmcommand );
01377 
01378         return;
01379 }

void start_background_queue ( void   ) 

printing.c1386 行で定義されています。

参照先 change_to_root_user()claim_connection()errnoexit_server_cleanly()got_sig_termlocking_init()message_dispatch()message_register()print_notify_send_messages()print_queue_receive()reload_after_sighupreload_services()strerror()sys_fork().

参照元 main().

01387 {
01388         DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
01389         background_lpq_updater_pid = sys_fork();
01390 
01391         if (background_lpq_updater_pid == -1) {
01392                 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
01393                 exit(1);
01394         }
01395 
01396         if(background_lpq_updater_pid == 0) {
01397                 /* Child. */
01398                 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
01399 
01400                 claim_connection( NULL, "smbd lpq backend", 0, False, 
01401                         FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
01402 
01403                 if (!locking_init(0)) {
01404                         exit(1);
01405                 }
01406 
01407                 message_register(MSG_PRINTER_UPDATE, print_queue_receive,
01408                                  NULL);
01409                 
01410                 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
01411                 while (1) {
01412                         pause();
01413                         
01414                         /* check for some essential signals first */
01415                         
01416                         if (got_sig_term) {
01417                                 exit_server_cleanly(NULL);
01418                         }
01419 
01420                         if (reload_after_sighup) {
01421                                 change_to_root_user();
01422                                 DEBUG(1,("Reloading services after SIGHUP\n"));
01423                                 reload_services(False);
01424                                 reload_after_sighup = 0;
01425                         }
01426                         
01427                         /* now check for messages */
01428                         
01429                         DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
01430                         message_dispatch();
01431 
01432                         /* process any pending print change notify messages */
01433 
01434                         print_notify_send_messages(0);
01435                 }
01436         }
01437 }

static void print_queue_update ( int  snum,
BOOL  force 
) [static]

printing.c1443 行で定義されています。

参照先 current_usercurrent_user_infouserdom_struct::domainget_current_username()get_print_db_byname()get_printer_fns()_unix_token::gidlenmessage_send_pid()pid_to_procid()print_queue_update_with_lock()release_print_db()snprintf()standard_sub_advanced()string_sub2()tdb_print_db::tdbtdb_pack()tdb_store_uint32()typeuserdom_struct::unix_namecurrent_user::ut.

参照元 get_stored_queue_info()print_job_delete()print_job_end()print_queue_length()print_queue_purge()print_queue_resume()print_queue_status().

01444 {
01445         fstring key;
01446         fstring sharename;
01447         pstring lpqcommand, lprmcommand;
01448         char *buffer = NULL;
01449         size_t len = 0;
01450         size_t newlen;
01451         struct tdb_print_db *pdb;
01452         int type;
01453         struct printif *current_printif;
01454 
01455         fstrcpy( sharename, lp_const_servicename(snum));
01456 
01457         /* don't strip out characters like '$' from the printername */
01458         
01459         pstrcpy( lpqcommand, lp_lpqcommand(snum));
01460         string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), 
01461                      False, False, False );
01462         standard_sub_advanced(lp_servicename(snum),
01463                               current_user_info.unix_name, "",
01464                               current_user.ut.gid,
01465                               get_current_username(),
01466                               current_user_info.domain,
01467                               lpqcommand, sizeof(lpqcommand) );
01468         
01469         pstrcpy( lprmcommand, lp_lprmcommand(snum));
01470         string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), 
01471                      False, False, False );
01472         standard_sub_advanced(lp_servicename(snum),
01473                               current_user_info.unix_name, "",
01474                               current_user.ut.gid,
01475                               get_current_username(),
01476                               current_user_info.domain,
01477                               lprmcommand, sizeof(lprmcommand) );
01478         
01479         /* 
01480          * Make sure that the background queue process exists.  
01481          * Otherwise just do the update ourselves 
01482          */
01483         
01484         if ( force || background_lpq_updater_pid == -1 ) {
01485                 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
01486                 current_printif = get_printer_fns( snum );
01487                 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
01488 
01489                 return;
01490         }
01491 
01492         type = lp_printing(snum);
01493         
01494         /* get the length */
01495 
01496         len = tdb_pack( NULL, 0, "fdPP",
01497                 sharename,
01498                 type,
01499                 lpqcommand, 
01500                 lprmcommand );
01501 
01502         buffer = SMB_XMALLOC_ARRAY( char, len );
01503 
01504         /* now pack the buffer */
01505         newlen = tdb_pack( buffer, len, "fdPP",
01506                 sharename,
01507                 type,
01508                 lpqcommand,
01509                 lprmcommand );
01510 
01511         SMB_ASSERT( newlen == len );
01512 
01513         DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
01514                 "type = %d, lpq command = [%s] lprm command = [%s]\n", 
01515                 sharename, type, lpqcommand, lprmcommand ));
01516 
01517         /* here we set a msg pending record for other smbd processes 
01518            to throttle the number of duplicate print_queue_update msgs
01519            sent.  */
01520 
01521         pdb = get_print_db_byname(sharename);
01522         if (!pdb) {
01523                 SAFE_FREE(buffer);
01524                 return;
01525         }
01526 
01527         snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
01528 
01529         if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
01530                 /* log a message but continue on */
01531 
01532                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
01533                         sharename));
01534         }
01535 
01536         release_print_db( pdb );
01537 
01538         /* finally send the message */
01539         
01540         message_send_pid(pid_to_procid(background_lpq_updater_pid),
01541                  MSG_PRINTER_UPDATE, buffer, len, False);
01542 
01543         SAFE_FREE( buffer );
01544 
01545         return;
01546 }

BOOL print_notify_register_pid ( int  snum  ) 

printing.c1553 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeget_print_db_byname()get_printer_notify_pid_list()lp_snum_ok()mypidrelease_print_db()sys_getpid()tdb_print_db::tdbtdbtdb_lock_bystring_with_timeout().

参照元 srv_spoolss_replyopenprinter().

01554 {
01555         TDB_DATA data;
01556         struct tdb_print_db *pdb = NULL;
01557         TDB_CONTEXT *tdb = NULL;
01558         const char *printername;
01559         uint32 mypid = (uint32)sys_getpid();
01560         BOOL ret = False;
01561         size_t i;
01562 
01563         /* if (snum == -1), then the change notify request was
01564            on a print server handle and we need to register on
01565            all print queus */
01566            
01567         if (snum == -1) 
01568         {
01569                 int num_services = lp_numservices();
01570                 int idx;
01571                 
01572                 for ( idx=0; idx<num_services; idx++ ) {
01573                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
01574                                 print_notify_register_pid(idx);
01575                 }
01576                 
01577                 return True;
01578         }
01579         else /* register for a specific printer */
01580         {
01581                 printername = lp_const_servicename(snum);
01582                 pdb = get_print_db_byname(printername);
01583                 if (!pdb)
01584                         return False;
01585                 tdb = pdb->tdb;
01586         }
01587 
01588         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
01589                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
01590                                         printername));
01591                 if (pdb)
01592                         release_print_db(pdb);
01593                 return False;
01594         }
01595 
01596         data = get_printer_notify_pid_list( tdb, printername, True );
01597 
01598         /* Add ourselves and increase the refcount. */
01599 
01600         for (i = 0; i < data.dsize; i += 8) {
01601                 if (IVAL(data.dptr,i) == mypid) {
01602                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
01603                         SIVAL(data.dptr, i+4, new_refcount);
01604                         break;
01605                 }
01606         }
01607 
01608         if (i == data.dsize) {
01609                 /* We weren't in the list. Realloc. */
01610                 data.dptr = (char *)SMB_REALLOC(data.dptr, data.dsize + 8);
01611                 if (!data.dptr) {
01612                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
01613                                                 printername));
01614                         goto done;
01615                 }
01616                 data.dsize += 8;
01617                 SIVAL(data.dptr,data.dsize - 8,mypid);
01618                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
01619         }
01620 
01621         /* Store back the record. */
01622         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
01623                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
01624 list for printer %s\n", printername));
01625                 goto done;
01626         }
01627 
01628         ret = True;
01629 
01630  done:
01631 
01632         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
01633         if (pdb)
01634                 release_print_db(pdb);
01635         SAFE_FREE(data.dptr);
01636         return ret;
01637 }

BOOL print_notify_deregister_pid ( int  snum  ) 

printing.c1644 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeget_print_db_byname()get_printer_notify_pid_list()lp_snum_ok()mypidrelease_print_db()sys_getpid()tdb_print_db::tdbtdbtdb_lock_bystring_with_timeout().

参照元 srv_spoolss_replycloseprinter().

01645 {
01646         TDB_DATA data;
01647         struct tdb_print_db *pdb = NULL;
01648         TDB_CONTEXT *tdb = NULL;
01649         const char *printername;
01650         uint32 mypid = (uint32)sys_getpid();
01651         size_t i;
01652         BOOL ret = False;
01653 
01654         /* if ( snum == -1 ), we are deregister a print server handle
01655            which means to deregister on all print queues */
01656            
01657         if (snum == -1) 
01658         {
01659                 int num_services = lp_numservices();
01660                 int idx;
01661                 
01662                 for ( idx=0; idx<num_services; idx++ ) {
01663                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
01664                                 print_notify_deregister_pid(idx);
01665                 }
01666                 
01667                 return True;
01668         }
01669         else /* deregister a specific printer */
01670         {
01671                 printername = lp_const_servicename(snum);
01672                 pdb = get_print_db_byname(printername);
01673                 if (!pdb)
01674                         return False;
01675                 tdb = pdb->tdb;
01676         }
01677 
01678         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
01679                 DEBUG(0,("print_notify_register_pid: Failed to lock \
01680 printer %s database\n", printername));
01681                 if (pdb)
01682                         release_print_db(pdb);
01683                 return False;
01684         }
01685 
01686         data = get_printer_notify_pid_list( tdb, printername, True );
01687 
01688         /* Reduce refcount. Remove ourselves if zero. */
01689 
01690         for (i = 0; i < data.dsize; ) {
01691                 if (IVAL(data.dptr,i) == mypid) {
01692                         uint32 refcount = IVAL(data.dptr, i+4);
01693 
01694                         refcount--;
01695 
01696                         if (refcount == 0) {
01697                                 if (data.dsize - i > 8)
01698                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
01699                                 data.dsize -= 8;
01700                                 continue;
01701                         }
01702                         SIVAL(data.dptr, i+4, refcount);
01703                 }
01704 
01705                 i += 8;
01706         }
01707 
01708         if (data.dsize == 0)
01709                 SAFE_FREE(data.dptr);
01710 
01711         /* Store back the record. */
01712         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
01713                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
01714 list for printer %s\n", printername));
01715                 goto done;
01716         }
01717 
01718         ret = True;
01719 
01720   done:
01721 
01722         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
01723         if (pdb)
01724                 release_print_db(pdb);
01725         SAFE_FREE(data.dptr);
01726         return ret;
01727 }

BOOL print_job_exists ( const char *  sharename,
uint32  jobid 
)

printing.c1733 行で定義されています。

参照先 get_print_db_byname()print_key()release_print_db()tdb_print_db::tdbtdb_exists().

参照元 _spoolss_setjob()api_PrintJobInfo()api_RDosPrintJobDel().

01734 {
01735         struct tdb_print_db *pdb = get_print_db_byname(sharename);
01736         BOOL ret;
01737 
01738         if (!pdb)
01739                 return False;
01740         ret = tdb_exists(pdb->tdb, print_key(jobid));
01741         release_print_db(pdb);
01742         return ret;
01743 }

int print_job_fd ( const char *  sharename,
uint32  jobid 
)

printing.c1749 行で定義されています。

参照先 printjob::fdprintjob::pidprint_job_find()sys_getpid().

参照元 print_fsp_open().

01750 {
01751         struct printjob *pjob = print_job_find(sharename, jobid);
01752         if (!pjob)
01753                 return -1;
01754         /* don't allow another process to get this info - it is meaningless */
01755         if (pjob->pid != sys_getpid())
01756                 return -1;
01757         return pjob->fd;
01758 }

char* print_job_fname ( const char *  sharename,
uint32  jobid 
)

printing.c1766 行で定義されています。

参照先 printjob::filenameprintjob::pidprint_job_find()printjob::spooledsys_getpid().

参照元 print_fsp_open()print_job_delete().

01767 {
01768         struct printjob *pjob = print_job_find(sharename, jobid);
01769         if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
01770                 return NULL;
01771         return pjob->filename;
01772 }

NT_DEVICEMODE* print_job_devmode ( const char *  sharename,
uint32  jobid 
)

printing.c1781 行で定義されています。

参照先 printjob::nt_devmodeprint_job_find().

参照元 getjob_level_2().

01782 {
01783         struct printjob *pjob = print_job_find(sharename, jobid);
01784         
01785         if ( !pjob )
01786                 return NULL;
01787                 
01788         return pjob->nt_devmode;
01789 }

BOOL print_job_set_place ( const char *  sharename,
uint32  jobid,
int  place 
)

printing.c1795 行で定義されています。

参照元 api_PrintJobInfo().

01796 {
01797         DEBUG(2,("print_job_set_place not implemented yet\n"));
01798         return False;
01799 }

BOOL print_job_set_name ( const char *  sharename,
uint32  jobid,
char *  name 
)

printing.c1805 行で定義されています。

参照先 printjob::jobnameprintjob::pidpjob_store()print_job_find()sys_getpid().

参照元 api_PrintJobInfo().

01806 {
01807         struct printjob *pjob;
01808 
01809         pjob = print_job_find(sharename, jobid);
01810         if (!pjob || pjob->pid != sys_getpid())
01811                 return False;
01812 
01813         fstrcpy(pjob->jobname, name);
01814         return pjob_store(sharename, jobid, pjob);
01815 }

static BOOL print_job_delete1 ( int  snum,
uint32  jobid 
) [static]

printing.c1880 行で定義されています。

参照先 get_print_db_byname()get_printer_fns()printif::job_deleteLPQ_DELETINGpjob_delete()pjob_store()print_job_find()release_print_db()remove_from_jobs_changed()resultprintjob::spooledprintjob::statusprintjob::sysjobtdb_print_db::tdbtdb_change_int32_atomic().

参照元 print_job_delete()print_queue_purge().

01881 {
01882         const char* sharename = lp_const_servicename(snum);
01883         struct printjob *pjob = print_job_find(sharename, jobid);
01884         int result = 0;
01885         struct printif *current_printif = get_printer_fns( snum );
01886 
01887         if (!pjob)
01888                 return False;
01889 
01890         /*
01891          * If already deleting just return.
01892          */
01893 
01894         if (pjob->status == LPQ_DELETING)
01895                 return True;
01896 
01897         /* Hrm - we need to be able to cope with deleting a job before it
01898            has reached the spooler.  Just mark it as LPQ_DELETING and 
01899            let the print_queue_update() code rmeove the record */
01900            
01901 
01902         if (pjob->sysjob == -1) {
01903                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
01904         }
01905 
01906         /* Set the tdb entry to be deleting. */
01907 
01908         pjob->status = LPQ_DELETING;
01909         pjob_store(sharename, jobid, pjob);
01910 
01911         if (pjob->spooled && pjob->sysjob != -1) 
01912         {
01913                 result = (*(current_printif->job_delete))(
01914                         PRINTERNAME(snum),
01915                         lp_lprmcommand(snum), 
01916                         pjob);
01917 
01918                 /* Delete the tdb entry if the delete succeeded or the job hasn't
01919                    been spooled. */
01920 
01921                 if (result == 0) {
01922                         struct tdb_print_db *pdb = get_print_db_byname(sharename);
01923                         int njobs = 1;
01924 
01925                         if (!pdb)
01926                                 return False;
01927                         pjob_delete(sharename, jobid);
01928                         /* Ensure we keep a rough count of the number of total jobs... */
01929                         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
01930                         release_print_db(pdb);
01931                 }
01932         }
01933 
01934         remove_from_jobs_changed( sharename, jobid );
01935 
01936         return (result == 0);
01937 }

static BOOL is_owner ( struct current_user user,
const char *  servicename,
uint32  jobid 
) [static]

printing.c1943 行で定義されています。

参照先 get_valid_user_struct()print_job_find()userdom_struct::smb_namestrequal()uidtoname()user_struct::userprintjob::user.

参照元 print_job_delete()print_job_pause()print_job_resume()print_queue_purge().

01945 {
01946         struct printjob *pjob = print_job_find(servicename, jobid);
01947         user_struct *vuser;
01948 
01949         if (!pjob || !user)
01950                 return False;
01951 
01952         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
01953                 return strequal(pjob->user, vuser->user.smb_name);
01954         } else {
01955                 return strequal(pjob->user, uidtoname(user->ut.uid));
01956         }
01957 }

BOOL print_job_delete ( struct current_user user,
int  snum,
uint32  jobid,
WERROR errcode 
)

printing.c1963 行で定義されています。

参照先 errnois_owner()LPQ_DELETINGmap_werror_from_unix()print_access_check()print_job_delete1()print_job_find()print_job_fname()print_queue_update()printjob::statussys_adminlog()uidtoname()printjob::user.

参照元 _spoolss_abortprinter()_spoolss_setjob()api_RDosPrintJobDel().

01964 {
01965         const char* sharename = lp_const_servicename( snum );
01966         struct printjob *pjob;
01967         BOOL    owner;
01968         char    *fname;
01969 
01970         *errcode = WERR_OK;
01971                 
01972         owner = is_owner(user, lp_const_servicename(snum), jobid);
01973         
01974         /* Check access against security descriptor or whether the user
01975            owns their job. */
01976 
01977         if (!owner && 
01978             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
01979                 DEBUG(3, ("delete denied by security descriptor\n"));
01980                 *errcode = WERR_ACCESS_DENIED;
01981 
01982                 /* BEGIN_ADMIN_LOG */
01983                 sys_adminlog( LOG_ERR, 
01984                               "Permission denied-- user not allowed to delete, \
01985 pause, or resume print job. User name: %s. Printer name: %s.",
01986                               uidtoname(user->ut.uid), PRINTERNAME(snum) );
01987                 /* END_ADMIN_LOG */
01988 
01989                 return False;
01990         }
01991 
01992         /* 
01993          * get the spooled filename of the print job
01994          * if this works, then the file has not been spooled
01995          * to the underlying print system.  Just delete the 
01996          * spool file & return.
01997          */
01998          
01999         if ( (fname = print_job_fname( sharename, jobid )) != NULL )
02000         {
02001                 /* remove the spool file */
02002                 DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
02003                 if ( unlink( fname ) == -1 ) {
02004                         *errcode = map_werror_from_unix(errno);
02005                         return False;
02006                 }
02007         }
02008         
02009         if (!print_job_delete1(snum, jobid)) {
02010                 *errcode = WERR_ACCESS_DENIED;
02011                 return False;
02012         }
02013 
02014         /* force update the database and say the delete failed if the
02015            job still exists */
02016 
02017         print_queue_update(snum, True);
02018         
02019         pjob = print_job_find(sharename, jobid);
02020         if ( pjob && (pjob->status != LPQ_DELETING) )
02021                 *errcode = WERR_ACCESS_DENIED;
02022 
02023         return (pjob == NULL );
02024 }

BOOL print_job_pause ( struct current_user user,
int  snum,
uint32  jobid,
WERROR errcode 
)

printing.c2030 行で定義されています。

参照先 get_printer_fns()is_owner()printif::job_pausenotify_job_status()print_access_check()print_cache_flush()print_job_find()printjob::spooledsys_adminlog()printjob::sysjob_unix_token::uiduidtoname()current_user::ut.

参照元 _spoolss_setjob()api_RDosPrintJobDel().

02031 {
02032         const char* sharename = lp_const_servicename(snum);
02033         struct printjob *pjob;
02034         int ret = -1;
02035         struct printif *current_printif = get_printer_fns( snum );
02036 
02037         pjob = print_job_find(sharename, jobid);
02038         
02039         if (!pjob || !user) {
02040                 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
02041                         (unsigned int)jobid ));
02042                 return False;
02043         }
02044 
02045         if (!pjob->spooled || pjob->sysjob == -1) {
02046                 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
02047                         (int)pjob->sysjob, (unsigned int)jobid ));
02048                 return False;
02049         }
02050 
02051         if (!is_owner(user, lp_const_servicename(snum), jobid) &&
02052             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
02053                 DEBUG(3, ("pause denied by security descriptor\n"));
02054 
02055                 /* BEGIN_ADMIN_LOG */
02056                 sys_adminlog( LOG_ERR, 
02057                         "Permission denied-- user not allowed to delete, \
02058 pause, or resume print job. User name: %s. Printer name: %s.",
02059                                 uidtoname(user->ut.uid), PRINTERNAME(snum) );
02060                 /* END_ADMIN_LOG */
02061 
02062                 *errcode = WERR_ACCESS_DENIED;
02063                 return False;
02064         }
02065 
02066         /* need to pause the spooled entry */
02067         ret = (*(current_printif->job_pause))(snum, pjob);
02068 
02069         if (ret != 0) {
02070                 *errcode = WERR_INVALID_PARAM;
02071                 return False;
02072         }
02073 
02074         /* force update the database */
02075         print_cache_flush(lp_const_servicename(snum));
02076 
02077         /* Send a printer notify message */
02078 
02079         notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
02080 
02081         /* how do we tell if this succeeded? */
02082 
02083         return True;
02084 }

BOOL print_job_resume ( struct current_user user,
int  snum,
uint32  jobid,
WERROR errcode 
)

printing.c2090 行で定義されています。

参照先 get_printer_fns()is_owner()printif::job_resumenotify_job_status()print_access_check()print_cache_flush()print_job_find()printjob::spooledsys_adminlog()printjob::sysjob_unix_token::uiduidtoname()current_user::ut.

参照元 _spoolss_setjob()api_RDosPrintJobDel().

02091 {
02092         const char *sharename = lp_const_servicename(snum);
02093         struct printjob *pjob;
02094         int ret;
02095         struct printif *current_printif = get_printer_fns( snum );
02096 
02097         pjob = print_job_find(sharename, jobid);
02098         
02099         if (!pjob || !user) {
02100                 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
02101                         (unsigned int)jobid ));
02102                 return False;
02103         }
02104 
02105         if (!pjob->spooled || pjob->sysjob == -1) {
02106                 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
02107                         (int)pjob->sysjob, (unsigned int)jobid ));
02108                 return False;
02109         }
02110 
02111         if (!is_owner(user, lp_const_servicename(snum), jobid) &&
02112             !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
02113                 DEBUG(3, ("resume denied by security descriptor\n"));
02114                 *errcode = WERR_ACCESS_DENIED;
02115 
02116                 /* BEGIN_ADMIN_LOG */
02117                 sys_adminlog( LOG_ERR, 
02118                          "Permission denied-- user not allowed to delete, \
02119 pause, or resume print job. User name: %s. Printer name: %s.",
02120                         uidtoname(user->ut.uid), PRINTERNAME(snum) );
02121                 /* END_ADMIN_LOG */
02122                 return False;
02123         }
02124 
02125         ret = (*(current_printif->job_resume))(snum, pjob);
02126 
02127         if (ret != 0) {
02128                 *errcode = WERR_INVALID_PARAM;
02129                 return False;
02130         }
02131 
02132         /* force update the database */
02133         print_cache_flush(lp_const_servicename(snum));
02134 
02135         /* Send a printer notify message */
02136 
02137         notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
02138 
02139         return True;
02140 }

ssize_t print_job_write ( int  snum,
uint32  jobid,
const char *  buf,
SMB_OFF_T  pos,
size_t  size 
)

printing.c2146 行で定義されています。

参照先 printjob::fdprintjob::pidpjob_store()print_job_find()printjob::sizesys_getpid()write_data_at_offset().

参照元 _spoolss_writeprinter()write_file().

02147 {
02148         const char* sharename = lp_const_servicename(snum);
02149         int return_code;
02150         struct printjob *pjob;
02151 
02152         pjob = print_job_find(sharename, jobid);
02153 
02154         if (!pjob)
02155                 return -1;
02156         /* don't allow another process to get this info - it is meaningless */
02157         if (pjob->pid != sys_getpid())
02158                 return -1;
02159 
02160         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
02161 
02162         if (return_code>0) {
02163                 pjob->size += size;
02164                 pjob_store(sharename, jobid, pjob);
02165         }
02166         return return_code;
02167 }

int print_queue_length ( int  snum,
print_status_struct pstatus 
)

printing.c2207 行で定義されています。

参照先 get_queue_status()lenprint_cache_expired()print_queue_update()status.

参照元 construct_printer_info_0()construct_printer_info_2()print_job_start()spoolss_notify_cjobs()spoolss_notify_status().

02208 {
02209         const char* sharename = lp_const_servicename( snum );
02210         print_status_struct status;
02211         int len;
02212 
02213         ZERO_STRUCT( status );
02214  
02215         /* make sure the database is up to date */
02216         if (print_cache_expired(lp_const_servicename(snum), True))
02217                 print_queue_update(snum, False);
02218  
02219         /* also fetch the queue status */
02220         memset(&status, 0, sizeof(status));
02221         len = get_queue_status(sharename, &status);
02222 
02223         if (pstatus)
02224                 *pstatus = status;
02225 
02226         return len;
02227 }

static BOOL allocate_print_jobid ( struct tdb_print_db pdb,
int  snum,
const char *  sharename,
uint32 *  pjobid 
) [static]

printing.c2233 行で定義されています。

参照先 tdb_print_db::tdbTDB_ERR_NOEXISTtdb_error()tdb_fetch_uint32()tdb_lock_bystring_with_timeout().

参照元 print_job_start().

02234 {
02235         int i;
02236         uint32 jobid;
02237 
02238         *pjobid = (uint32)-1;
02239 
02240         for (i = 0; i < 3; i++) {
02241                 /* Lock the database - only wait 20 seconds. */
02242                 if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) {
02243                         DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
02244                         return False;
02245                 }
02246 
02247                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
02248                         if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
02249                                 DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
02250                                         sharename));
02251                                 return False;
02252                         }
02253                         jobid = 0;
02254                 }
02255 
02256                 jobid = NEXT_JOBID(jobid);
02257 
02258                 if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
02259                         DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
02260                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
02261                         return False;
02262                 }
02263 
02264                 /* We've finished with the INFO/nextjob lock. */
02265                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
02266                                 
02267                 if (!print_job_exists(sharename, jobid))
02268                         break;
02269         }
02270 
02271         if (i > 2) {
02272                 DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
02273                         sharename));
02274                 /* Probably full... */
02275                 errno = ENOSPC;
02276                 return False;
02277         }
02278 
02279         /* Store a dummy placeholder. */
02280         {
02281                 TDB_DATA dum;
02282                 dum.dptr = NULL;
02283                 dum.dsize = 0;
02284                 if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
02285                         DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
02286                                 jobid ));
02287                         return False;
02288                 }
02289         }
02290 
02291         *pjobid = jobid;
02292         return True;
02293 }

static BOOL add_to_jobs_changed ( struct tdb_print_db pdb,
uint32  jobid 
) [static]

printing.c2299 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizestring_tdb_data()tdb_print_db::tdbtdb_append().

参照元 print_job_start().

02300 {
02301         TDB_DATA data;
02302         uint32 store_jobid;
02303 
02304         SIVAL(&store_jobid, 0, jobid);
02305         data.dptr = (char *)&store_jobid;
02306         data.dsize = 4;
02307 
02308         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
02309 
02310         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
02311                            data) == 0);
02312 }

uint32 print_job_start ( struct current_user user,
int  snum,
char *  jobname,
NT_DEVICEMODE nt_devmode 
)

printing.c2318 行で定義されています。

参照先 add_to_jobs_changed()allocate_print_jobid()errnoprintjob::fdprintjob::filenameget_print_db_byname()get_valid_user_struct()printjob::jobnameLPQ_SPOOLINGprintjob::nt_devmodepcap_printername_ok()printjob::pidpjob_delete()pjob_store()print_access_check()print_queue_length()print_time_access_check()printjob::queuenamerelease_print_db()printjob::sizesmb_mkstemp()printjob::smbjobprintjob::spooledstandard_sub_advanced()printjob::starttimeprintjob::statusstrerror()sys_fsusage()sys_getpid()printjob::sysjobtdb_print_db::tdbtdb_change_int32_atomic()_unix_token::uiduidtoname()printjob::usercurrent_user::utcurrent_user::vuid.

参照元 _spoolss_startdocprinter()print_fsp_open().

02319 {
02320         uint32 jobid;
02321         char *path;
02322         struct printjob pjob;
02323         user_struct *vuser;
02324         const char *sharename = lp_const_servicename(snum);
02325         struct tdb_print_db *pdb = get_print_db_byname(sharename);
02326         int njobs;
02327 
02328         errno = 0;
02329 
02330         if (!pdb)
02331                 return (uint32)-1;
02332 
02333         if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
02334                 DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
02335                 release_print_db(pdb);
02336                 return (uint32)-1;
02337         }
02338 
02339         if (!print_time_access_check(lp_servicename(snum))) {
02340                 DEBUG(3, ("print_job_start: job start denied by time check\n"));
02341                 release_print_db(pdb);
02342                 return (uint32)-1;
02343         }
02344 
02345         path = lp_pathname(snum);
02346 
02347         /* see if we have sufficient disk space */
02348         if (lp_minprintspace(snum)) {
02349                 SMB_BIG_UINT dspace, dsize;
02350                 if (sys_fsusage(path, &dspace, &dsize) == 0 &&
02351                     dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
02352                         DEBUG(3, ("print_job_start: disk space check failed.\n"));
02353                         release_print_db(pdb);
02354                         errno = ENOSPC;
02355                         return (uint32)-1;
02356                 }
02357         }
02358 
02359         /* for autoloaded printers, check that the printcap entry still exists */
02360         if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
02361                 DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
02362                 release_print_db(pdb);
02363                 errno = ENOENT;
02364                 return (uint32)-1;
02365         }
02366 
02367         /* Insure the maximum queue size is not violated */
02368         if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
02369                 DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
02370                         sharename, njobs, lp_maxprintjobs(snum) ));
02371                 release_print_db(pdb);
02372                 errno = ENOSPC;
02373                 return (uint32)-1;
02374         }
02375 
02376         DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
02377                 sharename, njobs, lp_maxprintjobs(snum) ));
02378 
02379         if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
02380                 goto fail;
02381 
02382         /* create the database entry */
02383         
02384         ZERO_STRUCT(pjob);
02385         
02386         pjob.pid = sys_getpid();
02387         pjob.sysjob = -1;
02388         pjob.fd = -1;
02389         pjob.starttime = time(NULL);
02390         pjob.status = LPQ_SPOOLING;
02391         pjob.size = 0;
02392         pjob.spooled = False;
02393         pjob.smbjob = True;
02394         pjob.nt_devmode = nt_devmode;
02395         
02396         fstrcpy(pjob.jobname, jobname);
02397 
02398         if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
02399                 fstrcpy(pjob.user, lp_printjob_username(snum));
02400                 standard_sub_advanced(sharename, vuser->user.smb_name, path, 
02401                                         vuser->gid, vuser->user.smb_name, 
02402                                         vuser->user.domain, pjob.user, 
02403                                         sizeof(pjob.user) - 1);
02404                 /* ensure NULL termination */ 
02405                 pjob.user[sizeof(pjob.user)-1] = '\0'; 
02406         } else {
02407                 fstrcpy(pjob.user, uidtoname(user->ut.uid));
02408         }
02409 
02410         fstrcpy(pjob.queuename, lp_const_servicename(snum));
02411 
02412         /* we have a job entry - now create the spool file */
02413         slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 
02414                  path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
02415         pjob.fd = smb_mkstemp(pjob.filename);
02416 
02417         if (pjob.fd == -1) {
02418                 if (errno == EACCES) {
02419                         /* Common setup error, force a report. */
02420                         DEBUG(0, ("print_job_start: insufficient permissions \
02421 to open spool file %s.\n", pjob.filename));
02422                 } else {
02423                         /* Normal case, report at level 3 and above. */
02424                         DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
02425                         DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
02426                 }
02427                 goto fail;
02428         }
02429 
02430         pjob_store(sharename, jobid, &pjob);
02431 
02432         /* Update the 'jobs changed' entry used by print_queue_status. */
02433         add_to_jobs_changed(pdb, jobid);
02434 
02435         /* Ensure we keep a rough count of the number of total jobs... */
02436         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
02437 
02438         release_print_db(pdb);
02439 
02440         return jobid;
02441 
02442  fail:
02443         if (jobid != -1)
02444                 pjob_delete(sharename, jobid);
02445 
02446         release_print_db(pdb);
02447 
02448         DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
02449         return (uint32)-1;
02450 }

void print_job_endpage ( int  snum,
uint32  jobid 
)

printing.c2456 行で定義されています。

参照先 printjob::page_countprintjob::pidpjob_store()print_job_find()sys_getpid().

参照元 _spoolss_endpageprinter().

02457 {
02458         const char* sharename = lp_const_servicename(snum);
02459         struct printjob *pjob;
02460 
02461         pjob = print_job_find(sharename, jobid);
02462         if (!pjob)
02463                 return;
02464         /* don't allow another process to get this info - it is meaningless */
02465         if (pjob->pid != sys_getpid())
02466                 return;
02467 
02468         pjob->page_count++;
02469         pjob_store(sharename, jobid, pjob);
02470 }

BOOL print_job_end ( int  snum,
uint32  jobid,
enum file_close_type  close_type 
)

printing.c2478 行で定義されています。

参照先 printjob::fdprintjob::filenameget_printer_fns()printif::job_submitLPQ_DELETINGLPQ_QUEUEDNORMAL_CLOSEprintjob::pidpjob_delete()pjob_store()print_cache_expired()print_job_find()print_queue_update()SHUTDOWN_CLOSEprintjob::sizeprintjob::smbjobprintjob::spooledprintjob::statussys_fstat()sys_getpid().

参照元 _spoolss_enddocprinter_internal()print_fsp_end().

02479 {
02480         const char* sharename = lp_const_servicename(snum);
02481         struct printjob *pjob;
02482         int ret;
02483         SMB_STRUCT_STAT sbuf;
02484         struct printif *current_printif = get_printer_fns( snum );
02485 
02486         pjob = print_job_find(sharename, jobid);
02487 
02488         if (!pjob)
02489                 return False;
02490 
02491         if (pjob->spooled || pjob->pid != sys_getpid())
02492                 return False;
02493 
02494         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
02495                                 (sys_fstat(pjob->fd, &sbuf) == 0)) {
02496                 pjob->size = sbuf.st_size;
02497                 close(pjob->fd);
02498                 pjob->fd = -1;
02499         } else {
02500 
02501                 /* 
02502                  * Not a normal close or we couldn't stat the job file,
02503                  * so something has gone wrong. Cleanup.
02504                  */
02505                 close(pjob->fd);
02506                 pjob->fd = -1;
02507                 DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
02508                 goto fail;
02509         }
02510 
02511         /* Technically, this is not quite right. If the printer has a separator
02512          * page turned on, the NT spooler prints the separator page even if the
02513          * print job is 0 bytes. 010215 JRR */
02514         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
02515                 /* don't bother spooling empty files or something being deleted. */
02516                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
02517                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
02518                 unlink(pjob->filename);
02519                 pjob_delete(sharename, jobid);
02520                 return True;
02521         }
02522 
02523         pjob->smbjob = jobid;
02524 
02525         ret = (*(current_printif->job_submit))(snum, pjob);
02526 
02527         if (ret)
02528                 goto fail;
02529 
02530         /* The print job has been successfully handed over to the back-end */
02531         
02532         pjob->spooled = True;
02533         pjob->status = LPQ_QUEUED;
02534         pjob_store(sharename, jobid, pjob);
02535         
02536         /* make sure the database is up to date */
02537         if (print_cache_expired(lp_const_servicename(snum), True))
02538                 print_queue_update(snum, False);
02539         
02540         return True;
02541 
02542 fail:
02543 
02544         /* The print job was not successfully started. Cleanup */
02545         /* Still need to add proper error return propagation! 010122:JRR */
02546         unlink(pjob->filename);
02547         pjob_delete(sharename, jobid);
02548         return False;
02549 }

static BOOL get_stored_queue_info ( struct tdb_print_db pdb,
int  snum,
int *  pcount,
print_queue_struct **  ppqueue 
) [static]

printing.c2555 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsize_print_queue_struct::fs_file_print_queue_struct::fs_user_print_queue_struct::jobprintjob::jobnamelenprintjob::page_count_print_queue_struct::page_countprint_cache_expired()print_job_find()print_queue_update()printjob_comp()_print_queue_struct::priorityremove_from_jobs_changed()printjob::size_print_queue_struct::sizeprintjob::starttimeprintjob::status_print_queue_struct::statusstring_tdb_data()tdb_print_db::tdbtdb_fetch()tdb_unpack()_print_queue_struct::timeprintjob::user.

参照元 print_queue_status().

02556 {
02557         TDB_DATA data, cgdata;
02558         print_queue_struct *queue = NULL;
02559         uint32 qcount = 0;
02560         uint32 extra_count = 0;
02561         int total_count = 0;
02562         size_t len = 0;
02563         uint32 i;
02564         int max_reported_jobs = lp_max_reported_jobs(snum);
02565         BOOL ret = False;
02566         const char* sharename = lp_servicename(snum);
02567 
02568         /* make sure the database is up to date */
02569         if (print_cache_expired(lp_const_servicename(snum), True))
02570                 print_queue_update(snum, False);
02571  
02572         *pcount = 0;
02573         *ppqueue = NULL;
02574 
02575         ZERO_STRUCT(data);
02576         ZERO_STRUCT(cgdata);
02577 
02578         /* Get the stored queue data. */
02579         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
02580         
02581         if (data.dptr && data.dsize >= sizeof(qcount))
02582                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
02583                 
02584         /* Get the changed jobs list. */
02585         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
02586         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
02587                 extra_count = cgdata.dsize/4;
02588 
02589         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
02590 
02591         /* Allocate the queue size. */
02592         if (qcount == 0 && extra_count == 0)
02593                 goto out;
02594 
02595         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
02596                 goto out;
02597 
02598         /* Retrieve the linearised queue data. */
02599 
02600         for( i  = 0; i < qcount; i++) {
02601                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
02602                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
02603                                 &qjob,
02604                                 &qsize,
02605                                 &qpage_count,
02606                                 &qstatus,
02607                                 &qpriority,
02608                                 &qtime,
02609                                 queue[i].fs_user,
02610                                 queue[i].fs_file);
02611                 queue[i].job = qjob;
02612                 queue[i].size = qsize;
02613                 queue[i].page_count = qpage_count;
02614                 queue[i].status = qstatus;
02615                 queue[i].priority = qpriority;
02616                 queue[i].time = qtime;
02617         }
02618 
02619         total_count = qcount;
02620 
02621         /* Add in the changed jobids. */
02622         for( i  = 0; i < extra_count; i++) {
02623                 uint32 jobid;
02624                 struct printjob *pjob;
02625 
02626                 jobid = IVAL(cgdata.dptr, i*4);
02627                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
02628                 pjob = print_job_find(lp_const_servicename(snum), jobid);
02629                 if (!pjob) {
02630                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
02631                         remove_from_jobs_changed(sharename, jobid);
02632                         continue;
02633                 }
02634 
02635                 queue[total_count].job = jobid;
02636                 queue[total_count].size = pjob->size;
02637                 queue[total_count].page_count = pjob->page_count;
02638                 queue[total_count].status = pjob->status;
02639                 queue[total_count].priority = 1;
02640                 queue[total_count].time = pjob->starttime;
02641                 fstrcpy(queue[total_count].fs_user, pjob->user);
02642                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
02643                 total_count++;
02644         }
02645 
02646         /* Sort the queue by submission time otherwise they are displayed
02647            in hash order. */
02648 
02649         qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
02650 
02651         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
02652 
02653         if (max_reported_jobs && total_count > max_reported_jobs)
02654                 total_count = max_reported_jobs;
02655 
02656         *ppqueue = queue;
02657         *pcount = total_count;
02658 
02659         ret = True;
02660 
02661   out:
02662 
02663         SAFE_FREE(data.dptr);
02664         SAFE_FREE(cgdata.dptr);
02665         return ret;
02666 }

int print_queue_status ( int  snum,
print_queue_struct **  ppqueue,
print_status_struct status 
)

printing.c2673 行で定義されています。

参照先 TDB_DATA::dptrTDB_DATA::dsizeget_print_db_byname()get_stored_queue_info()print_cache_expired()print_queue_update()release_print_db()statustdb_print_db::tdbtdb_fetch().

参照元 _spoolss_enumjobs()_spoolss_getjob()api_DosPrintQEnum()api_DosPrintQGetInfo()api_WPrintJobEnumerate()api_WPrintJobGetInfo()print_queue_purge()printer_notify_info()reply_printqueue()update_monitored_printq_cache().

02676 {
02677         fstring keystr;
02678         TDB_DATA data, key;
02679         const char *sharename;
02680         struct tdb_print_db *pdb;
02681         int count = 0;
02682 
02683         /* make sure the database is up to date */
02684 
02685         if (print_cache_expired(lp_const_servicename(snum), True))
02686                 print_queue_update(snum, False);
02687 
02688         /* return if we are done */
02689         if ( !ppqueue || !status )
02690                 return 0;
02691 
02692         *ppqueue = NULL;
02693         sharename = lp_const_servicename(snum);
02694         pdb = get_print_db_byname(sharename);
02695 
02696         if (!pdb)
02697                 return 0;
02698 
02699         /*
02700          * Fetch the queue status.  We must do this first, as there may
02701          * be no jobs in the queue.
02702          */
02703 
02704         ZERO_STRUCTP(status);
02705         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
02706         key.dptr = keystr;
02707         key.dsize = strlen(keystr);
02708         data = tdb_fetch(pdb->tdb, key);
02709         if (data.dptr) {
02710                 if (data.dsize == sizeof(*status)) {
02711                         /* this memcpy is ok since the status struct was 
02712                            not packed before storing it in the tdb */
02713                         memcpy(status, data.dptr, sizeof(*status));
02714                 }
02715                 SAFE_FREE(data.dptr);
02716         }
02717 
02718         /*
02719          * Now, fetch the print queue information.  We first count the number
02720          * of entries, and then only retrieve the queue if necessary.
02721          */
02722 
02723         if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
02724                 release_print_db(pdb);
02725                 return 0;
02726         }
02727 
02728         release_print_db(pdb);
02729         return count;
02730 }

BOOL print_queue_pause ( struct current_user user,
int  snum,
WERROR errcode 
)

printing.c2736 行で定義されています。

参照先 become_root()get_printer_fns()notify_printer_status()print_access_check()print_cache_flush()printif::queue_pauseunbecome_root().

参照元 api_WPrintQueueCtrl()control_printer().

02737 {
02738         int ret;
02739         struct printif *current_printif = get_printer_fns( snum );
02740         
02741         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
02742                 *errcode = WERR_ACCESS_DENIED;
02743                 return False;
02744         }
02745         
02746 
02747         become_root();
02748                 
02749         ret = (*(current_printif->queue_pause))(snum);
02750 
02751         unbecome_root();
02752                 
02753         if (ret != 0) {
02754                 *errcode = WERR_INVALID_PARAM;
02755                 return False;
02756         }
02757 
02758         /* force update the database */
02759         print_cache_flush(lp_const_servicename(snum));
02760 
02761         /* Send a printer notify message */
02762 
02763         notify_printer_status(snum, PRINTER_STATUS_PAUSED);
02764 
02765         return True;
02766 }

BOOL print_queue_resume ( struct current_user user,
int  snum,
WERROR errcode 
)

printing.c2772 行で定義されています。

参照先 become_root()get_printer_fns()notify_printer_status()print_access_check()print_cache_expired()print_queue_update()printif::queue_resumeunbecome_root().

参照元 api_WPrintQueueCtrl()control_printer().

02773 {
02774         int ret;
02775         struct printif *current_printif = get_printer_fns( snum );
02776 
02777         if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
02778                 *errcode = WERR_ACCESS_DENIED;
02779                 return False;
02780         }
02781         
02782         become_root();
02783                 
02784         ret = (*(current_printif->queue_resume))(snum);
02785 
02786         unbecome_root();
02787                 
02788         if (ret != 0) {
02789                 *errcode = WERR_INVALID_PARAM;
02790                 return False;
02791         }
02792 
02793         /* make sure the database is up to date */
02794         if (print_cache_expired(lp_const_servicename(snum), True))
02795                 print_queue_update(snum, True);
02796 
02797         /* Send a printer notify message */
02798 
02799         notify_printer_status(snum, PRINTER_STATUS_OK);
02800 
02801         return True;
02802 }

BOOL print_queue_purge ( struct current_user user,
int  snum,
WERROR errcode 
)

printing.c2808 行で定義されています。

参照先 become_root()is_owner()print_access_check()print_job_delete1()print_queue_status()print_queue_update()statusunbecome_root().

参照元 api_WPrintQueueCtrl()control_printer().

02809 {
02810         print_queue_struct *queue;
02811         print_status_struct status;
02812         int njobs, i;
02813         BOOL can_job_admin;
02814 
02815         /* Force and update so the count is accurate (i.e. not a cached count) */
02816         print_queue_update(snum, True);
02817         
02818         can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
02819         njobs = print_queue_status(snum, &queue, &status);
02820         
02821         if ( can_job_admin )
02822                 become_root();
02823 
02824         for (i=0;i<njobs;i++) {
02825                 BOOL owner = is_owner(user, lp_const_servicename(snum), queue[i].job);
02826 
02827                 if (owner || can_job_admin) {
02828                         print_job_delete1(snum, queue[i].job);
02829                 }
02830         }
02831         
02832         if ( can_job_admin )
02833                 unbecome_root();
02834 
02835         /* update the cache */
02836         print_queue_update( snum, True );
02837 
02838         SAFE_FREE(queue);
02839 
02840         return True;
02841 }


変数

SIG_ATOMIC_T got_sig_term

process.c48 行で定義されています。

SIG_ATOMIC_T reload_after_sighup

process.c47 行で定義されています。

struct current_user current_user

smbrun.c24 行で定義されています。

userdom_struct current_user_info

substitute.c29 行で定義されています。

TDB_CONTEXT* rap_tdb [static]

printing.c48 行で定義されています。

参照元 pjobid_to_rap()rap_jobid_delete()rap_to_pjobid().

uint16 next_rap_jobid [static]

printing.c49 行で定義されています。

参照元 pjobid_to_rap().

uint32 sysjob_to_jobid_value [static]

printing.c379 行で定義されています。

参照元 sysjob_to_jobid()unixjob_traverse_fn().

uint32 lpq_status

printing.c437 行で定義されています。

uint32 spoolss_status

printing.c438 行で定義されています。

struct { ... } lpq_to_spoolss_status_map[] [static]

参照元 map_to_spoolss_status().

pid_t background_lpq_updater_pid = -1 [static]

printing.c1381 行で定義されています。


Sambaに対してSat Aug 29 21:24:04 2009に生成されました。  doxygen 1.4.7