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

📄 messages.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/CIFS implementation.   Samba internal messaging functions   Copyright (C) Andrew Tridgell 2000   Copyright (C) 2001 by Martin Pool   Copyright (C) 2002 by Jeremy Allison      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*//**  @defgroup messages Internal messaging framework  @{  @file messages.c    @brief  Module for internal messaging between Samba daemons.    The idea is that if a part of Samba wants to do communication with   another Samba process then it will do a message_register() of a   dispatch function, and use message_send_pid() to send messages to   that process.   The dispatch function is given the pid of the sender, and it can   use that to reply by message_send_pid().  See ping_message() for a   simple example.   @caution Dispatch functions must be able to cope with incoming   messages on an *odd* byte boundary.   This system doesn't have any inherent size limitations but is not   very efficient for large messages or when messages are sent in very   quick succession.*/#include "includes.h"/* the locking database handle */static TDB_CONTEXT *tdb;static int received_signal;/* change the message version with any incompatible changes in the protocol */#define MESSAGE_VERSION 1struct message_rec {	int msg_version;	int msg_type;	struct process_id dest;	struct process_id src;	size_t len;};/* we have a linked list of dispatch handlers */static struct dispatch_fns {	struct dispatch_fns *next, *prev;	int msg_type;	void (*fn)(int msg_type, struct process_id pid, void *buf, size_t len);} *dispatch_fns;/**************************************************************************** Notifications come in as signals.****************************************************************************/static void sig_usr1(void){	received_signal = 1;	sys_select_signal(SIGUSR1);}/**************************************************************************** A useful function for testing the message system.****************************************************************************/static void ping_message(int msg_type, struct process_id src,			 void *buf, size_t len){	const char *msg = buf ? buf : "none";	DEBUG(1,("INFO: Received PING message from PID %s [%s]\n",		 procid_str_static(&src), msg));	message_send_pid(src, MSG_PONG, buf, len, True);}/**************************************************************************** Initialise the messaging functions. ****************************************************************************/BOOL message_init(void){	if (tdb) return True;	tdb = tdb_open_log(lock_path("messages.tdb"), 		       0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, 		       O_RDWR|O_CREAT,0600);	if (!tdb) {		DEBUG(0,("ERROR: Failed to initialise messages database\n"));		return False;	}	CatchSignal(SIGUSR1, SIGNAL_CAST sig_usr1);	message_register(MSG_PING, ping_message);	/* Register some debugging related messages */	register_msg_pool_usage();	register_dmalloc_msgs();	return True;}/******************************************************************* Form a static tdb key from a pid.******************************************************************/static TDB_DATA message_key_pid(struct process_id pid){	static char key[20];	TDB_DATA kbuf;	slprintf(key, sizeof(key)-1, "PID/%s", procid_str_static(&pid));		kbuf.dptr = (char *)key;	kbuf.dsize = strlen(key)+1;	return kbuf;}/**************************************************************************** Notify a process that it has a message. If the process doesn't exist  then delete its record in the database.****************************************************************************/static BOOL message_notify(struct process_id procid){	pid_t pid = procid.pid;	/*	 * Doing kill with a non-positive pid causes messages to be	 * sent to places we don't want.	 */	SMB_ASSERT(pid > 0);	if (kill(pid, SIGUSR1) == -1) {		if (errno == ESRCH) {			DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid));			tdb_delete(tdb, message_key_pid(procid));		} else {			DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(errno)));		}		return False;	}	return True;}/**************************************************************************** Send a message to a particular pid.****************************************************************************/static BOOL message_send_pid_internal(struct process_id pid, int msg_type,				      const void *buf, size_t len,				      BOOL duplicates_allowed,				      unsigned int timeout){	TDB_DATA kbuf;	TDB_DATA dbuf;	TDB_DATA old_dbuf;	struct message_rec rec;	char *ptr;	struct message_rec prec;	/*	 * Doing kill with a non-positive pid causes messages to be	 * sent to places we don't want.	 */	SMB_ASSERT(procid_to_pid(&pid) > 0);	rec.msg_version = MESSAGE_VERSION;	rec.msg_type = msg_type;	rec.dest = pid;	rec.src = procid_self();	rec.len = len;	kbuf = message_key_pid(pid);	dbuf.dptr = (void *)SMB_MALLOC(len + sizeof(rec));	if (!dbuf.dptr)		return False;	memcpy(dbuf.dptr, &rec, sizeof(rec));	if (len > 0)		memcpy((void *)((char*)dbuf.dptr+sizeof(rec)), buf, len);	dbuf.dsize = len + sizeof(rec);	if (duplicates_allowed) {		/* If duplicates are allowed we can just append the message and return. */		/* lock the record for the destination */		if (timeout) {			if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {				DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout));				return False;			}		} else {			if (tdb_chainlock(tdb, kbuf) == -1) {				DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n"));				return False;			}		}			tdb_append(tdb, kbuf, dbuf);		tdb_chainunlock(tdb, kbuf);		SAFE_FREE(dbuf.dptr);		errno = 0;                    /* paranoia */		return message_notify(pid);	}	/* lock the record for the destination */	if (timeout) {		if (tdb_chainlock_with_timeout(tdb, kbuf, timeout) == -1) {			DEBUG(0,("message_send_pid_internal: failed to get chainlock with timeout %ul.\n", timeout));			return False;		}	} else {		if (tdb_chainlock(tdb, kbuf) == -1) {			DEBUG(0,("message_send_pid_internal: failed to get chainlock.\n"));			return False;		}	}		old_dbuf = tdb_fetch(tdb, kbuf);	if (!old_dbuf.dptr) {		/* its a new record */		tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);		tdb_chainunlock(tdb, kbuf);		SAFE_FREE(dbuf.dptr);		errno = 0;                    /* paranoia */		return message_notify(pid);	}	/* Not a new record. Check for duplicates. */	for(ptr = (char *)old_dbuf.dptr; ptr < old_dbuf.dptr + old_dbuf.dsize; ) {		/*		 * First check if the message header matches, then, if it's a non-zero		 * sized message, check if the data matches. If so it's a duplicate and		 * we can discard it. JRA.		 */		if (!memcmp(ptr, &rec, sizeof(rec))) {			if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {				tdb_chainunlock(tdb, kbuf);				DEBUG(10,("message_send_pid_internal: discarding duplicate message.\n"));				SAFE_FREE(dbuf.dptr);				SAFE_FREE(old_dbuf.dptr);				return True;			}		}		memcpy(&prec, ptr, sizeof(prec));		ptr += sizeof(rec) + prec.len;	}	/* we're adding to an existing entry */	tdb_append(tdb, kbuf, dbuf);	tdb_chainunlock(tdb, kbuf);	SAFE_FREE(old_dbuf.dptr);	SAFE_FREE(dbuf.dptr);	errno = 0;                    /* paranoia */	return message_notify(pid);}/**************************************************************************** Send a message to a particular pid - no timeout.****************************************************************************/BOOL message_send_pid(struct process_id pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed){	return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, 0);}/**************************************************************************** Send a message to a particular pid, with timeout in seconds.****************************************************************************/

⌨️ 快捷键说明

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