⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 printing.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
}/**************************************************************************** Delete a print job.****************************************************************************/BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode){	const char* sharename = lp_const_servicename( snum );	struct printjob *pjob;	BOOL 	owner;	char 	*fname;	*errcode = WERR_OK;			owner = is_owner(user, snum, jobid);		/* Check access against security descriptor or whether the user	   owns their job. */	if (!owner && 	    !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {		DEBUG(3, ("delete denied by security descriptor\n"));		*errcode = WERR_ACCESS_DENIED;		/* BEGIN_ADMIN_LOG */		sys_adminlog( LOG_ERR, 			      "Permission denied-- user not allowed to delete, \pause, or resume print job. User name: %s. Printer name: %s.",			      uidtoname(user->uid), PRINTERNAME(snum) );		/* END_ADMIN_LOG */		return False;	}	/* 	 * get the spooled filename of the print job	 * if this works, then the file has not been spooled	 * to the underlying print system.  Just delete the 	 * spool file & return.	 */	 	if ( (fname = print_job_fname( sharename, jobid )) != NULL )	{		/* remove the spool file */		DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));		if ( unlink( fname ) == -1 ) {			*errcode = map_werror_from_unix(errno);			return False;		}	}		if (!print_job_delete1(snum, jobid)) {		*errcode = WERR_ACCESS_DENIED;		return False;	}	/* force update the database and say the delete failed if the           job still exists */	print_queue_update(snum, True);		pjob = print_job_find(sharename, jobid);	if ( pjob && (pjob->status != LPQ_DELETING) )		*errcode = WERR_ACCESS_DENIED;	return (pjob == NULL );}/**************************************************************************** Pause a job.****************************************************************************/BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode){	const char* sharename = lp_const_servicename(snum);	struct printjob *pjob;	int ret = -1;	struct printif *current_printif = get_printer_fns( snum );	pjob = print_job_find(sharename, jobid);		if (!pjob || !user) 		return False;	if (!pjob->spooled || pjob->sysjob == -1) 		return False;	if (!is_owner(user, snum, jobid) &&	    !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {		DEBUG(3, ("pause denied by security descriptor\n"));		/* BEGIN_ADMIN_LOG */		sys_adminlog( LOG_ERR, 			"Permission denied-- user not allowed to delete, \pause, or resume print job. User name: %s. Printer name: %s.",				uidtoname(user->uid), PRINTERNAME(snum) );		/* END_ADMIN_LOG */		*errcode = WERR_ACCESS_DENIED;		return False;	}	/* need to pause the spooled entry */	ret = (*(current_printif->job_pause))(snum, pjob);	if (ret != 0) {		*errcode = WERR_INVALID_PARAM;		return False;	}	/* force update the database */	print_cache_flush(snum);	/* Send a printer notify message */	notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);	/* how do we tell if this succeeded? */	return True;}/**************************************************************************** Resume a job.****************************************************************************/BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode){	const char *sharename = lp_const_servicename(snum);	struct printjob *pjob;	int ret;	struct printif *current_printif = get_printer_fns( snum );	pjob = print_job_find(sharename, jobid);		if (!pjob || !user)		return False;	if (!pjob->spooled || pjob->sysjob == -1)		return False;	if (!is_owner(user, snum, jobid) &&	    !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {		DEBUG(3, ("resume denied by security descriptor\n"));		*errcode = WERR_ACCESS_DENIED;		/* BEGIN_ADMIN_LOG */		sys_adminlog( LOG_ERR, 			 "Permission denied-- user not allowed to delete, \pause, or resume print job. User name: %s. Printer name: %s.",			uidtoname(user->uid), PRINTERNAME(snum) );		/* END_ADMIN_LOG */		return False;	}	ret = (*(current_printif->job_resume))(snum, pjob);	if (ret != 0) {		*errcode = WERR_INVALID_PARAM;		return False;	}	/* force update the database */	print_cache_flush(snum);	/* Send a printer notify message */	notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);	return True;}/**************************************************************************** Write to a print file.****************************************************************************/ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size){	const char* sharename = lp_const_servicename(snum);	int return_code;	struct printjob *pjob;	pjob = print_job_find(sharename, jobid);	if (!pjob)		return -1;	/* don't allow another process to get this info - it is meaningless */	if (pjob->pid != sys_getpid())		return -1;	return_code = write_data_at_offset(pjob->fd, buf, size, pos);	if (return_code>0) {		pjob->size += size;		pjob_store(sharename, jobid, pjob);	}	return return_code;}/**************************************************************************** Get the queue status - do not update if db is out of date.****************************************************************************/static int get_queue_status(const char* sharename, print_status_struct *status){	fstring keystr;	TDB_DATA data;	struct tdb_print_db *pdb = get_print_db_byname(sharename);	int len;	if (status) {		ZERO_STRUCTP(status);	}	if (!pdb)		return 0;	if (status) {		fstr_sprintf(keystr, "STATUS/%s", sharename);		data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));		if (data.dptr) {			if (data.dsize == sizeof(print_status_struct))				/* this memcpy is ok since the status struct was 				   not packed before storing it in the tdb */				memcpy(status, data.dptr, sizeof(print_status_struct));			SAFE_FREE(data.dptr);		}	}	len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");	release_print_db(pdb);	return (len == -1 ? 0 : len);}/**************************************************************************** Determine the number of jobs in a queue.****************************************************************************/int print_queue_length(int snum, print_status_struct *pstatus){	const char* sharename = lp_const_servicename( snum );	print_status_struct status;	int len;	ZERO_STRUCT( status ); 	/* make sure the database is up to date */	if (print_cache_expired(lp_const_servicename(snum), True))		print_queue_update(snum, False); 	/* also fetch the queue status */	memset(&status, 0, sizeof(status));	len = get_queue_status(sharename, &status);	if (pstatus)		*pstatus = status;	return len;}/*************************************************************************** Allocate a jobid. Hold the lock for as short a time as possible.***************************************************************************/static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid){	int i;	uint32 jobid;	*pjobid = (uint32)-1;	for (i = 0; i < 3; i++) {		/* Lock the database - only wait 20 seconds. */		if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {			DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));			return False;		}		if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {			if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {				DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",					sharename));				return False;			}			jobid = 0;		}		jobid = NEXT_JOBID(jobid);		if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {			DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));			tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");			return False;		}		/* We've finished with the INFO/nextjob lock. */		tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");						if (!print_job_exists(sharename, jobid))			break;	}	if (i > 2) {		DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",			sharename));		/* Probably full... */		errno = ENOSPC;		return False;	}	/* Store a dummy placeholder. */	{		TDB_DATA dum;		dum.dptr = NULL;		dum.dsize = 0;		if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {			DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",				jobid ));			return False;		}	}	*pjobid = jobid;	return True;}/*************************************************************************** Append a jobid to the 'jobs changed' list.***************************************************************************/static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid){	TDB_DATA data;	uint32 store_jobid;	SIVAL(&store_jobid, 0, jobid);	data.dptr = (char *)&store_jobid;	data.dsize = 4;	DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));	return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),			   data) == 0);}/*************************************************************************** Start spooling a job - return the jobid.***************************************************************************/uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode ){	uint32 jobid;	char *path;	struct printjob pjob;	user_struct *vuser;	const char *sharename = lp_const_servicename(snum);	struct tdb_print_db *pdb = get_print_db_byname(sharename);	int njobs;	errno = 0;	if (!pdb)		return (uint32)-1;	if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {		DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));		release_print_db(pdb);		return (uint32)-1;	}	if (!print_time_access_check(snum)) {		DEBUG(3, ("print_job_start: job start denied by time check\n"));		release_print_db(pdb);		return (uint32)-1;	}	path = lp_pathname(snum);	/* see if we have sufficient disk space */	if (lp_minprintspace(snum)) {		SMB_BIG_UINT dspace, dsize;		if (sys_fsusage(path, &dspace, &dsize) == 0 &&		    dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {			DEBUG(3, ("print_job_start: disk space check failed.\n"));			release_print_db(pdb);			errno = ENOSPC;			return (uint32)-1;		}	}	/* for autoloaded printers, check that the printcap entry still exists */	if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {		DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));		release_print_db(pdb);		errno = ENOENT;		return (uint32)-1;	}	/* Insure the maximum queue size is not violated */	if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {		DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",			sharename, njobs, lp_maxprintjobs(snum) ));		release_print_db(pdb);		errno = ENOSPC;		return (uint32)-1;	}	DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",		sharename, njobs, lp_maxprintjobs(snum) ));	if (!allocate_print_jobid(pdb, snum, sharename, &jobid))		goto fail;	/* create the database entry */		ZERO_STRUCT(pjob);		pjob.pid = sys_getpid();	pjob.sysjob = -1;	pjob.fd = -1;	pjob.starttime = time(NULL);	pjob.status = LPQ_SPOOLING;	pjob.size = 0;	pjob.spooled = False;	pjob.smbjob = True;	pjob.nt_devmode = nt_devmode;		fstrcpy(pjob.jobname, jobname);	if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {		fstrcpy(pjob.user, vuser->user.smb_name);	} else {		fstrcpy(pjob.user, uidtoname(user->uid));	}	fstrcpy(pjob.queuename, lp_const_servicename(snum));	/* we have a job entry - now create the spool file */	slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX", 		 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);	pjob.fd = smb_mkstemp(pjob.filename);	if (pjob.fd == -1) {		if (errno == EACCES) {			/* Common setup error, force a report. */			DEBUG(0, ("print_job_start: insufficient permissions \to open spool file %s.\n", pjob.filename));		} else {			/* Normal case, report at level 3 and above. */			DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));			DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));		}		goto fail;	}	pjob_store(sharename, jobid, &pjob);	/* Update the 'jobs changed' entry used by print_queue_status. */	add_to_jobs_changed(pdb, jobid);	/* Ensure we keep a rough count of the number of total jobs... */	tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);	release_print_db(pdb);	return jobid; fail:	if (jobid != -1)		pjob_delete(sharename, jobid);	release_print_db(pdb);	DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));	return (uint32)-1;}/**************************************************************************** Update the number of pages spooled to jobid****************************************************************************/void print_job_endpage(int snum, uint32 jobid){	const char* s

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -