예제 #1
0
/// Construct a new ResourceQueue system (you probably only need one)
ResourceQueue*
resourcequeue_new(guint structsize)
{
	AssimObj*		aself;
	ResourceQueue*		self;
	BINDDEBUG(ResourceQueue);

	if (structsize < sizeof(ResourceQueue)) {
		structsize = sizeof(ResourceQueue);
	}
	aself = assimobj_new(structsize);
	self = NEWSUBCLASS(ResourceQueue, aself);
	aself->_finalize = _resource_queue_finalize;
	
	self->Qcmd = _resource_queue_Qcmd;
	self->cancel = _resource_queue_cancel;
	self->cancelall = _resource_queue_cancelall;
	self->resources = g_hash_table_new_full(g_str_hash, g_str_equal
	,		_resource_queue_hash_key_destructor, _resource_queue_hash_data_destructor);
	self->timerid = g_timeout_add_seconds(1, _resource_queue_runqueue, self);
	self->activechildcnt = 0;
	self->shuttingdown = FALSE;

	return self;
}
예제 #2
0
/// Construct new SeqnoFrame object
SeqnoFrame*
seqnoframe_new(guint16 frametype,	///< Type of frame to create with this value
               int objsize)		///< Size of the object type - 0 means sizeof(SeqnoFrame)
{
    Frame*	frame;
    SeqnoFrame*	sframe;

    if (objsize < ((gssize)sizeof(SeqnoFrame))) {
        objsize = sizeof(SeqnoFrame);
    }

    frame = frame_new(frametype, objsize);
    sframe = NEWSUBCLASS(SeqnoFrame, frame);
    if (_sessionId == 0) {
        _seqnoframe_initsessionid();
    }
    sframe->getreqid = _seqnoframe_getreqid;
    sframe->setreqid = _seqnoframe_setreqid;
    sframe->getqid = _seqnoframe_getqid;
    sframe->setqid = _seqnoframe_setqid;
    sframe->getsessionid = _seqnoframe_getsessionid;
    sframe->equal = _seqnoframe_equal;
    sframe->compare = _seqnoframe_compare;

    // Base class member functions
    sframe->baseclass.baseclass.toString = _seqnoframe_toString;
    sframe->baseclass.updatedata = _seqnoframe_updatedata;
    sframe->baseclass.isvalid = _seqnoframe_isvalid;
    sframe->baseclass.value = NULL;
    sframe->baseclass.setvalue = NULL;
    sframe->baseclass.valuefinalize = NULL;
    sframe->baseclass.length = sizeof(guint32)+sizeof(guint64)+sizeof(guint16);

    // Subclass (i.e., SeqnoFrame) data
    sframe->_sessionid = _sessionId;
    sframe->_reqid = 0;
    sframe->_qid = 0;
    return sframe;
}
예제 #3
0
/// Discovery constructor.
/// Note that derived classes <i>must</i> set the discover member function - or things might crash.
/// That is certainly what will happen if you try and construct one of these objects directly and
/// then use it.
Discovery*
discovery_new(const char *	instname,	///<[in] instance name
	      NetGSource*	iosource,	///<[in/out] I/O object
	      ConfigContext*	context,	///<[in/out] configuration context
	      gsize objsize)			///<[in] number of bytes to malloc for the object (or zero)
{
	gsize	size = objsize < sizeof(Discovery) ? sizeof(Discovery) : objsize;
	Discovery * ret = NEWSUBCLASS(Discovery, assimobj_new(size));
	g_return_val_if_fail(ret != NULL, NULL);
	BINDDEBUG(Discovery);
	ret->_instancename		= g_strdup(instname);
	ret->instancename		= _discovery_instancename;
	ret->discoverintervalsecs	= _discovery_discoverintervalsecs;
	ret->baseclass._finalize	= _discovery_finalize;
	ret->sendjson			= _discovery_sendjson;
	ret->discover			= NULL;
	ret->_timerid			= 0;
	ret->_iosource			= iosource;
	ret->_config			= context;
	ret->starttime			= g_get_real_time();
	REF(ret->_config);
	return ret;
}
예제 #4
0
/// Create a new private key - or return the existing private key with this id
WINEXPORT CryptFramePrivateKey*
cryptframe_privatekey_new(const char *key_id,	///<[in] Key id of given private key
			  gpointer private_key)	///<[in] MALLOCed private key
{
	AssimObj*		aself;
	CryptFramePrivateKey*	self;
	INITMAPS;
	g_return_val_if_fail(key_id != NULL && private_key != NULL, NULL);
	self = cryptframe_private_key_by_id(key_id);
	if (self) {
		g_warning("%s.%d: Private key %s Already IN private key map", __FUNCTION__, __LINE__, key_id);
		return self;
	}
	aself = assimobj_new(sizeof(CryptFramePrivateKey));
	aself->_finalize = _cryptframe_privatekey_finalize;
	self = NEWSUBCLASS(CryptFramePrivateKey, aself);
	self->key_id = g_strdup(key_id);
	self->key_size = crypto_box_SECRETKEYBYTES;
	self->private_key = private_key;
	g_hash_table_insert(private_key_map, self->key_id, self);
	DEBUGCKSUM3(self->key_id, private_key);
	return self;
}
예제 #5
0
/// Create a new public key - or return the existing public key with this id
WINEXPORT CryptFramePublicKey*
cryptframe_publickey_new (const char *key_id,	///< Key id of the given public key
			  gpointer public_key)	///< MALLOCed public key
{
	AssimObj*		aself;
	CryptFramePublicKey*	self;
	INITMAPS;
	g_return_val_if_fail(key_id != NULL && public_key != NULL, NULL);
	self = cryptframe_public_key_by_id(key_id);
	if (self) {
		return self;
	}
	aself = assimobj_new(sizeof(CryptFramePublicKey));
	aself->_finalize = _cryptframe_publickey_finalize;
	self = NEWSUBCLASS(CryptFramePublicKey, aself);
	self->key_id = g_strdup(key_id);
	self->key_size = crypto_box_PUBLICKEYBYTES;
	self->frame_type = FRAMETYPE_PUBKEYCURVE25519;
	self->public_key = public_key;
	g_hash_table_insert(public_key_map, self->key_id, self);
	DEBUGCKSUM3(self->key_id, public_key);
	return self;
}
예제 #6
0
/// Construct a new CryptFrame
/// This can only be used directly for creating subclassed CryptFrame frames because
/// CryptFrame is an abstract class...
CryptFrame*
cryptframe_new( guint16 frame_type,		///<[in] TLV type of CryptFrame
		const char * sender_key_id,	///<[in] Sender key id
		const char * receiver_key_id,	///<[in] Receiver key id
		gsize objsize)			///<[in] size of object
{
	Frame*		baseframe;
	CryptFrame*	self;

	BINDDEBUG(CryptFrame);
	if (objsize < sizeof(CryptFrame)) {
		objsize = sizeof(CryptFrame);
	}
	baseframe = frame_new(frame_type, objsize);
	if (!_parentclass_finalize) {
		_parentclass_finalize = baseframe->baseclass._finalize;
	}
	baseframe->baseclass._finalize = _cryptframe_finalize;
	baseframe->isvalid = _cryptframe_default_isvalid;
	self = NEWSUBCLASS(CryptFrame, baseframe);
	self->sender_key_id = g_strdup(sender_key_id);
	self->receiver_key_id = g_strdup(receiver_key_id);
	return self;
}
예제 #7
0
/// Construct a new CryptCurve25519 object (frame).
CryptCurve25519*
cryptcurve25519_new(guint16 frame_type,	///<[in] TLV type of CryptCurve25519
	  const char * sender_key_id,	///<[in] name of sender's key
	  const char * receiver_key_id,	///<[in] name of receiver's key
	  gboolean     forsending,	///<[in] TRUE if this is for sending
	  gsize objsize)		///<[in] sizeof(this object) - or zero for default
{
	CryptFrame*		baseframe;
	CryptCurve25519*	ret;

	BINDDEBUG(CryptCurve25519);
	if (objsize < sizeof(CryptCurve25519)) {
		objsize = sizeof(CryptCurve25519);
	}
	if (NULL == sender_key_id) {
		sender_key_id = cryptframe_get_signing_key_id();
	}
	DEBUGMSG2("%s.%d:(%s, %s, %d)", __FUNCTION__, __LINE__, sender_key_id, receiver_key_id
	,	(int)objsize);
	g_return_val_if_fail(sender_key_id != NULL && receiver_key_id != NULL, NULL);
	if (!_is_valid_curve25519_key_id(receiver_key_id, PUBLICKEY)) {
		g_critical("%s.%d: public key name [%s] is invalid", __FUNCTION__, __LINE__, receiver_key_id);
		return NULL;
	}
	if (!_is_valid_curve25519_key_id(sender_key_id, PUBLICKEY)) {
		g_critical("%s.%d: public key name [%s] is invalid", __FUNCTION__, __LINE__, sender_key_id);
		return NULL;
	}
	baseframe = cryptframe_new(frame_type, sender_key_id, receiver_key_id, objsize);
	if (!_parentclass_finalize) {
		_parentclass_finalize = baseframe->baseclass.baseclass._finalize;
	}
	baseframe->baseclass.isvalid	= _cryptcurve25519_default_isvalid;
	baseframe->baseclass.updatedata	= _cryptcurve25519_updatedata;
	baseframe->baseclass.length	= TLVLEN(receiver_key_id, sender_key_id);
	baseframe->baseclass.baseclass._finalize = _cryptcurve25519_finalize;
	ret			= NEWSUBCLASS(CryptCurve25519, baseframe);
	ret->forsending		= forsending;
	ret->private_key	= cryptframe_private_key_by_id(forsending ? sender_key_id : receiver_key_id);
	ret->public_key		= cryptframe_public_key_by_id(forsending ? receiver_key_id : sender_key_id);
	if (ret->private_key && ret->public_key) {
		DEBUGCKSUM3("private_key:", ret->private_key->private_key, crypto_box_SECRETKEYBYTES);
		DEBUGCKSUM3("public_key:", ret->public_key->public_key, crypto_box_PUBLICKEYBYTES);
		DUMP3(__FUNCTION__, &ret->baseclass.baseclass.baseclass, " is return value");
		REF(ret->private_key);
		REF(ret->public_key);
	}else{
		if (!ret->private_key) {
			g_warning("%s.%d: Sender private key is NULL for key id %s", __FUNCTION__, __LINE__
			,	sender_key_id);
			abort();
		}
		if (!ret->public_key) {
			g_warning("%s.%d: Receiver public key is NULL for key id %s", __FUNCTION__, __LINE__
			,	receiver_key_id);
		}
		UNREF3(ret);
		return NULL;
	}
	return ret;
}
예제 #8
0
/**
 * @ref ChildProcess constructor.
 * Here's what we're going to do:
 * 1) Create child process using g_spawn_async_with_pipes()
 * 2) ...In child process become our own process group
 * 3) Create LogSourceFd object for stderr
 * 4) Create LogSourceFd or GMainFd object for stdout
 * 5) Set timer (if any)
 * 6) Initialize the child state to running
 * 7) Return.
 */
