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

📄 printing.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	pstrcpy( lprmcommand, lp_lprmcommand(snum));	string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), False, False );	standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) );		/* 	 * Make sure that the background queue process exists.  	 * Otherwise just do the update ourselves 	 */		if ( force || background_lpq_updater_pid == -1 ) {		DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));		current_printif = get_printer_fns( snum );		print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );		return;	}	type = lp_printing(snum);		/* get the length */	len = tdb_pack( buffer, len, "fdPP",		sharename,		type,		lpqcommand, 		lprmcommand );	buffer = SMB_XMALLOC_ARRAY( char, len );	/* now pack the buffer */	newlen = tdb_pack( buffer, len, "fdPP",		sharename,		type,		lpqcommand,		lprmcommand );	SMB_ASSERT( newlen == len );	DEBUG(10,("print_queue_update: Sending message -> printer = %s, "		"type = %d, lpq command = [%s] lprm command = [%s]\n", 		sharename, type, lpqcommand, lprmcommand ));	/* here we set a msg pending record for other smbd processes 	   to throttle the number of duplicate print_queue_update msgs	   sent.  */	pdb = get_print_db_byname(sharename);	if (!pdb) {		SAFE_FREE(buffer);		return;	}	snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);	if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {		/* log a message but continue on */		DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",			sharename));	}	release_print_db( pdb );	/* finally send the message */		become_root();	message_send_pid(pid_to_procid(background_lpq_updater_pid),		 MSG_PRINTER_UPDATE, buffer, len, False);	unbecome_root();	SAFE_FREE( buffer );	return;}/**************************************************************************** Create/Update an entry in the print tdb that will allow us to send notify updates only to interested smbd's. ****************************************************************************/BOOL print_notify_register_pid(int snum){	TDB_DATA data;	struct tdb_print_db *pdb = NULL;	TDB_CONTEXT *tdb = NULL;	const char *printername;	uint32 mypid = (uint32)sys_getpid();	BOOL ret = False;	size_t i;	/* if (snum == -1), then the change notify request was	   on a print server handle and we need to register on	   all print queus */	   	if (snum == -1) 	{		int num_services = lp_numservices();		int idx;				for ( idx=0; idx<num_services; idx++ ) {			if (lp_snum_ok(idx) && lp_print_ok(idx) )				print_notify_register_pid(idx);		}				return True;	}	else /* register for a specific printer */	{		printername = lp_const_servicename(snum);		pdb = get_print_db_byname(printername);		if (!pdb)			return False;		tdb = pdb->tdb;	}	if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {		DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",					printername));		if (pdb)			release_print_db(pdb);		return False;	}	data = get_printer_notify_pid_list( tdb, printername, True );	/* Add ourselves and increase the refcount. */	for (i = 0; i < data.dsize; i += 8) {		if (IVAL(data.dptr,i) == mypid) {			uint32 new_refcount = IVAL(data.dptr, i+4) + 1;			SIVAL(data.dptr, i+4, new_refcount);			break;		}	}	if (i == data.dsize) {		/* We weren't in the list. Realloc. */		data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8);		if (!data.dptr) {			DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",						printername));			goto done;		}		data.dsize += 8;		SIVAL(data.dptr,data.dsize - 8,mypid);		SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */	}	/* Store back the record. */	if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {		DEBUG(0,("print_notify_register_pid: Failed to update pid \list for printer %s\n", printername));		goto done;	}	ret = True; done:	tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);	if (pdb)		release_print_db(pdb);	SAFE_FREE(data.dptr);	return ret;}/**************************************************************************** Update an entry in the print tdb that will allow us to send notify updates only to interested smbd's. ****************************************************************************/BOOL print_notify_deregister_pid(int snum){	TDB_DATA data;	struct tdb_print_db *pdb = NULL;	TDB_CONTEXT *tdb = NULL;	const char *printername;	uint32 mypid = (uint32)sys_getpid();	size_t i;	BOOL ret = False;	/* if ( snum == -1 ), we are deregister a print server handle	   which means to deregister on all print queues */	   	if (snum == -1) 	{		int num_services = lp_numservices();		int idx;				for ( idx=0; idx<num_services; idx++ ) {			if ( lp_snum_ok(idx) && lp_print_ok(idx) )				print_notify_deregister_pid(idx);		}				return True;	}	else /* deregister a specific printer */	{		printername = lp_const_servicename(snum);		pdb = get_print_db_byname(printername);		if (!pdb)			return False;		tdb = pdb->tdb;	}	if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {		DEBUG(0,("print_notify_register_pid: Failed to lock \printer %s database\n", printername));		if (pdb)			release_print_db(pdb);		return False;	}	data = get_printer_notify_pid_list( tdb, printername, True );	/* Reduce refcount. Remove ourselves if zero. */	for (i = 0; i < data.dsize; ) {		if (IVAL(data.dptr,i) == mypid) {			uint32 refcount = IVAL(data.dptr, i+4);			refcount--;			if (refcount == 0) {				if (data.dsize - i > 8)					memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);				data.dsize -= 8;				continue;			}			SIVAL(data.dptr, i+4, refcount);		}		i += 8;	}	if (data.dsize == 0)		SAFE_FREE(data.dptr);	/* Store back the record. */	if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {		DEBUG(0,("print_notify_register_pid: Failed to update pid \list for printer %s\n", printername));		goto done;	}	ret = True;  done:	tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);	if (pdb)		release_print_db(pdb);	SAFE_FREE(data.dptr);	return ret;}/**************************************************************************** Check if a jobid is valid. It is valid if it exists in the database.****************************************************************************/BOOL print_job_exists(const char* sharename, uint32 jobid){	struct tdb_print_db *pdb = get_print_db_byname(sharename);	BOOL ret;	if (!pdb)		return False;	ret = tdb_exists(pdb->tdb, print_key(jobid));	release_print_db(pdb);	return ret;}/**************************************************************************** Give the fd used for a jobid.****************************************************************************/int print_job_fd(const char* sharename, uint32 jobid){	struct printjob *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 pjob->fd;}/**************************************************************************** Give the filename used for a jobid. Only valid for the process doing the spooling and when the job has not been spooled.****************************************************************************/char *print_job_fname(const char* sharename, uint32 jobid){	struct printjob *pjob = print_job_find(sharename, jobid);	if (!pjob || pjob->spooled || pjob->pid != sys_getpid())		return NULL;	return pjob->filename;}/**************************************************************************** Give the filename used for a jobid. Only valid for the process doing the spooling and when the job has not been spooled.****************************************************************************/NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid){	struct printjob *pjob = print_job_find(sharename, jobid);		if ( !pjob )		return NULL;			return pjob->nt_devmode;}/**************************************************************************** Set the place in the queue for a job.****************************************************************************/BOOL print_job_set_place(int snum, uint32 jobid, int place){	DEBUG(2,("print_job_set_place not implemented yet\n"));	return False;}/**************************************************************************** Set the name of a job. Only possible for owner.****************************************************************************/BOOL print_job_set_name(int snum, uint32 jobid, char *name){	const char* sharename = lp_const_servicename(snum);	struct printjob *pjob;	pjob = print_job_find(sharename, jobid);	if (!pjob || pjob->pid != sys_getpid())		return False;	fstrcpy(pjob->jobname, name);	return pjob_store(sharename, jobid, pjob);}/*************************************************************************** Remove a jobid from the 'jobs changed' list.***************************************************************************/static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid){	struct tdb_print_db *pdb = get_print_db_byname(sharename);	TDB_DATA data, key;	size_t job_count, i;	BOOL ret = False;	BOOL gotlock = False;	if (!pdb) {		return False;	}	ZERO_STRUCT(data);	key = string_tdb_data("INFO/jobs_changed");	if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)		goto out;	gotlock = True;	data = tdb_fetch(pdb->tdb, key);	if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))		goto out;	job_count = data.dsize / 4;	for (i = 0; i < job_count; i++) {		uint32 ch_jobid;		ch_jobid = IVAL(data.dptr, i*4);		if (ch_jobid == jobid) {			if (i < job_count -1 )				memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );			data.dsize -= 4;			if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)				goto out;			break;		}	}	ret = True;  out:	if (gotlock)		tdb_chainunlock(pdb->tdb, key);	SAFE_FREE(data.dptr);	release_print_db(pdb);	if (ret)		DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));	else		DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));	return ret;}/**************************************************************************** Delete a print job - don't update queue.****************************************************************************/static BOOL print_job_delete1(int snum, uint32 jobid){	const char* sharename = lp_const_servicename(snum);	struct printjob *pjob = print_job_find(sharename, jobid);	int result = 0;	struct printif *current_printif = get_printer_fns( snum );	if (!pjob)		return False;	/*	 * If already deleting just return.	 */	if (pjob->status == LPQ_DELETING)		return True;	/* Hrm - we need to be able to cope with deleting a job before it	   has reached the spooler.  Just mark it as LPQ_DELETING and 	   let the print_queue_update() code rmeove the record */	   	if (pjob->sysjob == -1) {		DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));	}	/* Set the tdb entry to be deleting. */	pjob->status = LPQ_DELETING;	pjob_store(sharename, jobid, pjob);	if (pjob->spooled && pjob->sysjob != -1) 	{		result = (*(current_printif->job_delete))(			PRINTERNAME(snum),			lp_lprmcommand(snum), 			pjob);		/* Delete the tdb entry if the delete succeeded or the job hasn't		   been spooled. */		if (result == 0) {			struct tdb_print_db *pdb = get_print_db_byname(sharename);			int njobs = 1;			if (!pdb)				return False;			pjob_delete(sharename, 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);		}	}	remove_from_jobs_changed( sharename, jobid );	return (result == 0);}/**************************************************************************** Return true if the current user owns the print job.****************************************************************************/static BOOL is_owner(struct current_user *user, int snum, uint32 jobid){	struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);	user_struct *vuser;	if (!pjob || !user)		return False;	if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {		return strequal(pjob->user, vuser->user.smb_name);	} else {		return strequal(pjob->user, uidtoname(user->uid));	}

⌨️ 快捷键说明

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