WINEXPORT ChildProcess*
childprocess_new(gsize cpsize		///< Size of created ChildProcess object
,		char** argv		///< NULL-terminated argv for the ChildProcess
,		const char** envp	///< Environment for the ChildProcess
,		ConfigContext* envmod	///< Modifications to the ChildProcess environment
,		const char* curdir	///< Current directory to start the child in
,		void (*notify)(ChildProcess*, enum HowDied, int rc, int signal, gboolean core_dumped)
					///< Function to call if/when the child terminates
,		gboolean save_stdout	///< TRUE to save stdout, FALSE to log it
,		const char*logdomain	///< Glib log domain
,		const char*logprefix	///< Prefix to prepend to log entries
,		GLogLevelFlags loglevel	///< Glib Log level
,		guint32 timeout_seconds	///< How long to wait before killing it - zero for no timeout
,		gpointer user_data	///< Data our user wants us to keep
,		enum ChildErrLogMode logmode ///< How to log child exits
,		const char* logname)	///< Name to use when logging child exits as requested
{
	AssimObj*	aself;
	ChildProcess*	self;
	gint		stdoutfd;
	gint		stderrfd;
	GError*		failcode = NULL;
	gchar**		childenv = NULL;

	BINDDEBUG(ChildProcess);
	g_return_val_if_fail(logprefix != NULL, NULL);
	if (cpsize < sizeof(ChildProcess)) {
		cpsize = sizeof(ChildProcess);
	}
	aself = assimobj_new(cpsize);
	g_return_val_if_fail(aself != NULL, NULL);
	self = NEWSUBCLASS(ChildProcess, aself);
	childenv = assim_merge_environ(envp, envmod);
	if (!g_spawn_async_with_pipes(
		curdir,				// Current directory
		argv,				// Arguments
		childenv,			// environment
		G_SPAWN_DO_NOT_REAP_CHILD,	// GSpawnFlags flags,
		_childprocess_setup_child,	// GSpawnChildSetupFunc child_setup,
		self,				// gpointer user_data,
		&self->child_pid,		// GPid *child_pid,
		NULL,				// gint *standard_input,
		&stdoutfd,			// gint *standard_output,
		&stderrfd,			// gint *standard_error,
		&failcode)) {			// GError **error

		// OOPS!  Failed!
		const char *	msg = "unknown exec error";
		if (failcode && failcode->message) {
			msg = failcode->message;
		}
		g_critical("%s.%d: %s", __FUNCTION__, __LINE__, msg);
		if (failcode) {
			g_clear_error(&failcode);	// sets failcode back to NULL
		}
		assim_free_environ(childenv); childenv = NULL;
		UNREF(self);
		aself = NULL;
		return NULL;
	}
	DEBUGMSG2("%s.%d: Spawned process with user_data = %p", __FUNCTION__, __LINE__, self);

	aself->_finalize = _childprocess_finalize;
	aself->toString = _childprocess_toString;
	self->stderr_src = logsourcefd_new(0, stderrfd, G_PRIORITY_HIGH, g_main_context_default()
	,		                   logdomain, loglevel, logprefix);
	self->user_data = user_data;
	self->logmode = logmode;
	if (NULL == logname) {
		logname = argv[0];
	}
	self->loggingname = g_strdup(logname);
	assim_free_environ(childenv);
	childenv = NULL;

	if (!save_stdout) {
		LogSourceFd*	logsrc;
		logsrc = logsourcefd_new(0, stdoutfd, G_PRIORITY_HIGH
		,		g_main_context_default(), logdomain, loglevel, logprefix);
		self->stdout_src = &logsrc->baseclass;
	}else{
		self->stdout_src = gmainfd_new(0, stdoutfd, G_PRIORITY_HIGH, g_main_context_default());
	}
	self->childsrc_id = g_child_watch_add(self->child_pid, _childprocess_childexit, self);

	self->notify = notify;

	if (0 == timeout_seconds) {
		DEBUGMSG2("No timeout for process with user_data = %p", self);
		self->timeoutsrc_id = 0;
	}else{
		self->timeoutsrc_id = g_timeout_add_seconds(timeout_seconds
		,			                   _childprocess_timeout, self);
		DEBUGMSG3("%s.%d: Set %d second timeout %d for process with user_data = %p"
		,	__FUNCTION__, __LINE__, timeout_seconds, self->timeoutsrc_id, self);
	}
	self->child_state = CHILDSTATE_RUNNING;
	DEBUGMSG5("%s.%d: REF child: %p", __FUNCTION__,__LINE__, self);
	REF(self);	// We do this because we need to still be here when the process exits
	return self;
}