Example #1
0
/** Load client entries from Couchbase client documents on startup
 *
 * This function executes the view defined in the module configuration and loops
 * through all returned rows.  The view is called with "stale=false" to ensure the
 * most accurate data available when the view is called.  This will force an index
 * rebuild on this design document in Couchbase.  However, since this function is only
 * run once at sever startup this should not be a concern.
 *
 * @param  inst The module instance.
 * @param  tmpl Default values for new clients.
 * @param  map  The client attribute configuration section.
 * @return
 *	- 0 on success.
 *	- -1 on failure.
 */
int mod_load_client_documents(rlm_couchbase_t *inst, CONF_SECTION *tmpl, CONF_SECTION *map)
{
	rlm_couchbase_handle_t *handle = NULL; /* connection pool handle */
	char vpath[256], vid[MAX_KEY_SIZE], vkey[MAX_KEY_SIZE];  /* view path and fields */
	char error[512];                                         /* view error return */
	int idx = 0;                                             /* row array index counter */
	int retval = 0;                                          /* return value */
	lcb_error_t cb_error = LCB_SUCCESS;                      /* couchbase error holder */
	json_object *json, *jval;                                /* json object holders */
	json_object *jrows = NULL;                               /* json object to hold view rows */
	CONF_SECTION *client;                                    /* freeradius config section */
	RADCLIENT *c;                                            /* freeradius client */

	/* get handle */
	handle = fr_connection_get(inst->pool);

	/* check handle */
	if (!handle) return -1;

	/* set couchbase instance */
	lcb_t cb_inst = handle->handle;

	/* set cookie */
	cookie_t *cookie = handle->cookie;

	/* build view path */
	snprintf(vpath, sizeof(vpath), "%s?stale=false", inst->client_view);

	/* query view for document */
	cb_error = couchbase_query_view(cb_inst, cookie, vpath, NULL);

	/* check error and object */
	if (cb_error != LCB_SUCCESS || cookie->jerr != json_tokener_success || !cookie->jobj) {
		/* log error */
		ERROR("rlm_couchbase: failed to execute view request or parse return");
		/* set return */
		retval = -1;
		/* return */
		goto free_and_return;
	}

	/* debugging */
	DEBUG3("rlm_couchbase: cookie->jobj == %s", json_object_to_json_string(cookie->jobj));

	/* check for error in json object */
	if (json_object_object_get_ex(cookie->jobj, "error", &json)) {
		/* build initial error buffer */
		strlcpy(error, json_object_get_string(json), sizeof(error));
		/* get error reason */
		if (json_object_object_get_ex(cookie->jobj, "reason", &json)) {
			/* append divider */
			strlcat(error, " - ", sizeof(error));
			/* append reason */
			strlcat(error, json_object_get_string(json), sizeof(error));
		}
		/* log error */
		ERROR("rlm_couchbase: view request failed with error: %s", error);
		/* set return */
		retval = -1;
		/* return */
		goto free_and_return;
	}

	/* check for document id in return */
	if (!json_object_object_get_ex(cookie->jobj, "rows", &json)) {
		/* log error */
		ERROR("rlm_couchbase: failed to fetch rows from view payload");
		/* set return */
		retval = -1;
		/* return */
		goto free_and_return;
	}

	/* get and hold rows */
	jrows = json_object_get(json);

	/* free cookie object */
	if (cookie->jobj) {
		json_object_put(cookie->jobj);
		cookie->jobj = NULL;
	}

	/* debugging */
	DEBUG3("rlm_couchbase: jrows == %s", json_object_to_json_string(jrows));

	/* check for valid row value */
	if (!fr_json_object_is_type(jrows, json_type_array) || json_object_array_length(jrows) < 1) {
		/* log error */
		ERROR("rlm_couchbase: no valid rows returned from view: %s", vpath);
		/* set return */
		retval = -1;
		/* return */
		goto free_and_return;
	}

	/* loop across all row elements */
	for (idx = 0; idx < json_object_array_length(jrows); idx++) {
		/* fetch current index */
		json = json_object_array_get_idx(jrows, idx);

		/* get view id */
		if (json_object_object_get_ex(json, "id", &jval)) {
			/* clear view id */
			memset(vid, 0, sizeof(vid));
			/* copy and check length */
			if (strlcpy(vid, json_object_get_string(jval), sizeof(vid)) >= sizeof(vid)) {
				ERROR("rlm_couchbase: id from row longer than MAX_KEY_SIZE (%d)",
				      MAX_KEY_SIZE);
				continue;
			}
		} else {
			WARN("rlm_couchbase: failed to fetch id from row - skipping");
			continue;
		}

		/* get view key */
		if (json_object_object_get_ex(json, "key", &jval)) {
			/* clear view key */
			memset(vkey, 0, sizeof(vkey));
			/* copy and check length */
			if (strlcpy(vkey, json_object_get_string(jval), sizeof(vkey)) >= sizeof(vkey)) {
				ERROR("rlm_couchbase: key from row longer than MAX_KEY_SIZE (%d)",
				      MAX_KEY_SIZE);
				continue;
			}
		} else {
			WARN("rlm_couchbase: failed to fetch key from row - skipping");
			continue;
		}

		/* fetch document */
		cb_error = couchbase_get_key(cb_inst, cookie, vid);

		/* check error and object */
		if (cb_error != LCB_SUCCESS || cookie->jerr != json_tokener_success || !cookie->jobj) {
			/* log error */
			ERROR("rlm_couchbase: failed to execute get request or parse return");
			/* set return */
			retval = -1;
			/* return */
			goto free_and_return;
		}

		/* debugging */
		DEBUG3("rlm_couchbase: cookie->jobj == %s", json_object_to_json_string(cookie->jobj));

		/* allocate conf section */
		client = tmpl ? cf_section_dup(NULL, tmpl, "client", vkey, true) :
				cf_section_alloc(NULL, "client", vkey);

		if (client_map_section(client, map, _get_client_value, cookie->jobj) < 0) {
			/* free config setion */
			talloc_free(client);
			/* set return */
			retval = -1;
			/* return */
			goto free_and_return;
		}

		/*
		 * @todo These should be parented from something.
		 */
		c = client_afrom_cs(NULL, client, false, false);
		if (!c) {
			ERROR("rlm_couchbase: failed to allocate client");
			/* free config setion */
			talloc_free(client);
			/* set return */
			retval = -1;
			/* return */
			goto free_and_return;
		}

		/*
		 * Client parents the CONF_SECTION which defined it.
		 */
		talloc_steal(c, client);

		/* attempt to add client */
		if (!client_add(NULL, c)) {
			ERROR("rlm_couchbase: failed to add client '%s' from '%s', possible duplicate?", vkey, vid);
			/* free client */
			client_free(c);
			/* set return */
			retval = -1;
			/* return */
			goto free_and_return;
		}

		/* debugging */
		DEBUG("rlm_couchbase: client '%s' added", c->longname);

		/* free json object */
		if (cookie->jobj) {
			json_object_put(cookie->jobj);
			cookie->jobj = NULL;
		}
	}

	free_and_return:

	/* free rows */
	if (jrows) {
		json_object_put(jrows);
	}

	/* free json object */
	if (cookie->jobj) {
		json_object_put(cookie->jobj);
		cookie->jobj = NULL;
	}

	/* release handle */
	if (handle) {
		fr_connection_release(inst->pool, handle);
	}

	/* return */
	return retval;
}
Example #2
0
int proxy_tls_recv(rad_listen_t *listener)
{
	listen_socket_t *sock = listener->data;
	char buffer[256];
	RADIUS_PACKET *packet;
	uint8_t *data;
	ssize_t data_len;

	if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;

	DEBUG3("Proxy SSL socket has data to read");
	PTHREAD_MUTEX_LOCK(&sock->mutex);
	data_len = proxy_tls_read(listener);
	PTHREAD_MUTEX_UNLOCK(&sock->mutex);

	if (data_len < 0) {
		DEBUG("Closing TLS socket to home server");
		PTHREAD_MUTEX_LOCK(&sock->mutex);
		tls_socket_close(listener);
		PTHREAD_MUTEX_UNLOCK(&sock->mutex);
		return 0;
	}

	if (data_len == 0) return 0; /* not done yet */

	data = sock->data;

	packet = rad_alloc(sock, false);
	packet->sockfd = listener->fd;
	packet->src_ipaddr = sock->other_ipaddr;
	packet->src_port = sock->other_port;
	packet->dst_ipaddr = sock->my_ipaddr;
	packet->dst_port = sock->my_port;
	packet->code = data[0];
	packet->id = data[1];
	packet->data_len = data_len;
	packet->data = talloc_array(packet, uint8_t, packet->data_len);
	memcpy(packet->data, data, packet->data_len);
	memcpy(packet->vector, packet->data + 4, 16);

	/*
	 *	FIXME: Client MIB updates?
	 */
	switch (packet->code) {
	case PW_CODE_ACCESS_ACCEPT:
	case PW_CODE_ACCESS_CHALLENGE:
	case PW_CODE_ACCESS_REJECT:
		break;

#ifdef WITH_ACCOUNTING
	case PW_CODE_ACCOUNTING_RESPONSE:
		break;
#endif

	default:
		/*
		 *	FIXME: Update MIB for packet types?
		 */
		ERROR("Invalid packet code %d sent to a proxy port "
		       "from home server %s port %d - ID %d : IGNORED",
		       packet->code,
		       ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
		       packet->src_port, packet->id);
		rad_free(&packet);
		return 0;
	}

	if (!request_proxy_reply(packet)) {
		rad_free(&packet);
		return 0;
	}

	return 1;
}
Example #3
0
/*
 *	Find a module on disk or in memory, and link to it.
 */
static module_entry_t *linkto_module(const char *module_name,
				     CONF_SECTION *cs)
{
	module_entry_t myentry;
	module_entry_t *node;
	lt_dlhandle handle = NULL;
	char module_struct[256];
	char *p;
	const module_t *module;

	strlcpy(myentry.name, module_name, sizeof(myentry.name));
	node = rbtree_finddata(module_tree, &myentry);
	if (node) return node;

	/*
	 *	Link to the module's rlm_FOO{} module structure.
	 *
	 *	The module_name variable has the version number
	 *	embedded in it, and we don't want that here.
	 */
	strcpy(module_struct, module_name);
	p = strrchr(module_struct, '-');
	if (p) *p = '\0';

#if defined(WITHOUT_LIBLTDL) && defined (WITH_DLOPEN) && defined(RTLD_SELF)
	module = lt_dlsym(RTLD_SELF, module_struct);
	if (module) goto open_self;
#endif

	/*
	 *	Keep the handle around so we can dlclose() it.
	 */
	handle = fr_dlopenext(module_name);
	if (handle == NULL) {
		cf_log_err(cf_sectiontoitem(cs),
			   "Failed to link to module '%s': %s\n",
			   module_name, lt_dlerror());
		return NULL;
	}

	DEBUG3("    (Loaded %s, checking if it's valid)", module_name);

	/*
	 *	libltld MAY core here, if the handle it gives us contains
	 *	garbage data.
	 */
	module = lt_dlsym(handle, module_struct);
	if (!module) {
		cf_log_err(cf_sectiontoitem(cs),
			   "Failed linking to %s structure: %s\n",
			   module_name, lt_dlerror());
		lt_dlclose(handle);
		return NULL;
	}

#if defined(WITHOUT_LIBLTDL) && defined (WITH_DLOPEN) && defined(RTLD_SELF)
 open_self:
#endif
	/*
	 *	Before doing anything else, check if it's sane.
	 */
	if (module->magic != RLM_MODULE_MAGIC_NUMBER) {
		lt_dlclose(handle);
		cf_log_err(cf_sectiontoitem(cs),
			   "Invalid version in module '%s'",
			   module_name);
		return NULL;

	}

	/* make room for the module type */
	node = rad_malloc(sizeof(*node));
	memset(node, 0, sizeof(*node));
	strlcpy(node->name, module_name, sizeof(node->name));
	node->module = module;
	node->handle = handle;

	cf_log_module(cs, "Linked to module %s", module_name);

	/*
	 *	Add the module as "rlm_foo-version" to the configuration
	 *	section.
	 */
	if (!rbtree_insert(module_tree, node)) {
		radlog(L_ERR, "Failed to cache module %s", module_name);
		lt_dlclose(handle);
		free(node);
		return NULL;
	}

	return node;
}
/*
 *	The "detail.work" file doesn't exist.  Let's see if we can rename one.
 */
static int work_rename(proto_detail_file_thread_t *thread)
{
	proto_detail_file_t const *inst = thread->inst;
	unsigned int	i;
	int		found;
	time_t		chtime;
	char const	*filename;
	glob_t		files;
	struct stat	st;

	DEBUG3("proto_detail (%s): polling for detail files in %s",
	       thread->name, inst->directory);

	memset(&files, 0, sizeof(files));
	if (glob(inst->filename, 0, NULL, &files) != 0) {
	noop:
		DEBUG3("proto_detail (%s): no matching files for %s",
		       thread->name, inst->filename);
		globfree(&files);
		return -1;
	}

	/*
	 *	Loop over the glob'd files, looking for the
	 *	oldest one.
	 */
	chtime = 0;
	found = -1;
	for (i = 0; i < files.gl_pathc; i++) {
		if (stat(files.gl_pathv[i], &st) < 0) continue;

		if ((i == 0) || (st.st_ctime < chtime)) {
			chtime = st.st_ctime;
			found = i;
		}
	}

	/*
	 *	No matching files, reset the timer and continue.
	 */
	if (found < 0) goto noop;

	/*
	 *	Rename detail to detail.work
	 */
	filename = files.gl_pathv[found];

	DEBUG("proto_detail (%s): Renaming %s -> %s", thread->name, filename, inst->filename_work);
	if (rename(filename, inst->filename_work) < 0) {
		ERROR("detail (%s): Failed renaming %s to %s: %s",
		      thread->name, filename, inst->filename_work, fr_syserror(errno));
		goto noop;
	}

	globfree(&files);	/* Shouldn't be using anything in files now */

	/*
	 *	The file should now exist, return the open'd FD.
	 */
	return open(inst->filename_work, inst->mode);
}
static void work_init(proto_detail_file_thread_t *thread)
{
	proto_detail_file_t const *inst = thread->inst;
	int fd, rcode;
	bool has_worker;

	pthread_mutex_lock(&thread->worker_mutex);
	has_worker = (thread->num_workers != 0);
	pthread_mutex_unlock(&thread->worker_mutex);

	/*
	 *	The worker is still processing the file, poll until
	 *	it's done.
	 */
	if (has_worker) {
		DEBUG3("proto_detail (%s): worker %s is still alive, waiting for it to finish.",
		       thread->name, inst->filename_work);
		goto delay;
	}

	rad_assert(thread->vnode_fd < 0);

	/*
	 *	See if there is a "detail.work" file.  If not, try to
	 *	rename an existing file to "detail.work".
	 */
	DEBUG3("Trying to open %s", inst->filename_work);
	fd = open(inst->filename_work, inst->mode);

	/*
	 *	If the work file didn't exist, try to rename detail* ->
	 *	detail.work, and return the newly opened file.
	 */
	if (fd < 0) {
		if (errno != ENOENT) {
			DEBUG("proto_detail (%s): Failed opening %s: %s",
			      thread->name, inst->filename_work,
			      fr_syserror(errno));
			goto delay;
		}

retry:
		fd = work_rename(thread);
	}

	/*
	 *	The work file still doesn't exist.  Go set up timers,
	 *	or wait for an event which signals us that something
	 *	in the directory changed.
	 */
	if (fd < 0) {
		struct timeval when, now;

#ifdef __linux__
		/*
		 *	Wait for the directory to change before
		 *	looking for another "detail" file.
		 */
		if (!inst->poll_interval) return;
#endif

delay:
		/*
		 *	Check every N seconds.
		 */
		when.tv_sec = inst->poll_interval;
		when.tv_usec = 0;

		DEBUG3("Waiting %d.%06ds for new files in %s",
		       (int) when.tv_sec, (int) when.tv_usec, thread->name);

		gettimeofday(&now, NULL);

		fr_timeval_add(&when, &when, &now);

		if (fr_event_timer_insert(thread, thread->el, &thread->ev,
					  &when, work_retry_timer, thread) < 0) {
			ERROR("Failed inserting poll timer for %s", inst->filename_work);
		}
		return;
	}

	thread->lock_interval = USEC / 10;

	/*
	 *	It exists, go process it!
	 *
	 *	We will get back to the main loop when the
	 *	"detail.work" file is deleted.
	 */
	rcode = work_exists(thread, fd);
	if (rcode < 0) goto delay;

	/*
	 *	The file was empty, so we try to get another one.
	 */
	if (rcode == 1) goto retry;

	/*
	 *	Otherwise the child is successfully processing the
	 *	file.
	 */
}
Example #6
0
static void process_source_stat (stats_source_t *src_stats, stats_event_t *event)
{
    if (event->name)
    {
        stats_node_t *node = _find_node (src_stats->stats_tree, event->name);
        if (node == NULL)
        {
            /* adding node */
            if (event->action != STATS_EVENT_REMOVE && event->value)
            {
                DEBUG3 ("new node on %s \"%s\" (%s)", src_stats->source, event->name, event->value);
                node = (stats_node_t *)calloc (1,sizeof(stats_node_t));
                node->name = (char *)strdup (event->name);
                node->value = (char *)strdup (event->value);
                node->flags = event->flags;
                if (src_stats->flags & STATS_HIDDEN)
                    node->flags |= STATS_HIDDEN;
                stats_listener_send (node->flags, "EVENT %s %s %s\n", src_stats->source, event->name, event->value);
                avl_insert (src_stats->stats_tree, (void *)node);
            }
            return;
        }
        if (event->action == STATS_EVENT_REMOVE)
        {
            DEBUG2 ("delete node %s from %s", event->name, src_stats->source);
            stats_listener_send (node->flags, "DELETE %s %s\n", src_stats->source, event->name);
            avl_delete (src_stats->stats_tree, (void *)node, _free_stats);
            return;
        }
        modify_node_event (node, event);
        stats_listener_send (node->flags, "EVENT %s %s %s\n", src_stats->source, node->name, node->value);
        return;
    }
    if (event->action == STATS_EVENT_REMOVE && event->name == NULL)
    {
        avl_tree_unlock (src_stats->stats_tree);
        avl_tree_wlock (_stats.source_tree);
        avl_tree_wlock (src_stats->stats_tree);
        avl_delete (_stats.source_tree, (void *)src_stats, _free_source_stats);
        avl_tree_unlock (_stats.source_tree);
        return;
    }
    /* change source flags status */
    if (event->action & STATS_EVENT_HIDDEN)
    {
        avl_node *node = avl_get_first (src_stats->stats_tree);
        int visible = 0;

        if ((event->flags&STATS_HIDDEN) == (src_stats->flags&STATS_HIDDEN))
            return;
        if (src_stats->flags & STATS_HIDDEN)
        {
            stats_node_t *ct = _find_node (src_stats->stats_tree, "server_type");
            const char *type = "audio/mpeg";
            if (ct)
                type = ct->value;
            src_stats->flags &= ~STATS_HIDDEN;
            stats_listener_send (src_stats->flags, "NEW %s %s\n", type, src_stats->source);
            visible = 1;
        }
        else
        {
            stats_listener_send (src_stats->flags, "DELETE %s\n", src_stats->source);
            src_stats->flags |= STATS_HIDDEN;
        }
        while (node)
        {
            stats_node_t *stats = (stats_node_t*)node->key;
            if (visible)
            {
                stats->flags &= ~STATS_HIDDEN;
                stats_listener_send (stats->flags, "EVENT %s %s %s\n", src_stats->source, stats->name, stats->value);
            }
            else
                stats->flags |= STATS_HIDDEN;
            node = avl_get_next (node);
        }
    }
}
/**
 * Transaction 3 - T3
 *
 * Read session details
 *
 * Input:
 *   SubscriberNumber
 *   ServerId
 *   ServerBit
 *
 * Output:
 *   BranchExecuted
 *   SessionDetails
 *   ChangedBy
 *   ChangedTime
 *   Location
 */
int
T3(void * obj,
   const SubscriberNumber   inNumber,
   const SubscriberSuffix   inSuffix,
   const ServerId           inServerId,
   const ServerBit          inServerBit,
   SessionDetails     outSessionDetails,
   ChangedBy          outChangedBy,
   ChangedTime        outChangedTime,
   Location         * outLocation,
   BranchExecuted   * outBranchExecuted,
   BenchmarkTime    * outTransactionTime){
  
  Ndb * pNDB = (Ndb *) obj;

  GroupId        groupId;
  ActiveSessions sessions;
  Permission     permission;

  BenchmarkTime start;
  get_time(&start);

  int check;
  NdbRecAttr * check2;

  NdbConnection * MyTransaction = pNDB->startTransaction();
  if (MyTransaction == NULL)	  
    error_handler("T3-1: startTranscation", pNDB->getNdbErrorString(), 0);
  
  NdbOperation *MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
  CHECK_NULL(MyOperation, "T3-1: getNdbOperation", 
	     MyTransaction);
  
  
  check = MyOperation->readTuple();
  CHECK_MINUS_ONE(check, "T3-1: readTuple", 
		  MyTransaction);
  
  check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, 
			     inNumber);
  CHECK_MINUS_ONE(check, "T3-1: equal subscriber",
		  MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, 
				 (char *)outLocation);
  CHECK_NULL(check2, "T3-1: getValue location", 
	     MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, 
				 outChangedBy);
  CHECK_NULL(check2, "T3-1: getValue changed_by", 
	     MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
                                 outChangedTime);
  CHECK_NULL(check2, "T3-1: getValue changed_time",
	     MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP,
				 (char *)&groupId);
  CHECK_NULL(check2, "T3-1: getValue group", 
	     MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
				 (char *)&sessions);
  CHECK_NULL(check2, "T3-1: getValue sessions", 
	     MyTransaction);
  
  check = MyTransaction->execute( NoCommit ); 
  CHECK_MINUS_ONE(check, "T3-1: NoCommit", 
		  MyTransaction);
  
    /* Operation 2 */

  MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
  CHECK_NULL(MyOperation, "T3-2: getNdbOperation", 
	     MyTransaction);
  
  
  check = MyOperation->readTuple();
  CHECK_MINUS_ONE(check, "T3-2: readTuple", 
		  MyTransaction);
  
  check = MyOperation->equal(IND_GROUP_ID,
		     (char*)&groupId);
  CHECK_MINUS_ONE(check, "T3-2: equal group",
		  MyTransaction);
  
  check2 = MyOperation->getValue(IND_GROUP_ALLOW_READ, 
				 (char *)&permission);
  CHECK_NULL(check2, "T3-2: getValue allow_read", 
	     MyTransaction);

  check = MyTransaction->execute( NoCommit ); 
  CHECK_MINUS_ONE(check, "T3-2: NoCommit", 
		  MyTransaction);
  
  DEBUG3("T3(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);

  if(((permission & inServerBit) == inServerBit) &&
     ((sessions   & inServerBit) == inServerBit)){
    
    DEBUG("reading - ");

    /* Operation 3 */

    MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
    CHECK_NULL(MyOperation, "T3-3: getNdbOperation", 
	       MyTransaction);
    
    check = MyOperation->readTuple();
    CHECK_MINUS_ONE(check, "T3-3: readTuple", 
		    MyTransaction);
    
    check = MyOperation->equal(IND_SESSION_SUBSCRIBER,
			       (char*)inNumber);
    CHECK_MINUS_ONE(check, "T3-3: equal number",
		    MyTransaction);

    check = MyOperation->equal(IND_SESSION_SERVER,
			       (char*)&inServerId);
    CHECK_MINUS_ONE(check, "T3-3: equal server id",
		    MyTransaction);
    
    check2 = MyOperation->getValue(IND_SESSION_DATA, 
				   (char *)outSessionDetails);
    CHECK_NULL(check2, "T3-3: getValue session details", 
	       MyTransaction);
    
    check = MyTransaction->execute( NoCommit ); 
    CHECK_MINUS_ONE(check, "T3-3: NoCommit", 
		    MyTransaction);

    /* Operation 4 */

    MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
    CHECK_NULL(MyOperation, "T3-4: getNdbOperation", 
	       MyTransaction);
    
    check = MyOperation->interpretedUpdateTuple();
    CHECK_MINUS_ONE(check, "T3-4: interpretedUpdateTuple", 
		    MyTransaction);
    
    check = MyOperation->equal(IND_SERVER_ID,
			       (char*)&inServerId);
    CHECK_MINUS_ONE(check, "T3-4: equal serverId",
		    MyTransaction);

    check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
			       (char*)inSuffix);
    CHECK_MINUS_ONE(check, "T3-4: equal suffix",
		    MyTransaction);

    check = MyOperation->incValue(IND_SERVER_READS, (uint32)1);
    CHECK_MINUS_ONE(check, "T3-4: inc value",
		    MyTransaction);
    
    check = MyTransaction->execute( NoCommit ); 
    CHECK_MINUS_ONE(check, "T3-4: NoCommit", 
		    MyTransaction);

    (* outBranchExecuted) = 1;
  } else {
    (* outBranchExecuted) = 0;
  }
  DEBUG("commit\n");
  check = MyTransaction->execute( Commit ); 
  CHECK_MINUS_ONE(check, "T3: Commit", 
		  MyTransaction);
  
  pNDB->closeTransaction(MyTransaction);
  
  get_time(outTransactionTime);
  time_diff(outTransactionTime, &start);
  return 0;
}
Example #8
0
File: utils.c Project: JMED106/2pop
t_data Scan_Data(char *file, t_data d) {
  char c, mesg[100],arg[10], valor[10],aux[100];
  FILE *fin;
  int lines = 0, *linea_vacia,  i = 0, j = 0, error = 0;
  t_data data;  
  data = d;
  linea_vacia = (int*) calloc (1, sizeof(int));
  
  printf("\nOpening data file %s ...............",file);
  if ((fin = fopen (file, "r")) == NULL) {			/* Abrimos el archivo de datos */
    printf(" FAILED\n");
    fprintf (stderr, "\nERROR: File ’%s’ does not exist or it can't be read......... TERMINATED\n\n", file);
    exit(1);
  }
  else
    printf(" OK\n");

  printf("Reading data file %s ...............",file);
  fflush(stdin);
  fflush(stdout);

  while((c = getc(fin)) != EOF) { /* Leemos el archivo de datos */
    if(c == '#'){ /* Si se detecta una # como primer carácter de línea... */
      linea_vacia[lines] = 1;
      DEBUG3("Comentario Encontrado");
    }
    if(c == '\n') {
      DEBUG3("Línea encontrada");
      lines++;
      linea_vacia = (int*) realloc (linea_vacia,(lines+1)*sizeof(int));
      linea_vacia[lines] = 0;
    }
  }
  rewind(fin);
  for(j = 0; j < lines; j++) {
    sprintf(mesg,"línea %d: vacía: %d ",j,linea_vacia[j] );
    DEBUG3(mesg);
    if(linea_vacia[j] == 0)  {
      DEBUG("Escaneando línea");
      fscanf(fin,"%s\n",arg);
      if(isdigit(arg[0])) {
	printf("\nERROR de lectura: la línea %d tiene formato incorrecto\n",lines);
	error = 1;
      }
      else {
	i = 0;
	while(arg[i+2] != '\0') {
	  valor[i] = arg[i+2];
	  i++;
	}
	valor[i] = '\0';
	sprintf(mesg,"Valor de %c = %s",arg[0],valor);
	DEBUG(mesg);
	sprintf(mesg,"Valor de %c = %lf (convertido)\n",arg[0],atof(valor));
	DEBUG(mesg);
      }
      data = Variables(arg[0],valor, d);
      sprintf(mesg,"data.init_dist = %d\t data.vr = %lf ",data.init_dist,data.vr );
  DEBUG(mesg);
      d = data;
sprintf(mesg,"data.init_dist = %d\t data.vr = %lf ",data.init_dist,data.vr );
 DEBUG(mesg);
    } else {
       fscanf(fin," %[^\n]s",aux);
    }
  }
  
  fclose(fin);
  if(error == 0) printf(" OK\n");
  else		 printf(" ERROR\n");

  sprintf(mesg,"data.vr = %lf ",data.vr );
  DEBUG(mesg);

  return data;
}
Example #9
0
GLOBAL Int UMF_transpose
(
    Int n_row,			/* A is n_row-by-n_col */
    Int n_col,
    const Int Ap [ ],		/* size n_col+1 */
    const Int Ai [ ],		/* size nz = Ap [n_col] */
    const double Ax [ ],	/* size nz if present */

    const Int P [ ],	/* P [k] = i means original row i is kth row in A(P,Q)*/
			/* P is identity if not present */
			/* size n_row, if present */

    const Int Q [ ],	/* Q [k] = j means original col j is kth col in A(P,Q)*/
			/* Q is identity if not present */
			/* size nq, if present */
    Int nq,		/* size of Q, ignored if Q is (Int *) NULL */

			/* output matrix: Rp, Ri, Rx, and Rz: */
    Int Rp [ ],		/* size n_row+1 */
    Int Ri [ ],		/* size nz */
    double Rx [ ],	/* size nz, if present */

    Int W [ ],		/* size max (n_row,n_col) workspace */

    Int check		/* if true, then check inputs */
#ifdef COMPLEX
    , const double Az [ ]	/* size nz */
    , double Rz [ ]		/* size nz */
    , Int do_conjugate		/* if true, then do conjugate transpose */
				/* otherwise, do array transpose */
#endif
)
{

    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Int i, j, k, p, bp, newj, do_values ;
#ifdef COMPLEX
    Int split ;
#endif

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    Int nz ;
    ASSERT (n_col >= 0) ;
    nz = (Ap != (Int *) NULL) ? Ap [n_col] : 0 ;
    DEBUG2 (("UMF_transpose: "ID"-by-"ID" nz "ID"\n", n_row, n_col, nz)) ;
#endif

    if (check)
    {
	/* UMFPACK_symbolic skips this check */
	/* UMFPACK_transpose always does this check */
	if (!Ai || !Ap || !Ri || !Rp || !W)
	{
	    return (UMFPACK_ERROR_argument_missing) ;
	}
	if (n_row <= 0 || n_col <= 0)		/* n_row,n_col must be > 0 */
	{
	    return (UMFPACK_ERROR_n_nonpositive) ;
	}
	if (!UMF_is_permutation (P, W, n_row, n_row) ||
	    !UMF_is_permutation (Q, W, nq, nq))
	{
	    return (UMFPACK_ERROR_invalid_permutation) ;
	}
	if (!AMD_valid (n_row, n_col, Ap, Ai))
	{
	    return (UMFPACK_ERROR_invalid_matrix) ;
	}
    }

#ifndef NDEBUG
    DEBUG2 (("UMF_transpose, input matrix:\n")) ;
    UMF_dump_col_matrix (Ax,
#ifdef COMPLEX
	Az,
#endif
	Ai, Ap, n_row, n_col, nz) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* count the entries in each row of A */
    /* ---------------------------------------------------------------------- */

    /* use W as workspace for RowCount */

    for (i = 0 ; i < n_row ; i++)
    {
	W [i] = 0 ;
	Rp [i] = 0 ;
    }

    if (Q != (Int *) NULL)
    {
	for (newj = 0 ; newj < nq ; newj++)
	{
	    j = Q [newj] ;
	    ASSERT (j >= 0 && j < n_col) ;
	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
	    {
		i = Ai [p] ;
		ASSERT (i >= 0 && i < n_row) ;
		W [i]++ ;
	    }
	}
    }
    else
    {
	for (j = 0 ; j < n_col ; j++)
	{
	    for (p = Ap [j] ; p < Ap [j+1] ; p++)
	    {
		i = Ai [p] ;
		ASSERT (i >= 0 && i < n_row) ;
		W [i]++ ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* compute the row pointers for R = A (P,Q) */
    /* ---------------------------------------------------------------------- */

    if (P != (Int *) NULL)
    {
	Rp [0] = 0 ;
	for (k = 0 ; k < n_row ; k++)
	{
	    i = P [k] ;
	    ASSERT (i >= 0 && i < n_row) ;
	    Rp [k+1] = Rp [k] + W [i] ;
	}
	for (k = 0 ; k < n_row ; k++)
	{
	    i = P [k] ;
	    ASSERT (i >= 0 && i < n_row) ;
	    W [i] = Rp [k] ;
	}
    }
    else
    {
	Rp [0] = 0 ;
	for (i = 0 ; i < n_row ; i++)
	{
	    Rp [i+1] = Rp [i] + W [i] ;
	}
	for (i = 0 ; i < n_row ; i++)
	{
	    W [i] = Rp [i] ;
	}
    }
    ASSERT (Rp [n_row] <= Ap [n_col]) ;

    /* at this point, W holds the permuted row pointers */

    /* ---------------------------------------------------------------------- */
    /* construct the row form of B */
    /* ---------------------------------------------------------------------- */

    do_values = Ax && Rx ;

#ifdef COMPLEX
    split = SPLIT (Az) && SPLIT (Rz) ;

    if (do_conjugate && do_values)
    {
	if (Q != (Int *) NULL)
	{
	    if (split)
	    {
		/* R = A (P,Q)' */
		for (newj = 0 ; newj < nq ; newj++)
		{
		    j = Q [newj] ;
		    ASSERT (j >= 0 && j < n_col) ;
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			bp = W [Ai [p]]++ ;
			Ri [bp] = newj ;
			Rx [bp] = Ax [p] ;
			Rz [bp] = -Az [p] ;
		    }
		}
	    }
	    else
	    {
		/* R = A (P,Q)' (merged complex values) */
		for (newj = 0 ; newj < nq ; newj++)
		{
		    j = Q [newj] ;
		    ASSERT (j >= 0 && j < n_col) ;
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			bp = W [Ai [p]]++ ;
			Ri [bp] = newj ;
			Rx [2*bp] = Ax [2*p] ;
			Rx [2*bp+1] = -Ax [2*p+1] ;
		    }
		}
	    }
	}
	else
	{
	    if (split)
	    {
		/* R = A (P,:)' */
		for (j = 0 ; j < n_col ; j++)
		{
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			bp = W [Ai [p]]++ ;
			Ri [bp] = j ;
			Rx [bp] = Ax [p] ;
			Rz [bp] = -Az [p] ;
		    }
		}
	    }
	    else
	    {
		/* R = A (P,:)' (merged complex values) */
		for (j = 0 ; j < n_col ; j++)
		{
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			bp = W [Ai [p]]++ ;
			Ri [bp] = j ;
			Rx [2*bp] = Ax [2*p] ;
			Rx [2*bp+1] = -Ax [2*p+1] ;
		    }
		}
	    }
	}
    }
    else
#endif
    {
	if (Q != (Int *) NULL)
	{
	    if (do_values)
	    {
#ifdef COMPLEX
		if (split)
#endif
		{
		    /* R = A (P,Q).' */
		    for (newj = 0 ; newj < nq ; newj++)
		    {
			j = Q [newj] ;
			ASSERT (j >= 0 && j < n_col) ;
			for (p = Ap [j] ; p < Ap [j+1] ; p++)
			{
			    bp = W [Ai [p]]++ ;
			    Ri [bp] = newj ;
			    Rx [bp] = Ax [p] ;
#ifdef COMPLEX
			    Rz [bp] = Az [p] ;
#endif
			}
		    }
		}
#ifdef COMPLEX
		else
		{
		    /* R = A (P,Q).' (merged complex values) */
		    for (newj = 0 ; newj < nq ; newj++)
		    {
			j = Q [newj] ;
			ASSERT (j >= 0 && j < n_col) ;
			for (p = Ap [j] ; p < Ap [j+1] ; p++)
			{
			    bp = W [Ai [p]]++ ;
			    Ri [bp] = newj ;
			    Rx [2*bp] = Ax [2*p] ;
			    Rx [2*bp+1] = Ax [2*p+1] ;
			}
		    }
		}
#endif
	    }
	    else
	    {
		/* R = pattern of A (P,Q).' */
		for (newj = 0 ; newj < nq ; newj++)
		{
		    j = Q [newj] ;
		    ASSERT (j >= 0 && j < n_col) ;
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			Ri [W [Ai [p]]++] = newj ;
		    }
		}
	    }
	}
	else
	{
	    if (do_values)
	    {
#ifdef COMPLEX
		if (split)
#endif
		{
		    /* R = A (P,:).' */
		    for (j = 0 ; j < n_col ; j++)
		    {
			for (p = Ap [j] ; p < Ap [j+1] ; p++)
			{
			    bp = W [Ai [p]]++ ;
			    Ri [bp] = j ;
			    Rx [bp] = Ax [p] ;
#ifdef COMPLEX
			    Rz [bp] = Az [p] ;
#endif
			}
		    }
		}
#ifdef COMPLEX
		else
		{
		    /* R = A (P,:).' (merged complex values) */
		    for (j = 0 ; j < n_col ; j++)
		    {
			for (p = Ap [j] ; p < Ap [j+1] ; p++)
			{
			    bp = W [Ai [p]]++ ;
			    Ri [bp] = j ;
			    Rx [2*bp] = Ax [2*p] ;
			    Rx [2*bp+1] = Ax [2*p+1] ;
			}
		    }
		}
#endif
	    }
	    else
	    {
		/* R = pattern of A (P,:).' */
		for (j = 0 ; j < n_col ; j++)
		{
		    for (p = Ap [j] ; p < Ap [j+1] ; p++)
		    {
			Ri [W [Ai [p]]++] = j ;
		    }
		}
	    }
	}
    }

#ifndef NDEBUG
    for (k = 0 ; k < n_row ; k++)
    {
	if (P != (Int *) NULL)
	{
	    i = P [k] ;
	}
	else
	{
	    i = k ;
	}
	DEBUG3 ((ID":  W[i] "ID" Rp[k+1] "ID"\n", i, W [i], Rp [k+1])) ;
	ASSERT (W [i] == Rp [k+1]) ;
    }
    DEBUG2 (("UMF_transpose, output matrix:\n")) ;
    UMF_dump_col_matrix (Rx,
#ifdef COMPLEX
	Rz,
#endif
	Ri, Rp, n_col, n_row, Rp [n_row]) ;
    ASSERT (AMD_valid (n_col, n_row, Rp, Ri)) ;
#endif

    return (UMFPACK_OK) ;
}
Example #10
0
GLOBAL Int UMF_create_element
(
    NumericType *Numeric,
    WorkType *Work,
    SymbolicType *Symbolic
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Int j, col, row, *Fcols, *Frows, fnrows, fncols, *Cols, len, needunits, t1,
        t2, size, e, i, *E, *Fcpos, *Frpos, *Rows, eloc, fnr_curr, f,
        got_memory, *Row_tuples, *Row_degree, *Row_tlen, *Col_tuples, max_mark,
        *Col_degree, *Col_tlen, nn, n_row, n_col, r2, c2, do_Fcpos ;
    Entry *C, *Fcol ;
    Element *ep ;
    Unit *p, *Memory ;
    Tuple *tp, *tp1, *tp2, tuple, *tpend ;
#ifndef NDEBUG
    DEBUG2 (("FRONTAL WRAPUP\n")) ;
    UMF_dump_current_front (Numeric, Work, TRUE) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* get parameters */
    /* ---------------------------------------------------------------------- */

    ASSERT (Work->fnpiv == 0) ;
    ASSERT (Work->fnzeros == 0) ;
    Row_degree = Numeric->Rperm ;
    Row_tuples = Numeric->Uip ;
    Row_tlen   = Numeric->Uilen ;
    Col_degree = Numeric->Cperm ;
    Col_tuples = Numeric->Lip ;
    Col_tlen   = Numeric->Lilen ;
    n_row = Work->n_row ;
    n_col = Work->n_col ;
    nn = MAX (n_row, n_col) ;
    Fcols = Work->Fcols ;
    Frows = Work->Frows ;
    Fcpos = Work->Fcpos ;
    Frpos = Work->Frpos ;
    Memory = Numeric->Memory ;
    fncols = Work->fncols ;
    fnrows = Work->fnrows ;

    tp = (Tuple *) NULL ;
    tp1 = (Tuple *) NULL ;
    tp2 = (Tuple *) NULL ;

    /* ---------------------------------------------------------------------- */
    /* add the current frontal matrix to the degrees of each column */
    /* ---------------------------------------------------------------------- */

    if (!Symbolic->fixQ)
    {
        /* but only if the column ordering is not fixed */
#pragma ivdep
        for (j = 0 ; j < fncols ; j++)
        {
            /* add the current frontal matrix to the degree */
            ASSERT (Fcols [j] >= 0 && Fcols [j] < n_col) ;
            Col_degree [Fcols [j]] += fnrows ;
        }
    }

    /* ---------------------------------------------------------------------- */
    /* add the current frontal matrix to the degrees of each row */
    /* ---------------------------------------------------------------------- */

#pragma ivdep
    for (i = 0 ; i < fnrows ; i++)
    {
        /* add the current frontal matrix to the degree */
        ASSERT (Frows [i] >= 0 && Frows [i] < n_row) ;
        Row_degree [Frows [i]] += fncols ;
    }

    /* ---------------------------------------------------------------------- */
    /* Reset the external degree counters */
    /* ---------------------------------------------------------------------- */

    E = Work->E ;
    max_mark = MAX_MARK (nn) ;

    if (!Work->pivcol_in_front)
    {
        /* clear the external column degrees. no more Usons of current front */
        Work->cdeg0 += (nn + 1) ;
        if (Work->cdeg0 >= max_mark)
        {
            /* guard against integer overflow.  This is very rare */
            DEBUG1 (("Integer overflow, cdeg\n")) ;
            Work->cdeg0 = 1 ;
#pragma ivdep
            for (e = 1 ; e <= Work->nel ; e++)
            {
                if (E [e])
                {
                    ep = (Element *) (Memory + E [e]) ;
                    ep->cdeg = 0 ;
                }
            }
        }
    }

    if (!Work->pivrow_in_front)
    {
        /* clear the external row degrees.  no more Lsons of current front */
        Work->rdeg0 += (nn + 1) ;
        if (Work->rdeg0 >= max_mark)
        {
            /* guard against integer overflow.  This is very rare */
            DEBUG1 (("Integer overflow, rdeg\n")) ;
            Work->rdeg0 = 1 ;
#pragma ivdep
            for (e = 1 ; e <= Work->nel ; e++)
            {
                if (E [e])
                {
                    ep = (Element *) (Memory + E [e]) ;
                    ep->rdeg = 0 ;
                }
            }
        }
    }

    /* ---------------------------------------------------------------------- */
    /* clear row/col offsets */
    /* ---------------------------------------------------------------------- */

    if (!Work->pivrow_in_front)
    {
#pragma ivdep
        for (j = 0 ; j < fncols ; j++)
        {
            Fcpos [Fcols [j]] = EMPTY ;
        }
    }

    if (!Work->pivcol_in_front)
    {
#pragma ivdep
        for (i = 0 ; i < fnrows ; i++)
        {
            Frpos [Frows [i]] = EMPTY ;
        }
    }

    if (fncols <= 0 || fnrows <= 0)
    {
        /* no element to create */
        DEBUG2 (("Element evaporation\n")) ;
        Work->prior_element = EMPTY ;
        return (TRUE) ;
    }

    /* ---------------------------------------------------------------------- */
    /* create element for later assembly */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    UMF_allocfail = FALSE ;
    if (UMF_gprob > 0)
    {
        double rrr = ((double) (rand ( ))) / (((double) RAND_MAX) + 1) ;
        DEBUG4 (("Check random %e %e\n", rrr, UMF_gprob)) ;
        UMF_allocfail = rrr < UMF_gprob ;
        if (UMF_allocfail) DEBUGm2 (("Random garbage collection (create)\n"));
    }
#endif

    needunits = 0 ;
    got_memory = FALSE ;
    eloc = UMF_mem_alloc_element (Numeric, fnrows, fncols, &Rows, &Cols, &C,
                                  &needunits, &ep) ;

    /* if UMF_get_memory needs to be called */
    if (Work->do_grow)
    {
        /* full compaction of current frontal matrix, since UMF_grow_front will
         * be called next anyway. */
        r2 = fnrows ;
        c2 = fncols ;
        do_Fcpos = FALSE ;
    }
    else
    {
        /* partial compaction. */
        r2 = MAX (fnrows, Work->fnrows_new + 1) ;
        c2 = MAX (fncols, Work->fncols_new + 1) ;
        /* recompute Fcpos if pivot row is in the front */
        do_Fcpos = Work->pivrow_in_front ;
    }

    if (!eloc)
    {
        /* Do garbage collection, realloc, and try again. */
        /* Compact the current front if it needs to grow anyway. */
        /* Note that there are no pivot rows or columns in the current front */
        DEBUGm3 (("get_memory from umf_create_element, 1\n")) ;
        if (!UMF_get_memory (Numeric, Work, needunits, r2, c2, do_Fcpos))
        {
            /* :: out of memory in umf_create_element (1) :: */
            DEBUGm4 (("out of memory: create element (1)\n")) ;
            return (FALSE) ;	/* out of memory */
        }
        got_memory = TRUE ;
        Memory = Numeric->Memory ;
        eloc = UMF_mem_alloc_element (Numeric, fnrows, fncols, &Rows, &Cols, &C,
                                      &needunits, &ep) ;
        ASSERT (eloc >= 0) ;
        if (!eloc)
        {
            /* :: out of memory in umf_create_element (2) :: */
            DEBUGm4 (("out of memory: create element (2)\n")) ;
            return (FALSE) ;	/* out of memory */
        }
    }

    e = ++(Work->nel) ;	/* get the name of this new frontal matrix */
    Work->prior_element = e ;
    DEBUG8 (("wrapup e "ID" nel "ID"\n", e, Work->nel)) ;

    ASSERT (e > 0 && e < Work->elen) ;
    ASSERT (E [e] == 0) ;
    E [e] = eloc ;

    if (Work->pivcol_in_front)
    {
        /* the new element is a Uson of the next frontal matrix */
        ep->cdeg = Work->cdeg0 ;
    }

    if (Work->pivrow_in_front)
    {
        /* the new element is an Lson of the next frontal matrix */
        ep->rdeg = Work->rdeg0 ;
    }

    /* ---------------------------------------------------------------------- */
    /* copy frontal matrix into the new element */
    /* ---------------------------------------------------------------------- */

#pragma ivdep
    for (i = 0 ; i < fnrows ; i++)
    {
        Rows [i] = Frows [i] ;
    }
#pragma ivdep
    for (i = 0 ; i < fncols ; i++)
    {
        Cols [i] = Fcols [i] ;
    }
    Fcol = Work->Fcblock ;
    DEBUG0 (("copy front "ID" by "ID"\n", fnrows, fncols)) ;
    fnr_curr = Work->fnr_curr ;
    ASSERT (fnr_curr >= 0 && fnr_curr % 2 == 1) ;
    for (j = 0 ; j < fncols ; j++)
    {
        copy_column (fnrows, Fcol, C) ;
        Fcol += fnr_curr ;
        C += fnrows ;
    }

    DEBUG8 (("element copied\n")) ;

    /* ---------------------------------------------------------------------- */
    /* add tuples for the new element */
    /* ---------------------------------------------------------------------- */

    tuple.e = e ;

    if (got_memory)
    {

        /* ------------------------------------------------------------------ */
        /* UMF_get_memory ensures enough space exists for each new tuple */
        /* ------------------------------------------------------------------ */

        /* place (e,f) in the element list of each column */
        for (tuple.f = 0 ; tuple.f < fncols ; tuple.f++)
        {
            col = Fcols [tuple.f] ;
            ASSERT (col >= 0 && col < n_col) ;
            ASSERT (NON_PIVOTAL_COL (col)) ;
            ASSERT (Col_tuples [col]) ;
            tp = ((Tuple *) (Memory + Col_tuples [col])) + Col_tlen [col]++ ;
            *tp = tuple ;
        }

        /* ------------------------------------------------------------------ */

        /* place (e,f) in the element list of each row */
        for (tuple.f = 0 ; tuple.f < fnrows ; tuple.f++)
        {
            row = Frows [tuple.f] ;
            ASSERT (row >= 0 && row < n_row) ;
            ASSERT (NON_PIVOTAL_ROW (row)) ;
            ASSERT (Row_tuples [row]) ;
            tp = ((Tuple *) (Memory + Row_tuples [row])) + Row_tlen [row]++ ;
            *tp = tuple ;
        }

    }
    else
    {

        /* ------------------------------------------------------------------ */
        /* place (e,f) in the element list of each column */
        /* ------------------------------------------------------------------ */

        /* might not have enough space for each tuple */

        for (tuple.f = 0 ; tuple.f < fncols ; tuple.f++)
        {
            col = Fcols [tuple.f] ;
            ASSERT (col >= 0 && col < n_col) ;
            ASSERT (NON_PIVOTAL_COL (col)) ;
            t1 = Col_tuples [col] ;
            DEBUG1 (("Placing on col:"ID" , tuples at "ID"\n",
                     col, Col_tuples [col])) ;

            size = 0 ;
            len = 0 ;

            if (t1)
            {
                p = Memory + t1 ;
                tp = (Tuple *) p ;
                size = GET_BLOCK_SIZE (p) ;
                len = Col_tlen [col] ;
                tp2 = tp + len ;
            }

            needunits = UNITS (Tuple, len + 1) ;
            DEBUG1 (("len: "ID" size: "ID" needunits: "ID"\n",
                     len, size, needunits));

            if (needunits > size && t1)
            {
                /* prune the tuples */
                tp1 = tp ;
                tp2 = tp ;
                tpend = tp + len ;
                for ( ; tp < tpend ; tp++)
                {
                    e = tp->e ;
                    ASSERT (e > 0 && e <= Work->nel) ;
                    if (!E [e]) continue ;   /* element already deallocated */
                    f = tp->f ;
                    p = Memory + E [e] ;
                    ep = (Element *) p ;
                    p += UNITS (Element, 1) ;
                    Cols = (Int *) p ;
                    ;
                    if (Cols [f] == EMPTY) continue ;	/* already assembled */
                    ASSERT (col == Cols [f]) ;
                    *tp2++ = *tp ;	/* leave the tuple in the list */
                }
                len = tp2 - tp1 ;
                Col_tlen [col] = len ;
                needunits = UNITS (Tuple, len + 1) ;
            }

            if (needunits > size)
            {
                /* no room exists - reallocate elsewhere */
                DEBUG1 (("REALLOCATE Col: "ID", size "ID" to "ID"\n",
                         col, size, 2*needunits)) ;

#ifndef NDEBUG
                UMF_allocfail = FALSE ;
                if (UMF_gprob > 0)  /* a double relop, but ignore NaN case */
                {
                    double rrr = ((double) (rand ( ))) /
                                 (((double) RAND_MAX) + 1) ;
                    DEBUG1 (("Check random %e %e\n", rrr, UMF_gprob)) ;
                    UMF_allocfail = rrr < UMF_gprob ;
                    if (UMF_allocfail) DEBUGm2 (("Random gar. (col tuple)\n")) ;
                }
#endif

                needunits = MIN (2*needunits, (Int) UNITS (Tuple, nn)) ;
                t2 = UMF_mem_alloc_tail_block (Numeric, needunits) ;
                if (!t2)
                {
                    /* :: get memory in umf_create_element (1) :: */
                    /* get memory, reconstruct all tuple lists, and return */
                    /* Compact the current front if it needs to grow anyway. */
                    /* Note: no pivot rows or columns in the current front */
                    DEBUGm4 (("get_memory from umf_create_element, 1\n")) ;
                    return (UMF_get_memory (Numeric, Work, 0, r2, c2,do_Fcpos));
                }
                Col_tuples [col] = t2 ;
                tp2 = (Tuple *) (Memory + t2) ;
                if (t1)
                {
                    for (i = 0 ; i < len ; i++)
                    {
                        *tp2++ = *tp1++ ;
                    }
                    UMF_mem_free_tail_block (Numeric, t1) ;
                }
            }

            /* place the new (e,f) tuple in the element list of the column */
            Col_tlen [col]++ ;
            *tp2 = tuple ;
        }

        /* ------------------------------------------------------------------ */
        /* place (e,f) in the element list of each row */
        /* ------------------------------------------------------------------ */

        for (tuple.f = 0 ; tuple.f < fnrows ; tuple.f++)
        {
            row = Frows [tuple.f] ;
            ASSERT (row >= 0 && row < n_row) ;
            ASSERT (NON_PIVOTAL_ROW (row)) ;
            t1 = Row_tuples [row] ;
            DEBUG1 (("Placing on row:"ID" , tuples at "ID"\n",
                     row, Row_tuples [row])) ;

            size = 0 ;
            len = 0 ;
            if (t1)
            {
                p = Memory + t1 ;
                tp = (Tuple *) p ;
                size = GET_BLOCK_SIZE (p) ;
                len = Row_tlen [row] ;
                tp2 = tp + len ;
            }

            needunits = UNITS (Tuple, len + 1) ;
            DEBUG1 (("len: "ID" size: "ID" needunits: "ID"\n",
                     len, size, needunits)) ;

            if (needunits > size && t1)
            {
                /* prune the tuples */
                tp1 = tp ;
                tp2 = tp ;
                tpend = tp + len ;
                for ( ; tp < tpend ; tp++)
                {
                    e = tp->e ;
                    ASSERT (e > 0 && e <= Work->nel) ;
                    if (!E [e])
                    {
                        continue ;	/* element already deallocated */
                    }
                    f = tp->f ;
                    p = Memory + E [e] ;
                    ep = (Element *) p ;
                    p += UNITS (Element, 1) ;
                    Cols = (Int *) p ;
                    Rows = Cols + (ep->ncols) ;
                    if (Rows [f] == EMPTY) continue ;	/* already assembled */
                    ASSERT (row == Rows [f]) ;
                    *tp2++ = *tp ;	/* leave the tuple in the list */
                }
                len = tp2 - tp1 ;
                Row_tlen [row] = len ;
                needunits = UNITS (Tuple, len + 1) ;
            }

            if (needunits > size)
            {
                /* no room exists - reallocate elsewhere */
                DEBUG1 (("REALLOCATE Row: "ID", size "ID" to "ID"\n",
                         row, size, 2*needunits)) ;

#ifndef NDEBUG
                UMF_allocfail = FALSE ;
                if (UMF_gprob > 0)  /* a double relop, but ignore NaN case */
                {
                    double rrr = ((double) (rand ( ))) /
                                 (((double) RAND_MAX) + 1) ;
                    DEBUG1 (("Check random %e %e\n", rrr, UMF_gprob)) ;
                    UMF_allocfail = rrr < UMF_gprob ;
                    if (UMF_allocfail) DEBUGm2 (("Random gar. (row tuple)\n")) ;
                }
#endif

                needunits = MIN (2*needunits, (Int) UNITS (Tuple, nn)) ;
                t2 = UMF_mem_alloc_tail_block (Numeric, needunits) ;
                if (!t2)
                {
                    /* :: get memory in umf_create_element (2) :: */
                    /* get memory, reconstruct all tuple lists, and return */
                    /* Compact the current front if it needs to grow anyway. */
                    /* Note: no pivot rows or columns in the current front */
                    DEBUGm4 (("get_memory from umf_create_element, 2\n")) ;
                    return (UMF_get_memory (Numeric, Work, 0, r2, c2,do_Fcpos));
                }
                Row_tuples [row] = t2 ;
                tp2 = (Tuple *) (Memory + t2) ;
                if (t1)
                {
                    for (i = 0 ; i < len ; i++)
                    {
                        *tp2++ = *tp1++ ;
                    }
                    UMF_mem_free_tail_block (Numeric, t1) ;
                }
            }

            /* place the new (e,f) tuple in the element list of the row */
            Row_tlen [row]++ ;
            *tp2 = tuple ;
        }

    }

    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    DEBUG1 (("Done extending\nFINAL: element row pattern: len="ID"\n", fncols));
    for (j = 0 ; j < fncols ; j++) DEBUG1 ((""ID"\n", Fcols [j])) ;
    DEBUG1 (("FINAL: element col pattern:  len="ID"\n", fnrows)) ;
    for (j = 0 ; j < fnrows ; j++) DEBUG1 ((""ID"\n", Frows [j])) ;
    for (j = 0 ; j < fncols ; j++)
    {
        col = Fcols [j] ;
        ASSERT (col >= 0 && col < n_col) ;
        UMF_dump_rowcol (1, Numeric, Work, col, !Symbolic->fixQ) ;
    }
    for (j = 0 ; j < fnrows ; j++)
    {
        row = Frows [j] ;
        ASSERT (row >= 0 && row < n_row) ;
        UMF_dump_rowcol (0, Numeric, Work, row, TRUE) ;
    }
    if (n_row < 1000 && n_col < 1000)
    {
        UMF_dump_memory (Numeric) ;
    }
    DEBUG1 (("New element, after filling with stuff: "ID"\n", e)) ;
    UMF_dump_element (Numeric, Work, e, TRUE) ;
    if (nn < 1000)
    {
        DEBUG4 (("Matrix dump, after New element: "ID"\n", e)) ;
        UMF_dump_matrix (Numeric, Work, TRUE) ;
    }
    DEBUG3 (("FRONTAL WRAPUP DONE\n")) ;
#endif

    return (TRUE) ;
}
Example #11
0
/**
 *  @param argc Number of command line arguments
 *  @param argv Array of command line arguments
 * Usage:   [CORBA OPTIONS] [OPTIONS]
 *     -  -h             : This help text
 *     -  -v             : Prints out the version
 *     -  -file Filename : Read XML data from here
 *     -  -f    Filename : Read XML data from here
 *     -  -ecname NAME   : The name of the event channel
 *     -  -e      NAME   : The name of the event channel
 */
int
main (int argc, char *argv[])
{
  QMS_Trace ("main", __LINE__, __FILE__);
  DEBUG0 (DEBUG_L_ENTER, "DEBUG: starting\n");
  signal(SIGTERM,sig_handler);
  signal(SIGINT,sig_handler);
  signal(SIGABRT,sig_handler);
  signal(SIGHUP,sig_handler);

  DEBUG0 (DEBUG_L_CALL, "DEBUG: added signal handling\n");
  ACE_OS::srand(time(0));

  DEBUG3 (DEBUG_L_CALL, "DEBUG: starting the API With ID = %d"
	  " Send event type = %d Recieve event type = %d\n" ,
	  Query_Supplier, QMS_Remos_Query, QMS_Remos_Data);

  char * ecname_p = (char *) "QMS_Channel";

  DEBUG0 (DEBUG_L_CALL, "DEBUG: parsing arguments\n");
  for (int i = 0; i < argc; i++)
   {
     if (!argv[i])           { break; }
     if (argv[i][0] != '-')  { continue; }
     int j = 1;
     if (argv[i][1] == '-')  {
       if (argv[i][2] == 0)  { break; }	// handle -- end of options
       j = 2;			// handle --argument
     }
     if (strstr((argv[i] + j), "ORB"))  { continue; }
     if (! strcmp((argv[i] + j), "help") || strchr((argv[i] + j), 'h'))
      {				// -h or --help
	cout << argv[0] << version << endl
	     << "Usage: " << argv[0] << "[CORBA OPTIONS] [OPTIONS]"
	     << endl
	     << "\t-h             : This help text"  << endl
	     << "\t-v             : Prints out the version"  << endl
	     << "\t-file Filename : Read XML data from here"  << endl
	     << "\t-f    Filename : Read XML data from here"  << endl
	     << "\t-ecname NAME   : The name of the event channel"  << endl
	     << "\t-e      NAME   : The name of the event channel"  << endl
	  ;
	exit (0);
      }
     if (! strcmp((argv[i] + j), "version") || strchr((argv[i] + j), 'v'))
      {
	cout << argv[0] << ": Version "<< version << endl;
	exit (0);
      }

     if (! strcmp((argv[i] + j), "file") || strchr((argv[i] + j), 'f'))
      {
	filename_p = (char *) malloc (sizeof(argv[i + 1]) + 1);
	strcpy(filename_p,argv[i + 1]);
	continue;
      }
     if (! strcmp((argv[i] + j), "ecname") || strchr((argv[i] + j), 'f'))
      {
	ecname_p = (char *) malloc (sizeof(argv[i + 1]) + 1);
	strcpy(ecname_p,argv[i + 1]);
	continue;
      }
     DEBUG1 (DEBUG_L_ERROR, "unknown argument %s", argv[i] );
   }


  ACE_DECLARE_NEW_CORBA_ENV;
  ACE_TRY
    {

      qms_api.init(argc, argv,
		   Query_Supplier,  // My ID
		   QMS_Remos_Query, //  The data I send
		   QMS_Remos_Data,  // The data I get
		   ecname_p
		   );
      ACE_TRY_CHECK;


      qms_api.register_callback(my_cb_func, 0);
      ACE_TRY_CHECK;
      qms_api.connect_supplier();
      ACE_TRY_CHECK;
      qms_api.connect_consumer();
      ACE_TRY_CHECK;

      DEBUG0 (DEBUG_L_CALL, "DEBUG: Spawning a thread\n");

      if (ACE_Thread::spawn((ACE_THR_FUNC)generate_query,
			    0,	// arg
			    THR_JOINABLE, // flags
			    0,	// t_id
			    0,	// t_handle
			    ACE_DEFAULT_THREAD_PRIORITY,
			    0,	// stack
			    0,	// stack_size
			    0	// thread_adapter
			    )==-1)
       {
	 DEBUG0 (DEBUG_L_ERROR, "DEBUG: Error in spawning thread\n");
       }
      DEBUG0 (DEBUG_L_CALL, "DEBUG: Entering Loop\n");
      qms_api.listen();
      ACE_TRY_CHECK;
    }
  ACE_CATCH (CORBA::SystemException, sysex)
    {
      ACE_PRINT_EXCEPTION (sysex, "System Exception :");
      qms_api.connect_supplier();
      qms_api.connect_consumer();
	exit (1);
    }
Example #12
0
/*@notnull@*/ void *allocandusespaceviaptr(char *file,Uint line, 
                                           /*@null@*/ void *ptr,
                                           Uint size,Uint number)
{
  Uint i, blocknum;

  DEBUG2(2,"\n# allocandusespaceviaptr(file=%s,line=%lu)\n",file,
                      (Showuint) line);
  if(nextfreeblock > 0)
  {
    NOTSUPPOSEDTOBENULL(blocks);
    for(blocknum=0; blocknum < nextfreeblock; blocknum++)
    {
      if(blocks[blocknum].spaceptr == ptr)
      {
        break;
      }
    }
  } else
  {
    blocknum = 0;
  }
  if(blocknum == nextfreeblock)
  {
    if(ptr == NULL)
    {
      nextfreeblock += 64;
      blocks = (Blockdescription *) realloc(blocks,
                                            (size_t) (sizeof(Blockdescription)* 
                                                      nextfreeblock));
      if(blocks == NULL)
      {
        ALLOCVIAFATAL("not enough space for the block descriptions available");
      }
      for(i=blocknum; i < nextfreeblock; i++)
      {
        blocks[i].spaceptr = NULL;
        blocks[i].sizeofcells = 0;
        blocks[i].numberofcells = 0;
      }
    } else
    {
      ALLOCVIAFATAL("cannot find space block");
    }
  }
  NOTSUPPOSEDTOBENULL(blocks);
  subtractspace(blocks[blocknum].numberofcells * blocks[blocknum].sizeofcells);
  addspace(size*number);
  DEBUG3(2,"# allocandusespaceviaptr:block %lu: %lu cells of size %lu\n",
            (Showuint) blocknum,(Showuint) number,(Showuint) size);
  DEBUG2(2,"# previously allocated for this block (%lu,%lu)\n",
            (Showuint) blocks[blocknum].numberofcells,
            (Showuint) blocks[blocknum].sizeofcells);
  blocks[blocknum].numberofcells = number;
  blocks[blocknum].sizeofcells = size;
  blocks[blocknum].fileallocated = file;
  blocks[blocknum].lineallocated = line;
  if(blocks[blocknum].spaceptr == NULL)
  {
    numberofblocks++;
  }
  if((blocks[blocknum].spaceptr 
      = realloc(blocks[blocknum].spaceptr,(size_t) (size*number))) == NULL)
  {
    ALLOCVIAFATAL("not enough memory");
  }
  DEBUG0(2,"# allocandusespaceviaptr Okay\n");
  NOTSUPPOSEDTOBENULL(blocks[blocknum].spaceptr);
  return blocks[blocknum].spaceptr;
}
Example #13
0
void
sdl_visual_put_pixel(VWKREF vwk,
                     int    x,
                     int    y,
                     int    c)
{
  Uint32        color;
  SDL_Surface * screen;

  DEBUG3("sdl_visual_put_pixel entered\n");
  
  screen = VISUAL_T(vwk->visual->private);

  /* printf("c = %d ", c);*/
  color = PENS(vwk->visual->private)[c];
  /*  printf("color = 0x%x\n", color);*/

  if(SDL_MUSTLOCK(screen))
  {
    if(SDL_LockSurface(screen) < 0)
    {
      return;
    }
  }

  if( WRITE_MODE(vwk->visual->private) == MD_XOR ) {
    printf("bpp = %d\n", screen->format->BytesPerPixel);
  }

  switch(screen->format->BytesPerPixel)
  {
  case 1: /* Assuming 8-bpp */
  {
    Uint8 *bufp;
    
    bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
    *bufp = color;
  }
  break;
  
  case 2: /* Probably 15-bpp or 16-bpp */
  {
    Uint16 * bufp;
    
    bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
    *bufp = color;
  }
  break;
  
  case 3: /* Slow 24-bpp mode, usually not used */
  {
    Uint8 * bufp;
    
    bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
    if(SDL_BYTEORDER == SDL_LIL_ENDIAN)
    {
      bufp[0] = color;
      bufp[1] = color >> 8;
      bufp[2] = color >> 16;
    }
    else
    {
      bufp[2] = color;
      bufp[1] = color >> 8;
      bufp[0] = color >> 16;
    }
  }
Example #14
0
unsigned int anak_kirim(
	unsigned int identifikasi,
	FILE *pberkas,
	RSA *rsapub,
	RSA *rsapriv,
	struct KIRIMBERKAS *kirim,
	struct INFOALAMAT *infoalamat,
	int ukuberkas_panjang
){
	char pesan[CHUNK_MESSAGE_SIZE];
	char pecahan[ENCRYPTED_CONTAINER_SIZE];
	size_t panjang_pesan=0;
	
	// Perilaku.
	int status=0;;
	int maksimal_coba=aturan.tries;
	int ulang_tunggu=aturan.waitretry;
	int urut_tunggu=aturan.waitqueue;
	unsigned int kelompok_kirim=kirim->kelompok_kirim;
	char *nama_berkas=kirim->berkas;
	
	// Identifikasi.
	bool identifikasi_awal=true;
	unsigned int identifikasi_sebelumnya=kirim->identifikasi_sebelumnya;
	
	// Pengepala Pecahan.
	int paritas=0;
	int panji=0;
	int status_gerbang=0;
	int status_peladen=0;
	
	// Tujuan.
	char *hostname=kirim->hostname;
	char *portno=kirim->portno;
	
	// Berurutan kirim.
	kirim->urut_kali++;
	
	// Membersihkan isi.
	memset(pesan, 0, CHUNK_MESSAGE_SIZE);
	memset(pecahan, 0, MAX_CHUNK_SIZE);
	
	// Bila identifikasi
	// lebih dari MAX_CHUNK_ID,
	// maka identifikasi adalah NOL.
	if(identifikasi>MAX_CHUNK_ID){
		DEBUG1(_("Telah melebihi maksimal identifikasi %1$i."), MAX_CHUNK_ID);
		DEBUG1(_("Nilai identifikasi adalah %1$i."), identifikasi);
		
		// Ke NOL.
		identifikasi=0;
		DEBUG1(_("Mengubah identifikasi ke nilai 0."), 0);
		
		// Keluar.
		DEBUG1(_("Tidak melanjutkan pengiriman."), 0);
		return identifikasi;
	};
	
	// Apakah pertama.
	if(kirim->paksa_panji!=UNDEFINED_FLAG){
		// Memaksa panji.
		panji=kirim->paksa_panji;
		kirim->paksa_panji=UNDEFINED_FLAG;
		
		// Pesan.
		DEBUG1(_("Memaksa panji '%1$s'."),arti_panji(panji));
		
		// Langsung berhenti bila panji STOP.
		if(panji==STOP_FLAG){
			
			// Mengirim panji STOP
			// dan keluar dari perulangan.
			DEBUG1(_("Menghentikan pengulangan pengiriman."), 0);
			kirim->do_kirim=false;
		};
		
	}else if(identifikasi==0){
		// Panji.
		panji=START_FLAG;
		
		// Memastikan nama berkas ada.
		if(!strlen(nama_berkas)){
			// Kesalahan.
			FAIL(_("Gagal memperoleh nama berkas."), 0);
			exit(EXIT_FAILURE_MEMORY);
		};
		
		// Pecahan pertama adalah
		// pecahan dengan informasi berkas.
		memcpy(pesan, buat_pesan_start(
			pesan,
			CHUNK_MESSAGE_SIZE,
			kirim->berkas_identifikasi,
			nama_berkas,
			kirim->ukuran_berkas
			), CHUNK_MESSAGE_SIZE);
	// Apakah hampir akhir.
	}else if(identifikasi==MAX_CHUNK_ID){
		// Panji.
		DEBUG1(_("Mengirim panji '%1$s'."),_("Henti"));
		panji=STOP_FLAG;
	/*
	}else if (kirim->ukuran_kirim>kirim->ukuran_berkas){
		// Panji STOP.
		DEBUG1(_("Mengirim panji '%1$s'."), _("Henti"));
		panji=STOP_FLAG;
		
		// Hentikan perulangan.
		// Keluar dari perulangan.
		DEBUG1(_("Menghentikan pengulangan pengiriman."), 0);
		kirim->do_kirim=false;
		*/
	}else{
		// Panji.
		panji=INTRANSFER_FLAG;
		
		// Mendapatkan posisi berkas.
		long int penunjuk_berkas=0
			+((long)(kelompok_kirim-1)*(MAX_CHUNK_ID-1)*CHUNK_MESSAGE_SIZE)
			+((long)identifikasi-1)*(long)CHUNK_MESSAGE_SIZE;
		
		// Bila mendekati dan pecahan transfer terakhir,
		// maka penunjuk merupakan
		// panjang berkas dikurangi CHUNK_MESSAGE_SIZE.
		// Aktifkan dengan aturan.shifteof=true.
		int panjang_geser_akhir=0;
		size_t panjang_baca=CHUNK_MESSAGE_SIZE;
		if (
			aturan.shifteof
			&& kirim->ukuran_kirim + (double)CHUNK_MESSAGE_SIZE
				>= kirim->ukuran_berkas
			&& kirim->ukuran_berkas - kirim->ukuran_kirim
				<= (double)CHUNK_MESSAGE_SIZE
		){
			// Pesan.
			DEBUG3(_("Merupakan pecahan akhir."), 0);
			
			// Jumlah geser.
			panjang_geser_akhir=(int)0
				+((double)CHUNK_MESSAGE_SIZE
				-(kirim->ukuran_berkas-kirim->ukuran_kirim));
			
			// Mengubah penunjuk berkas.
			penunjuk_berkas=kirim->ukuran_berkas-CHUNK_MESSAGE_SIZE;
			
			// Panjang baca.
			panjang_baca=CHUNK_MESSAGE_SIZE;
		}else{
			
			// Jumlah geser.
			panjang_geser_akhir=0;
			
			// Panjang baca.
			panjang_baca=CHUNK_MESSAGE_SIZE;
		};
		
		// Menggeser penunjuk berkas.
		status=fseek(pberkas, penunjuk_berkas, SEEK_SET);
		
		// Memeriksa posisi.
		if(status<0){
			FAIL(
			_("Gagal memindah posisi penunjuk berkas '%1$s': %2$s (%3$i)."),
				nama_berkas, strerror(errno), errno
			);
			exit(EXIT_FAILURE_IO);
		}else{
			long posisi_sekarang=ftell(pberkas);
			if(posisi_sekarang<0){
				FAIL(
			_("Gagal mendapatkan posisi penunjuk berkas '%1$s': %2$s (%3$i)."),
					nama_berkas, strerror(errno), errno
				);
				exit(EXIT_FAILURE_IO);
			}else if(posisi_sekarang!=penunjuk_berkas){
				FAIL(
_("Posisi penunjuk berkas '%1$s' (%2$li) tidak sesuai. Diharapkan: %2$li."),
					nama_berkas, posisi_sekarang, errno
				);
				exit(EXIT_FAILURE_IO);
			}else{
				// Berhasil.
				if(kelompok_kirim>1){
					DEBUG3(
_("Mulai membaca di bita %1$i sebesar %2$lu bita untuk pesan %3$i kelompok %4$i."),
						penunjuk_berkas,
						(long unsigned int) panjang_baca,
						identifikasi, kelompok_kirim
					);
				}else{
					DEBUG3(
		_("Mulai membaca di bita %1$i sebesar %2$lu bita untuk pesan %3$i."),
						penunjuk_berkas,
						(long unsigned int) panjang_baca, identifikasi
					);
				};
			};
		};
		
		// Baca berkas untuk pesan.
		panjang_pesan=fread(pesan, 1, CHUNK_MESSAGE_SIZE, pberkas);
		
		// Menambah bita terkirim.
		if(identifikasi_awal ||
			identifikasi!=identifikasi_sebelumnya){
			// Menambah.
			identifikasi_awal=false;
			// kirim->ukuran_kirim+=(double)panjang_pesan;
			identifikasi_sebelumnya=identifikasi;
			kirim->identifikasi_sebelumnya=identifikasi;
		};
		
		// Menggeser.
		if(
			panjang_geser_akhir>0
			&& panjang_geser_akhir <= CHUNK_MESSAGE_SIZE
		){
			// Membuat sementara.
			char pesan_tmp[CHUNK_MESSAGE_SIZE+1];
			memset(pesan_tmp, 0, CHUNK_MESSAGE_SIZE+1);
			
			// Mengeser.
			panjang_pesan=CHUNK_MESSAGE_SIZE-panjang_geser_akhir;
			memmove(pesan_tmp+0, pesan+panjang_geser_akhir, panjang_pesan);
			
			// Mengembalikan.
			memset(pesan, 0, CHUNK_MESSAGE_SIZE);
			memcpy(pesan, pesan_tmp, panjang_pesan);
			
			// Membersihkan.
			memset(pesan_tmp, 0, CHUNK_MESSAGE_SIZE+1);
			
			// Pesan.
			DEBUG3(
				_("Menggeser pesan sebanyak %1$i bita."),
				panjang_geser_akhir
			);
			DEBUG3(
				_("Mulai dibaca di bita %1$i sebesar %2$lu bita"),
				penunjuk_berkas+panjang_geser_akhir, panjang_pesan
			);
		};
		
		// Bila telah selesai.
		// Kecuali bila aturan.transferedcheck=true
		// maka penghentian melihat bita terterima Peladen
		// bukan bila berkas kosong. Berguna bila merupakan
		// sambungan paralel sehingga saat pecahan melebihi ukuran,
		// tidak langsung menghentikan.
		if (
			(!panjang_pesan
			&& !aturan.transferedcheck)
			||
			(!panjang_pesan
			&& (
				kirim->ukuran_kirim
				> kirim->ukuran_berkas+(CHUNK_MESSAGE_SIZE*10)
				)
			)
		){
			DEBUG3(_("Panjang pesan akhir adalah %1$i bita"), panjang_pesan);
			if(feof(pberkas)!=0){
				// Selesai kirim.
				char penyangga_feof[ukuberkas_panjang];
				INFO(
_("Berkas '%1$s' dengan ukuran %2$s (%3$.0lf bita) telah selesai dikirim."),
					nama_berkas,
					readable_fs(kirim->ukuran_berkas, penyangga_feof),
					kirim->ukuran_berkas
					);
				memset(penyangga_feof, 0, ukuberkas_panjang);
				clearerr(pberkas);
			}else if(ferror(pberkas)!=0){
				// Kesalahan.
				FAIL(
					_("Gagal membaca berkas '%1$s': %2$s (%3$i)."),
					nama_berkas, strerror(errno), errno
				);
				clearerr(pberkas);
				exit(EXIT_FAILURE_IO);
			}else{
				// Kesalahan.
				WARN(
					_("Kesalahan berkas yang tidak diketahui: %1$s (%2$i)."),
					strerror(errno), errno
				);
			};
			
			
			// Pesan.
			DEBUG1(_("Mengirim panji '%1$s'."),_("Henti"));
			panji=STOP_FLAG;
			
			// Mengirim panji STOP
			// dan keluar dari perulangan.
			DEBUG1(_("Menghentikan pengulangan pengiriman."), 0);
			kirim->do_kirim=false;
		}else{
			// Pesan.
			DEBUG3(_("Panjang pesan adalah %1$i bita"), panjang_pesan);
		};
	};
	
	// Bangun pesan.
	memcpy(pecahan, buat_pesan(
		pecahan,
		identifikasi,
		&paritas,
		pesan
	), MAX_CHUNK_SIZE);
	
	// Bangun pengepala.
	DEBUG2(_("Panji %1$s."), arti_panji(panji));
	memcpy(pecahan, buat_pengepala(
		pecahan,
		identifikasi,
		panji,
		paritas,
		status_gerbang,
		status_peladen
	), MAX_CHUNK_SIZE);
	
	// Pesan.
	if(kelompok_kirim>1){
		DEBUG1(
			_("Mengirim pesan %1$i kelompok %2$i."),
			identifikasi, kelompok_kirim);
	}else{
		DEBUG1(
			_("Mengirim pesan %1$i."),
			identifikasi);
	};
	
	// ============= Enkripsi  =======
	int panjang_pecahan;
	// Enkripsi.
	if(!aturan.rawtransfer){
	
		// Pesan mentah.
		DEBUG5(_("Pesan mentah dikirim"), pecahan, 0, MAX_CHUNK_SIZE);
		
		// Penyandian.
		unsigned char pesan_ency[MAX_CHUNK_SIZE+1];
		memcpy(pesan_ency, pecahan, MAX_CHUNK_SIZE);
		unsigned char tujuan_ency[ENCRYPTED_CONTAINER_SIZE+1];
		panjang_pecahan=rsa_encrypt(
			pesan_ency,
			MAX_CHUNK_SIZE+1,
			tujuan_ency,
			rsapub,
			aturan.rsa_padding
		);
		
		// Bersihkan.
		memset(pesan_ency, 0, MAX_CHUNK_SIZE);
		
		// Pesan mentah.
		DEBUG5(
			_("Pesan mentah dikirim tersandikan"),
			tujuan_ency, 0, MAX_CHUNK_SIZE
		);
		
		// Salin.
		memcpy(pecahan, tujuan_ency, panjang_pecahan);
	}else{
		panjang_pecahan=MAX_CHUNK_SIZE;
	};
	// ============ /Enkripsi  =======
	
	// Kirim.
	int panjang_diterima;
	char *kirim_data=kirimdata(
		pecahan,
		panjang_pecahan,
		hostname,
		portno,
		infoalamat,
		&panjang_diterima
	);
	
	// Bila kosong.
	if(kirim_data == NULL){
		// Pesan kesalahan.
		DEBUG1(_("Kegagalan %1$s."), _("Soket"));
		
		// Keluar.
		exit(EXIT_FAILURE_SOCKET);
	};
	
	// Menyalin isi.
	memcpy(pecahan, kirim_data, ENCRYPTED_CONTAINER_SIZE);
	
	// Pesan mentah.
	DEBUG4(_("Panjang pesan mentah diterima: %1$i"), panjang_pecahan);
	DEBUG5(_("Pesan mentah diterima"), pecahan, 0, panjang_pecahan);
	
	// ============= Dekripsi  =======
	
	if(!aturan.rawtransfer){
		// Pemecah sandi.
		unsigned char pesan_deco[ENCRYPTED_CONTAINER_SIZE+1];
		memcpy(pesan_deco, pecahan, ENCRYPTED_CONTAINER_SIZE);
		unsigned char tujuan_deco[MAX_CHUNK_SIZE+1];
		panjang_pecahan=rsa_decrypt(
			pesan_deco,
			panjang_diterima,
			tujuan_deco,
			rsapriv,
			aturan.rsa_padding
		);
		
		// Periksa.
		// print_unsigned_array(tujuan_deco, 100);
		
		// Bersihkan.
		memset(pesan_deco, 0, MAX_CHUNK_SIZE);
		
		// Pesan mentah.
		DEBUG4(
			_("Panjang pesan mentah diterima terpecahkan: %1$i"),
			panjang_pecahan
		);
		DEBUG5(
			_("Pesan mentah diterima terpecahkan"),
			tujuan_deco, 0, panjang_pecahan
		);
		
		// Salin.
		memcpy(pecahan, tujuan_deco, MAX_CHUNK_SIZE);
		
	};
	// ============ /Dekripsi  =======
	
	// Mendapatkan pesan.
	DEBUG4(_("Membersihkan penampung pesan."), 0);
	memset(pesan, 0, CHUNK_MESSAGE_SIZE);
	
	DEBUG4(_("Menyalin pesan."), 0);
	memcpy(pesan, ambil_pesan(pecahan), CHUNK_MESSAGE_SIZE);
	DEBUG4(_("Selesai menyalin pesan."), 0);
	
	// Periksa.
	// print_unsigned_array(tujuan_deco, 100);
	
	// Mendapatkan pengepala.
	// Respons.
	int r_versi;
	int r_panji;
	int r_paritas;
	int r_status_gerbang;
	int r_status_peladen;
	unsigned int r_identifikasi;
	DEBUG4(_("Mendapatkan pengepala."), 0);
	ambil_pengepala(
		pecahan,
		&r_versi,
		&r_identifikasi,
		&r_panji,
		&r_paritas,
		&r_status_gerbang,
		&r_status_peladen
		);
	DEBUG4(_("Selesai mendapatkan pengepala."), 0);
	
	// Mendapatkan informasi peladen.
	char* r_berkas_id;
	char* berkas_ukuran_str;
	char* berkas_diterima_str;
	char* unix_time_str;
	
	// Alikasi memori.
	r_berkas_id=malloc(
		sizeof(r_berkas_id)* (CHUNK_MESSAGE_SIZE/2));
	berkas_ukuran_str=malloc(
		sizeof(berkas_ukuran_str)* (CHUNK_MESSAGE_SIZE/2));
	berkas_diterima_str=malloc(
		sizeof(berkas_diterima_str)* (CHUNK_MESSAGE_SIZE/2));
	unix_time_str=malloc(
		sizeof(unix_time_str)* (CHUNK_MESSAGE_SIZE/2));
	
	// Membersihkan isi.
	memset(r_berkas_id, 0,
		sizeof(r_berkas_id)* (CHUNK_MESSAGE_SIZE/2));
	memset(berkas_ukuran_str, 0,
		sizeof(berkas_ukuran_str)* (CHUNK_MESSAGE_SIZE/2));
	memset(berkas_diterima_str, 0,
		sizeof(berkas_diterima_str)* (CHUNK_MESSAGE_SIZE/2));
	memset(unix_time_str, 0,
		sizeof(unix_time_str)* (CHUNK_MESSAGE_SIZE/2));
	
	// Ambil informasi.
	DEBUG4(_("Mendapatkan informasi peladen."), 0);
	DEBUG5(_("Pesan"), pesan, 0, CHUNK_MESSAGE_SIZE);
	status=ambil_pesan_peladen(
		pesan,
		CHUNK_MESSAGE_SIZE,
		&r_berkas_id,
		&berkas_ukuran_str,
		&berkas_diterima_str,
		&unix_time_str
	);
	DEBUG4(_("Selesai mendapatkan informasi peladen."), 0);
	
	// Ubah nilai.
	double r_berkas_ukuran=0;
	double r_berkas_diterima=0;
	double r_unixtime=0;
	
	if(status>0){
		// Tidak menerima.
		DEBUG1(
			_("Tidak memahami Peladen di pecahan %1$i (Status %2$i)."),
			r_identifikasi, status
		);
	}else{
		// Ubah nilai.
		r_berkas_ukuran=strtod(berkas_ukuran_str, NULL);
		r_berkas_diterima=strtod(berkas_diterima_str, NULL);
		r_unixtime=strtod(unix_time_str, NULL);
	};
	
	// Balasan
	DEBUG2(_("Balasan: Versi: %1$i."), r_versi);
	DEBUG2(_("Balasan: Identifikasi: %1$i."), r_identifikasi);
	DEBUG2(_("Balasan: Panji: %1$s."), arti_panji(r_panji));
	DEBUG2(_("Balasan: Paritas: %1$i."), r_paritas);
	DEBUG2(_("Balasan: Status Gerbang: %1$s."), arti_status(r_status_gerbang));
	DEBUG2(_("Balasan: Status Peladen: %1$s."), arti_status(r_status_peladen));
	DEBUG2(_("Balasan: Identifikasi berkas: %1$s."), r_berkas_id);
	DEBUG2(_("Balasan: Ukuran berkas: %1$.0f bita."), r_berkas_ukuran);
	DEBUG2(_("Balasan: Berkas diterima: %1$.0f bita."), r_berkas_diterima)
	DEBUG2(_("Balasan: Waktu Peladen: %1$.06f."), r_unixtime);
	DEBUG1(
		_("Perbedaan waktu Peladen: %1$.06f detik."),
		infokancil.unixtime-r_unixtime
	);
	
	// Menyimpan.
	if(r_berkas_diterima<=0){
		DEBUG2(
			_("Berkas terterima berukuran %1$.0f bita."), r_berkas_diterima
			);
	}else{
		kirim->ukuran_kirim=r_berkas_diterima;
	};
	
	// Bila berkas yang diterima
	// telah sama atau lebih besar dari ukuran.
	if(
		aturan.transferedcheck
		&& r_berkas_diterima>=kirim->ukuran_berkas
	){
		// Pesan.
		if(
			(r_berkas_diterima-kirim->ukuran_berkas)
			> (double)CHUNK_MESSAGE_SIZE * (aturan.parallel)
		){
			WARN(
				_("Peladen telah menerima berkas melebihi %1$.0f bita."),
				r_berkas_diterima-kirim->ukuran_berkas
			);
		}else if(r_berkas_diterima>kirim->ukuran_berkas){
			DEBUG1(
				_("Peladen telah menerima berkas melebihi %1$.0f bita."),
				r_berkas_diterima-kirim->ukuran_berkas
			);
		}else{
			DEBUG1(_("Peladen telah menerima keseluruhan berkas."), 0);
		};
		
		// Ubah nilai.
		kirim->ukuran_kirim=r_berkas_diterima;
		kirim->paksa_panji=STOP_FLAG;
		
		// Keluar.
		return identifikasi;
	};
	
	
	// Memeriksa hasil.
	// Bila status gerbang atau peladen adalah NOL.
	if(!r_status_gerbang || !r_status_peladen){
		
		// Memeriksa apakah
		// telah terlalu banyak melakukan percobaan.
		if(kirim->coba>maksimal_coba){
			FAIL(
				_("Telah melakukan percobaan sebanyak %1$i kali. Berhenti."),
				maksimal_coba
			);
			exit(EXIT_FAILURE);
		}else if(!r_status_gerbang && !r_status_peladen){
			WARN(
				_("Gagal mengirim ke %1$s dan %2$s."),
				_("Gerbang"),_("Peladen")
			);
		}else if(!r_status_peladen){
			WARN(_("Gagal mengirim ke %1$s."),_("Peladen"));
		}else{
			WARN(_("Gagal mengirim ke %1$s."),_("Gerbang"));
		};
		
		// Panji Taksah.
		if(r_panji==INVALID_FLAG){
			// Pesan.
			NOTICE(_("Panji Taksah ditemukan."), 0);
			NOTICE(
				_("Menunggu %1$i detik untuk mengirim ulang."),
				ulang_tunggu
			);
			sleep(ulang_tunggu);
		}else if(r_panji==START_FLAG){
			// Mengunlang pengiriman
			// informasi berkas.
			int tunggu=ulang_tunggu;
			NOTICE(_("Meminta pengiriman ulang informasi berkas."), 0);
			NOTICE(_("Menunggu %1$i detik untuk mengirim ulang."), tunggu);
			sleep(tunggu);
			
			// Mengatur ulang ukuran berkas terkirim.
			kirim->ukuran_kirim=0;
		}else if(r_panji==INTRANSFER_FLAG){
			// Meminta pengiriman ulang
			// berkas berdasarkan identifikasi.
			NOTICE(
				_("Meminta pengiriman ulang pecahan identifikasi '%1$i'."),
				r_identifikasi
			);
			
			// Mengatur ulang ukuran berkas terkirim
			// sesuai dengan ukuran peladen.
			kirim->ukuran_kirim=r_berkas_diterima;
		};
		
		// Mengirim ulang.
		NOTICE(
			_("Percobaan ke-%1$i. Mengulangi pengiriman pecahan %2$i."),
			kirim->coba, r_identifikasi
		);
		identifikasi=r_identifikasi;
		
		// Menambah
		// percobaan pengiriman.
		kirim->coba++;
	}else{
		
		/*
		// Bila ukuran terterima Peladen
		// lebih besar dari pada terketahui Klien.
		if(r_berkas_diterima> kirim->ukuran_kirim){
			// Pesan.
			DEBUG2(
_("Peladen telah menerima berkas melebihi %1$.0f bita dari yang terkirim."),
				r_berkas_diterima-(kirim->ukuran_berkas)
			);
			
			// Ubah isi.
			kirim->ukuran_kirim=r_berkas_diterima;
		};
		*/
		
		// Berhasil.
		DEBUG2(_("Berhasil mengirim ke Gerbang dan Peladen."), 0);
		
		// Menambahkan.
		identifikasi++;
		DEBUG2(_("Menambah identifikasi menjadi %1$i."), identifikasi);
		
		// Bila belum selesai.
		if(kirim->ukuran_kirim<=kirim->ukuran_berkas){
			
			// Bila lebih dari spesifikasi,
			// mengulangi dari NOL.
			if(identifikasi>MAX_CHUNK_ID){
				// Pesan.
				WARN(
					_("Telah melebihi maksimal identifikasi %1$i."),
					MAX_CHUNK_ID
				);
				DEBUG1(_("Nilai identifikasi adalah %1$i."), identifikasi);
				
				// Perkembangan.
				tampil_info_progres_berkas(
					PROGRES_KIRIM, kirim->berkas,
					kirim->ukuran_kirim, kirim->ukuran_berkas,
					ukuberkas_panjang
				);
				
				// Menambah kelompok.
				kelompok_kirim++;
				kirim->kelompok_kirim=kelompok_kirim;
				
				// Pesan.
				DEBUG1(
					_("Menunggu %1$i detik untuk melanjutkan."),
					urut_tunggu
				);
				DEBUG1(
					_("Kelompok pecahan selanjutnya adalah '%1$i'."),
					kelompok_kirim
				);
				
				// Tunggu.
				sleep(urut_tunggu);
				
				// Mengulangi identifikasi.
				identifikasi=0;
			};
		}else{
			// DEBUG1(_("Menghentikan pengulangan pengiriman."), 0);
			// kirim->do_kirim=false;
		};
		kirim->coba=1;
	};
	
	/*
	// Bila lebih dari maksimal kali kirim,
	// menunggu sebanyak waktu untuk mengirim ulang.
	if(kirim->urut_kali>=urut_maksimal && !urut_jangan_tunggu){
		// Pesan.
		WARN(
			_("Telah mengirim berurutan sebanyak %1$i kali."),
			kirim->urut_kali
		);
		
		// Perkembangan.
		tampil_info_progres_berkas(
			PROGRES_KIRIM, kirim->berkas,
			kirim->ukuran_kirim, kirim->ukuran_berkas,
			ukuberkas_panjang
		);
		
		// Pesan.
		NOTICE(_("Menunggu %1$i detik untuk mengirim ulang."), urut_tunggu);
		sleep(urut_tunggu);
		kirim->urut_kali=0;
	};
	*/
	
	// Memastikan nilai kelompok benar.
	kirim->kelompok_kirim=kelompok_kirim;
	
	// Mengembalikan nilai identifikasi.
	return identifikasi;
			// kirim->identifikasi=identifikasi;
	
	// Mengembalikan data.
	// kirim->berkas=berkas;
	
	// if(identifikasi>3)
		// kirim->do_kirim=false;
}
Example #15
0
GLOBAL void UMF_assemble
#else
GLOBAL void UMF_assemble_fixq
#endif
(
    NumericType *Numeric,
    WorkType *Work
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Int e, i, row, col, i2, nrows, ncols, f, tpi, extcdeg, extrdeg, rdeg0,
	cdeg0, son_list, next, nrows_to_assemble,
	ncols_to_assemble, ngetrows, j, j2,
	nrowsleft,	/* number of rows remaining in S */
	ncolsleft,	/* number of columns remaining in S */
	prior_Lson, prior_Uson, *E, *Cols, *Rows, *Wm, *Woo,
	*Row_tuples, *Row_degree, *Row_tlen,
	*Col_tuples, *Col_tlen ;
    Unit *Memory, *p ;
    Element *ep ;
    Tuple *tp, *tp1, *tp2, *tpend ;
    Entry
	*S,		/* a pointer into the contribution block of a son */
	*Fcblock,	/* current contribution block */
	*Fcol ;		/* a column of FC */
    Int *Frpos,
	*Fcpos,
	fnrows,		/* number of rows in contribution block in F */
	fncols ;	/* number of columns in contribution block in F */

#if !defined (FIXQ) || !defined (NDEBUG)
    Int *Col_degree ;
#endif

#ifndef NDEBUG
    Int n_row, n_col ;
    n_row = Work->n_row ;
    n_col = Work->n_col ;
    DEBUG3 (("::Assemble SCANS 1-4\n")) ;
    UMF_dump_current_front (Numeric, Work, TRUE) ;
#endif

#if !defined (FIXQ) || !defined (NDEBUG)
    Col_degree = Numeric->Cperm ;   /* not updated if FIXQ is true */
#endif

    /* ---------------------------------------------------------------------- */
    /* get parameters */
    /* ---------------------------------------------------------------------- */

    fncols = Work->fncols ;
    fnrows = Work->fnrows ;
    Fcpos = Work->Fcpos ;
    Frpos = Work->Frpos ;
    Row_degree = Numeric->Rperm ;
    Row_tuples = Numeric->Uip ;
    Row_tlen   = Numeric->Uilen ;
    Col_tuples = Numeric->Lip ;
    Col_tlen   = Numeric->Lilen ;
    E = Work->E ;
    Memory = Numeric->Memory ;
    Wm = Work->Wm ;
    Woo = Work->Woo ;
    rdeg0 = Work->rdeg0 ;
    cdeg0 = Work->cdeg0 ;

#ifndef NDEBUG
    DEBUG6 (("============================================\n")) ;
    DEBUG6 (("Degree update, assembly.\n")) ;
    DEBUG6 (("pivot row pattern:  fncols="ID"\n", fncols)) ;
    for (j = 0 ; j < fncols ; j++)
    {
	col = Work->Fcols [j] ;
	DEBUG6 ((ID" ", col)) ;
	ASSERT (Fcpos [col] == j * Work->fnr_curr) ;
	ASSERT (NON_PIVOTAL_COL (col)) ;
    }
    ASSERT (Fcpos [Work->pivcol] >= 0) ;
    DEBUG6 (("pivcol: "ID" pos "ID" fnr_curr "ID" fncols "ID"\n",
	Work->pivcol, Fcpos [Work->pivcol], Work->fnr_curr, fncols)) ;
    ASSERT (Fcpos [Work->pivcol] <  fncols * Work->fnr_curr) ;
    DEBUG6 (("\npivot col pattern:  fnrows="ID"\n", fnrows)) ;
    for (i = 0 ; i < fnrows ; i++)
    {
	row = Work->Frows [i] ;
	DEBUG6 ((ID" ", row)) ;
	ASSERT (Frpos [row] == i) ;
	ASSERT (NON_PIVOTAL_ROW (row)) ;
    }
    DEBUG6 (("\n")) ;
    ASSERT (Frpos [Work->pivrow] >= 0) ;
    ASSERT (Frpos [Work->pivrow] < fnrows) ;
    ASSERT (Work->Flublock == (Entry *) (Numeric->Memory + E [0])) ;
    ASSERT (Work->Fcblock == Work->Flublock + Work->nb *
	(Work->nb + Work->fnr_curr + Work->fnc_curr)) ;
#endif

    Fcblock = Work->Fcblock ;

    /* ---------------------------------------------------------------------- */
    /* determine the largest actual frontal matrix size (for Info only) */
    /* ---------------------------------------------------------------------- */

    ASSERT (fnrows == Work->fnrows_new + 1) ;
    ASSERT (fncols == Work->fncols_new + 1) ;

    Numeric->maxnrows = MAX (Numeric->maxnrows, fnrows) ;
    Numeric->maxncols = MAX (Numeric->maxncols, fncols) ;

    /* this is safe from integer overflow, since the current frontal matrix
     * is already allocated. */
    Numeric->maxfrsize = MAX (Numeric->maxfrsize, fnrows * fncols) ;

    /* ---------------------------------------------------------------------- */
    /* assemble from prior elements into the current frontal matrix */
    /* ---------------------------------------------------------------------- */

    DEBUG2 (("New assemble start [prior_element:"ID"\n", Work->prior_element)) ;

    /* Currently no rows or columns are marked.  No elements are scanned, */
    /* that is, (ep->next == EMPTY) is true for all elements */

    son_list = 0 ;	/* start creating son_list [ */

    /* ---------------------------------------------------------------------- */
    /* determine if most recent element is Lson or Uson of current front */
    /* ---------------------------------------------------------------------- */

    if (!Work->do_extend)
    {
	prior_Uson = ( Work->pivcol_in_front && !Work->pivrow_in_front) ;
	prior_Lson = (!Work->pivcol_in_front &&  Work->pivrow_in_front) ;
	if (prior_Uson || prior_Lson)
	{
	    e = Work->prior_element ;
	    if (e != EMPTY)
	    {
		ASSERT (E [e]) ;
		p = Memory + E [e] ;
		ep = (Element *) p ;
		ep->next = son_list ;
		son_list = e ;
#ifndef NDEBUG
		DEBUG2 (("e "ID" is Prior son "ID" "ID"\n",
		    e, prior_Uson, prior_Lson)) ;
		UMF_dump_element (Numeric, Work, e, FALSE) ;
#endif
		ASSERT (E [e]) ;
	    }
	}
    }
    Work->prior_element = EMPTY ;

    /* ---------------------------------------------------------------------- */
    /* SCAN1-row:  scan the element lists of each new row in the pivot col */
    /* and compute the external column degree for each frontal */
    /* ---------------------------------------------------------------------- */

    for (i2 = Work->fscan_row ; i2 < fnrows ; i2++)
    {
	/* Get a row */
	row = Work->NewRows [i2] ;
	if (row < 0) row = FLIP (row) ;
	ASSERT (row >= 0 && row < n_row) ;

	DEBUG6 (("SCAN1-row: "ID"\n", row)) ;
#ifndef NDEBUG
	UMF_dump_rowcol (0, Numeric, Work, row, FALSE) ;
#endif

	ASSERT (NON_PIVOTAL_ROW (row)) ;
	tpi = Row_tuples [row] ;
	if (!tpi) continue ;
	tp = (Tuple *) (Memory + tpi) ;
	tp1 = tp ;
	tp2 = tp ;
	tpend = tp + Row_tlen [row] ;
	for ( ; tp < tpend ; tp++)
	{
	    e = tp->e ;
	    ASSERT (e > 0 && e <= Work->nel) ;
	    if (!E [e]) continue ;	/* element already deallocated */
	    f = tp->f ;
	    p = Memory + E [e] ;
	    ep = (Element *) p ;
	    p += UNITS (Element, 1) ;
	    Rows = ((Int *) p) + ep->ncols ;
	    if (Rows [f] == EMPTY) continue ;	/* row already assembled */
	    ASSERT (row == Rows [f]) ;

	    if (ep->cdeg < cdeg0)
	    {
		/* first time seen in scan1-row */
		ep->cdeg = ep->nrowsleft + cdeg0 ;
		DEBUG6 (("e "ID" First seen: cdeg: "ID" ", e, ep->cdeg-cdeg0)) ;
		ASSERT (ep->ncolsleft > 0 && ep->nrowsleft > 0) ;
	    }

	    ep->cdeg-- ;	/* decrement external column degree */
	    DEBUG6 (("e "ID" New ext col deg: "ID"\n", e, ep->cdeg - cdeg0)) ;

	    /* this element is not yet in the new son list */
	    if (ep->cdeg == cdeg0 && ep->next == EMPTY)
	    {
		/* A new LUson or Uson has been found */
		ep->next = son_list ;
		son_list = e ;
	    }

	    ASSERT (ep->cdeg >= cdeg0) ;
	    *tp2++ = *tp ;	/* leave the tuple in the list */
	}
	Row_tlen [row] = tp2 - tp1 ;
    }

    /* ---------------------------------------------------------------------- */
    /* SCAN1-col:  scan the element lists of each new col in the pivot row */
    /*	 and compute the external row degree for each frontal */
    /* ---------------------------------------------------------------------- */

    for (j2 = Work->fscan_col ; j2 < fncols ; j2++)
    {
	/* Get a column */
	col = Work->NewCols [j2] ;
	if (col < 0) col = FLIP (col) ;
	ASSERT (col >= 0 && col < n_col) ;

	DEBUG6 (("SCAN 1-col: "ID"\n", col)) ;
#ifndef NDEBUG
	UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ;
#endif

	ASSERT (NON_PIVOTAL_COL (col)) ;
	tpi = Col_tuples [col] ;
	if (!tpi) continue ;
	tp = (Tuple *) (Memory + tpi) ;
	tp1 = tp ;
	tp2 = tp ;
	tpend = tp + Col_tlen [col] ;
	for ( ; tp < tpend ; tp++)
	{
	    e = tp->e ;
	    ASSERT (e > 0 && e <= Work->nel) ;
	    if (!E [e]) continue ;	/* element already deallocated */
	    f = tp->f ;
	    p = Memory + E [e] ;
	    ep = (Element *) p ;
	    p += UNITS (Element, 1) ;
	    Cols = (Int *) p ;
	    if (Cols [f] == EMPTY) continue ;	/* column already assembled */
	    ASSERT (col == Cols [f]) ;

	    if (ep->rdeg < rdeg0)
	    {
		/* first time seen in scan1-col */
		ep->rdeg = ep->ncolsleft + rdeg0 ;
		DEBUG6 (("e "ID" First seen: rdeg: "ID" ", e, ep->rdeg-rdeg0)) ;
		ASSERT (ep->ncolsleft > 0 && ep->nrowsleft > 0) ;
	    }

	    ep->rdeg-- ;	/* decrement external row degree */
	    DEBUG6 (("e "ID" New ext row degree: "ID"\n", e, ep->rdeg-rdeg0)) ;

	    if (ep->rdeg == rdeg0 && ep->next == EMPTY)
	    {
		/* A new LUson or Lson has been found */
		ep->next = son_list ;
		son_list = e ;
	    }

	    ASSERT (ep->rdeg >= rdeg0) ;
	    *tp2++ = *tp ;	/* leave the tuple in the list */
	}
	Col_tlen [col] = tp2 - tp1 ;
    }

    /* ---------------------------------------------------------------------- */
    /* assemble new sons via full scans */
    /* ---------------------------------------------------------------------- */

    next = EMPTY ;

    for (e = son_list ; e > 0 ; e = next)
    {
	ASSERT (e > 0 && e <= Work->nel && E [e]) ;
	p = Memory + E [e] ;
	DEBUG2 (("New son: "ID"\n", e)) ;
#ifndef NDEBUG
	UMF_dump_element (Numeric, Work, e, FALSE) ;
#endif
	GET_ELEMENT (ep, p, Cols, Rows, ncols, nrows, S) ;
	nrowsleft = ep->nrowsleft ;
	ncolsleft = ep->ncolsleft ;
	next = ep->next ;
	ep->next = EMPTY ;

	extrdeg = (ep->rdeg < rdeg0) ? ncolsleft : (ep->rdeg - rdeg0) ;
	extcdeg = (ep->cdeg < cdeg0) ? nrowsleft : (ep->cdeg - cdeg0) ;
	ncols_to_assemble = ncolsleft - extrdeg ;
	nrows_to_assemble = nrowsleft - extcdeg ;
	DEBUG2 (("extrdeg "ID" extcdeg "ID"\n", extrdeg, extcdeg)) ;

	if (extrdeg == 0 && extcdeg == 0)
	{

	    /* -------------------------------------------------------------- */
	    /* this is an LUson - assemble an entire contribution block */
	    /* -------------------------------------------------------------- */

	    DEBUG6 (("LUson found: "ID"\n", e)) ;

	    if (nrows == nrowsleft)
	    {
		/* ---------------------------------------------------------- */
		/* no rows assembled out of this LUson yet */
		/* ---------------------------------------------------------- */

		/* compute the compressed column offset vector*/
		/* [ use Wm [0..nrows-1] for offsets */
#pragma ivdep
		for (i = 0 ; i < nrows ; i++)
		{
		    row = Rows [i] ;
		    Row_degree [row] -= ncolsleft ;
		    Wm [i] = Frpos [row] ;
		}

		if (ncols == ncolsleft)
		{
		    /* ------------------------------------------------------ */
		    /* no rows or cols assembled out of LUson yet */
		    /* ------------------------------------------------------ */

		    for (j = 0 ; j < ncols ; j++)
		    {
			col = Cols [j] ;
#ifndef FIXQ
			Col_degree [col] -= nrowsleft ;
#endif
			Fcol = Fcblock + Fcpos [col] ;
#pragma ivdep
			for (i = 0 ; i < nrows ; i++)
			{
			    /* Fcol [Wm [i]] += S [i] ; */
			    ASSEMBLE (Fcol [Wm [i]], S [i]) ;
			}
			S += nrows ;
		    }


		}
		else
		{
		    /* ------------------------------------------------------ */
		    /* only cols have been assembled out of LUson */
		    /* ------------------------------------------------------ */

		    for (j = 0 ; j < ncols ; j++)
		    {
			col = Cols [j] ;
			if (col >= 0)
			{
#ifndef FIXQ
			    Col_degree [col] -= nrowsleft ;
#endif
			    Fcol = Fcblock + Fcpos [col] ;
#pragma ivdep
			    for (i = 0 ; i < nrows ; i++)
			    {
				/* Fcol [Wm [i]] += S [i] ; */
				ASSEMBLE (Fcol [Wm [i]], S [i]) ;
			    }
			}
			S += nrows ;
		    }

		}
		/* ] done using Wm [0..nrows-1] for offsets */
	    }
	    else
	    {
		/* ---------------------------------------------------------- */
		/* some rows have been assembled out of this LUson */
		/* ---------------------------------------------------------- */

		/* compute the compressed column offset vector*/
		/* [ use Woo,Wm [0..nrowsleft-1] for offsets */
		ngetrows = 0 ;
		for (i = 0 ; i < nrows ; i++)
		{
		    row = Rows [i] ;
		    if (row >= 0)
		    {
			Row_degree [row] -= ncolsleft ;
			Woo [ngetrows] = i ;
			Wm [ngetrows++] = Frpos [row] ;
		    }
		}
		ASSERT (ngetrows == nrowsleft) ;

		if (ncols == ncolsleft)
		{
		    /* ------------------------------------------------------ */
		    /* only rows have been assembled out of this LUson */
		    /* ------------------------------------------------------ */

		    for (j = 0 ; j < ncols ; j++)
		    {
			col = Cols [j] ;
#ifndef FIXQ
			Col_degree [col] -= nrowsleft ;
#endif
			Fcol = Fcblock + Fcpos [col] ;
#pragma ivdep
			for (i = 0 ; i < nrowsleft ; i++)
			{
			    /* Fcol [Wm [i]] += S [Woo [i]] ; */
			    ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
			}
			S += nrows ;
		    }

		}
		else
		{
		    /* ------------------------------------------------------ */
		    /* both rows and columns have been assembled out of LUson */
		    /* ------------------------------------------------------ */

		    for (j = 0 ; j < ncols ; j++)
		    {
			col = Cols [j] ;
			if (col >= 0)
			{
#ifndef FIXQ
			    Col_degree [col] -= nrowsleft ;
#endif
			    Fcol = Fcblock + Fcpos [col] ;
#pragma ivdep
			    for (i = 0 ; i < nrowsleft ; i++)
			    {
				/* Fcol [Wm [i]] += S [Woo [i]] ; */
				ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
			    }
			}
			S += nrows ;
		    }

		}
		/* ] done using Woo,Wm [0..nrowsleft-1] */
	    }

	    /* deallocate the element: remove from ordered list */
	    UMF_mem_free_tail_block (Numeric, E [e]) ;
	    E [e] = 0 ;

	}
	else if (extcdeg == 0)
	{

	    /* -------------------------------------------------------------- */
	    /* this is a Uson - assemble all possible columns */
	    /* -------------------------------------------------------------- */

	    DEBUG6 (("New USON: "ID"\n", e)) ;
	    ASSERT (extrdeg > 0) ;

	    DEBUG6 (("New uson "ID" cols to do "ID"\n", e, ncols_to_assemble)) ;

	    if (ncols_to_assemble > 0)
	    {

		Int skip = FALSE ;
		if (ncols_to_assemble * 16 < ncols && nrows == 1)
		{
		    /* this is a tall and thin frontal matrix consisting of
		     * only one column (most likely an original column). Do
		     * not assemble it.   It cannot be the pivot column, since
		     * the pivot column element would be an LU son, not an Lson,
		     * of the current frontal matrix. */
		    ASSERT (nrowsleft == 1) ;
		    ASSERT (Rows [0] >= 0 && Rows [0] < Work->n_row) ;
		    skip = TRUE ;
		    Work->any_skip = TRUE ;
		}

		if (!skip)
		{

		    if (nrows == nrowsleft)
		    {
			/* -------------------------------------------------- */
			/* no rows have been assembled out of this Uson yet */
			/* -------------------------------------------------- */

			/* compute the compressed column offset vector */
			/* [ use Wm [0..nrows-1] for offsets */
#pragma ivdep
			for (i = 0 ; i < nrows ; i++)
			{
			    row = Rows [i] ;
			    ASSERT (row >= 0 && row < n_row) ;
			    Row_degree [row] -= ncols_to_assemble ;
			    Wm [i] = Frpos [row] ;
			}

			for (j = 0 ; j < ncols ; j++)
			{
			    col = Cols [j] ;
			    if ((col >= 0) && (Fcpos [col] >= 0))
			    {
#ifndef FIXQ
				Col_degree [col] -= nrowsleft ;
#endif
				Fcol = Fcblock + Fcpos [col] ;
#pragma ivdep
				for (i = 0 ; i < nrows ; i++)
				{
				    /* Fcol [Wm [i]] += S [i] ; */
				    ASSEMBLE (Fcol [Wm [i]], S [i]) ;
				}
				/* flag the column as assembled from Uson */
				Cols [j] = EMPTY ;
			    }
			    S += nrows ;
			}


			/* ] done using Wm [0..nrows-1] for offsets */
		    }
		    else
		    {
			/* -------------------------------------------------- */
			/* some rows have been assembled out of this Uson */
			/* -------------------------------------------------- */

			/* compute the compressed column offset vector*/
			/* [ use Woo,Wm [0..nrows-1] for offsets */
			ngetrows = 0 ;
			for (i = 0 ; i < nrows ; i++)
			{
			    row = Rows [i] ;
			    if (row >= 0)
			    {
				Row_degree [row] -= ncols_to_assemble ;
				ASSERT (row < n_row && Frpos [row] >= 0) ;
				Woo [ngetrows] = i ;
				Wm [ngetrows++] = Frpos [row] ;
			    }
			}
			ASSERT (ngetrows == nrowsleft) ;

			for (j = 0 ; j < ncols ; j++)
			{
			    col = Cols [j] ;
			    if ((col >= 0) && (Fcpos [col] >= 0))
			    {
#ifndef FIXQ
				Col_degree [col] -= nrowsleft ;
#endif
				Fcol = Fcblock + Fcpos [col] ;
#pragma ivdep
				for (i = 0 ; i < nrowsleft ; i++)
				{
				    /* Fcol [Wm [i]] += S [Woo [i]] ; */
				    ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
				}
				/* flag the column as assembled from Uson */
				Cols [j] = EMPTY ;
			    }
			    S += nrows ;
			}

			/* ] done using Woo,Wm */
		    }
		    ep->ncolsleft = extrdeg ;
		}
	    }

	}
	else
	{

	    /* -------------------------------------------------------------- */
	    /* this is an Lson - assemble all possible rows */
	    /* -------------------------------------------------------------- */

	    DEBUG6 (("New LSON: "ID"\n", e)) ;
	    ASSERT (extrdeg == 0 && extcdeg > 0) ;

	    DEBUG6 (("New lson "ID" rows to do "ID"\n", e, nrows_to_assemble)) ;

	    if (nrows_to_assemble > 0)
	    {

		Int skip = FALSE ;
		if (nrows_to_assemble * 16 < nrows && ncols == 1)
		{
		    /* this is a tall and thin frontal matrix consisting of
		     * only one column (most likely an original column). Do
		     * not assemble it.   It cannot be the pivot column, since
		     * the pivot column element would be an LU son, not an Lson,
		     * of the current frontal matrix. */
		    ASSERT (ncolsleft == 1) ;
		    ASSERT (Cols [0] >= 0 && Cols [0] < Work->n_col) ;
		    Work->any_skip = TRUE ;
		    skip = TRUE ;
		}

		if (!skip)
		{

		    /* compute the compressed column offset vector */
		    /* [ use Woo,Wm [0..nrows-1] for offsets */
		    ngetrows = 0 ;
		    for (i = 0 ; i < nrows ; i++)
		    {
			row = Rows [i] ;
			if ((row >= 0) && (Frpos [row] >= 0))
			{
			    ASSERT (row < n_row) ;
			    Row_degree [row] -= ncolsleft ;
			    Woo [ngetrows] = i ;
			    Wm [ngetrows++] = Frpos [row] ;
			    /* flag the row as assembled from the Lson */
			    Rows [i] = EMPTY ;
			}
		    }
		    ASSERT (nrowsleft - ngetrows == extcdeg) ;
		    ASSERT (ngetrows == nrows_to_assemble) ;

		    if (ncols == ncolsleft)
		    {
			/* -------------------------------------------------- */
			/* no columns assembled out this Lson yet */
			/* -------------------------------------------------- */

			for (j = 0 ; j < ncols ; j++)
			{
			    col = Cols [j] ;
			    ASSERT (col >= 0 && col < n_col) ;
#ifndef FIXQ
			    Col_degree [col] -= nrows_to_assemble ;
#endif
			    Fcol = Fcblock + Fcpos [col] ;
#pragma ivdep
			    for (i = 0 ; i < nrows_to_assemble ; i++)
			    {
				/* Fcol [Wm [i]] += S [Woo [i]] ; */
				ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
			    }
			    S += nrows ;
			}


		    }
		    else
		    {
			/* -------------------------------------------------- */
			/* some columns have been assembled out of this Lson */
			/* -------------------------------------------------- */

			for (j = 0 ; j < ncols ; j++)
			{
			    col = Cols [j] ;
			    ASSERT (col < n_col) ;
			    if (col >= 0)
			    {
#ifndef FIXQ
				Col_degree [col] -= nrows_to_assemble ;
#endif
				Fcol = Fcblock + Fcpos [col] ;
#pragma ivdep
				for (i = 0 ; i < nrows_to_assemble ; i++)
				{
				    /* Fcol [Wm [i]] += S [Woo [i]] ; */
				    ASSEMBLE (Fcol [Wm [i]], S [Woo [i]]) ;
				}
			    }
			    S += nrows ;
			}

		    }

		    /* ] done using Woo,Wm */

		    ep->nrowsleft = extcdeg ;
		}
	    }
	}
    }

    /* Note that garbage collection, and build tuples */
    /* both destroy the son list. */

    /* ] son_list now empty */

    /* ---------------------------------------------------------------------- */
    /* If frontal matrix extended, assemble old L/Usons from new rows/cols */
    /* ---------------------------------------------------------------------- */

    /* ---------------------------------------------------------------------- */
    /* SCAN2-row:  assemble rows of old Lsons from the new rows */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    DEBUG7 (("Current frontal matrix: (prior to scan2-row)\n")) ;
    UMF_dump_current_front (Numeric, Work, TRUE) ;
#endif

    /* rescan the pivot row */
    if (Work->any_skip)
    {
	row_assemble (Work->pivrow, Numeric, Work) ;
    }

    if (Work->do_scan2row)
    {
	for (i2 = Work->fscan_row ; i2 < fnrows ; i2++)
	{
	    /* Get a row */
	    row = Work->NewRows [i2] ;
	    if (row < 0) row = FLIP (row) ;
	    ASSERT (row >= 0 && row < n_row) ;
	    if (!(row == Work->pivrow && Work->any_skip))
	    {
		/* assemble it */
		row_assemble (row, Numeric, Work) ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* SCAN2-col:  assemble columns of old Usons from the new columns */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    DEBUG7 (("Current frontal matrix: (prior to scan2-col)\n")) ;
    UMF_dump_current_front (Numeric, Work, TRUE) ;
#endif

    /* rescan the pivot col */
    if (Work->any_skip)
    {
	col_assemble (Work->pivcol, Numeric, Work) ;
    }

    if (Work->do_scan2col)
    {

	for (j2 = Work->fscan_col ; j2 < fncols ; j2++)
	{
	    /* Get a column */
	    col = Work->NewCols [j2] ;
	    if (col < 0) col = FLIP (col) ;
	    ASSERT (col >= 0 && col < n_col) ;
	    if (!(col == Work->pivcol && Work->any_skip))
	    {
		/* assemble it */
		col_assemble (col, Numeric, Work) ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */
    /* done.  the remainder of this routine is used only when in debug mode */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG

    /* ---------------------------------------------------------------------- */
    /* when debugging: make sure the assembly did everything that it could */
    /* ---------------------------------------------------------------------- */

    DEBUG3 (("::Assemble done\n")) ;

    for (i2 = 0 ; i2 < fnrows ; i2++)
    {
	/* Get a row */
	row = Work->Frows [i2] ;
	ASSERT (row >= 0 && row < n_row) ;

	DEBUG6 (("DEBUG SCAN 1: "ID"\n", row)) ;
	UMF_dump_rowcol (0, Numeric, Work, row, TRUE) ;

	ASSERT (NON_PIVOTAL_ROW (row)) ;
	tpi = Row_tuples [row] ;
	if (!tpi) continue ;
	tp = (Tuple *) (Memory + tpi) ;
	tpend = tp + Row_tlen [row] ;
	for ( ; tp < tpend ; tp++)
	{
	    e = tp->e ;
	    ASSERT (e > 0 && e <= Work->nel) ;
	    if (!E [e]) continue ;	/* element already deallocated */
	    f = tp->f ;
	    p = Memory + E [e] ;
	    ep = (Element *) p ;
	    p += UNITS (Element, 1) ;
	    Cols = (Int *) p ;
	    Rows = ((Int *) p) + ep->ncols ;
	    if (Rows [f] == EMPTY) continue ;	/* row already assembled */
	    ASSERT (row == Rows [f]) ;
	    extrdeg = (ep->rdeg < rdeg0) ? ep->ncolsleft : (ep->rdeg - rdeg0) ;
	    extcdeg = (ep->cdeg < cdeg0) ? ep->nrowsleft : (ep->cdeg - cdeg0) ;
	    DEBUG6 ((
		"e "ID" After assembly ext row deg: "ID" ext col degree "ID"\n",
		e, extrdeg, extcdeg)) ;

	    if (Work->any_skip)
	    {
		/* no Lsons in any row, except for very tall and thin ones */
		ASSERT (extrdeg >= 0) ;
		if (extrdeg == 0)
		{
		    /* this is an unassemble Lson */
		    ASSERT (ep->ncols == 1) ;
		    ASSERT (ep->ncolsleft == 1) ;
		    col = Cols [0] ;
		    ASSERT (col != Work->pivcol) ;
		}
	    }
	    else
	    {
		/* no Lsons in any row */
		ASSERT (extrdeg > 0) ;
		/* Uson external row degree is = number of cols left */
		ASSERT (IMPLIES (extcdeg == 0, extrdeg == ep->ncolsleft)) ;
	    }
	}
    }

    /* ---------------------------------------------------------------------- */

    for (j2 = 0 ; j2 < fncols ; j2++)
    {
	/* Get a column */
	col = Work->Fcols [j2] ;
	ASSERT (col >= 0 && col < n_col) ;

	DEBUG6 (("DEBUG SCAN 2: "ID"\n", col)) ;
#ifndef FIXQ
	UMF_dump_rowcol (1, Numeric, Work, col, TRUE) ;
#else
	UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ;
#endif

	ASSERT (NON_PIVOTAL_COL (col)) ;
	tpi = Col_tuples [col] ;
	if (!tpi) continue ;
	tp = (Tuple *) (Memory + tpi) ;
	tpend = tp + Col_tlen [col] ;
	for ( ; tp < tpend ; tp++)
	{
	    e = tp->e ;
	    ASSERT (e > 0 && e <= Work->nel) ;
	    if (!E [e]) continue ;	/* element already deallocated */
	    f = tp->f ;
	    p = Memory + E [e] ;
	    ep = (Element *) p ;
	    p += UNITS (Element, 1) ;
	    Cols = (Int *) p ;
	    Rows = ((Int *) p) + ep->ncols ;
	    if (Cols [f] == EMPTY) continue ;	/* column already assembled */
	    ASSERT (col == Cols [f]) ;
	    extrdeg = (ep->rdeg < rdeg0) ? ep->ncolsleft : (ep->rdeg - rdeg0) ;
	    extcdeg = (ep->cdeg < cdeg0) ? ep->nrowsleft : (ep->cdeg - cdeg0) ;
	    DEBUG6 (("e "ID" After assembly ext col deg: "ID"\n", e, extcdeg)) ;

	    if (Work->any_skip)
	    {
		/* no Usons in any column, except for very tall and thin ones */
		ASSERT (extcdeg >= 0) ;
		if (extcdeg == 0)
		{
		    /* this is an unassemble Uson */
		    ASSERT (ep->nrows == 1) ;
		    ASSERT (ep->nrowsleft == 1) ;
		    row = Rows [0] ;
		    ASSERT (row != Work->pivrow) ;
		}
	    }
	    else
	    {
		/* no Usons in any column */
		ASSERT (extcdeg > 0) ;
		/* Lson external column degree is = number of rows left */
		ASSERT (IMPLIES (extrdeg == 0, extcdeg == ep->nrowsleft)) ;
	    }
	}
    }
#endif /* NDEBUG */
}
Example #16
0
static auth_result url_add_listener (auth_client *auth_user)
{
    client_t *client = auth_user->client;
    auth_t *auth = auth_user->auth;
    auth_url *url = auth->state;
    auth_thread_data *atd = auth_user->thread_data;

    int res = 0, ret = AUTH_FAILED, poffset = 0;
    struct build_intro_contents *x;
    char *userpwd = NULL, post [8192];

    if (url->addurl == NULL || client == NULL)
        return AUTH_OK;

    if (url->stop_req_until)
    {
        time_t now = time(NULL);
        if (url->stop_req_until <= now)
        {
            INFO1 ("restarting url after timeout on %s", auth_user->mount);
            url->stop_req_until = 0;
        }
        else
        {
            if (auth->flags & AUTH_SKIP_IF_SLOW)
            {
                client->flags |= CLIENT_AUTHENTICATED;
                return AUTH_OK;
            }
            return AUTH_FAILED;
        }
    }
    do
    {
        ice_config_t *config = config_get_config ();
        char *user_agent, *username, *password, *mount, *ipaddr, *referer, *current_listeners,
             *server = util_url_escape (config->hostname);
        int port = config->port;
        config_release_config ();

        const char *tmp = httpp_getvar (client->parser, "user-agent");

        if (tmp == NULL)
            tmp = "-";
        user_agent = util_url_escape (tmp);

        if (client->username)
            username  = util_url_escape (client->username);
        else
            username = strdup ("");
        if (client->password)
            password  = util_url_escape (client->password);
        else
            password = strdup ("");

        /* get the full uri (with query params if available) */
        tmp = httpp_getvar (client->parser, HTTPP_VAR_QUERYARGS);
        snprintf (post, sizeof post, "%s%s", auth_user->mount, tmp ? tmp : "");
        mount = util_url_escape (post);
        ipaddr = util_url_escape (client->connection.ip);
        tmp = httpp_getvar (client->parser, "referer");
        referer = tmp ? util_url_escape (tmp) : strdup ("");

        current_listeners = stats_get_value(auth->mount, "listeners");
        if (current_listeners == NULL)
            current_listeners = strdup("");

        poffset = snprintf (post, sizeof (post),
                "action=listener_add&server=%s&port=%d&client=%" PRIu64 "&mount=%s"
                "&user=%s&pass=%s&ip=%s&agent=%s&referer=%s&listeners=%s",
                server, port, client->connection.id, mount, username,
                password, ipaddr, user_agent, referer, current_listeners);
        free (current_listeners);
        free (server);
        free (mount);
        free (referer);
        free (user_agent);
        free (username);
        free (password);
        free (ipaddr);
        if (poffset < 0 || poffset >= sizeof (post))
        {
            WARN2 ("client from %s (on %s), rejected with headers problem", &client->connection.ip[0], auth_user->mount);
            return AUTH_FAILED;
        }
    } while (0);

    if (url->header_chk_list)
    {
        int c = url->header_chk_count, remaining = sizeof(post) - poffset;
        char *cur_header = url->header_chk_list;
        const char *prefix = (url->header_chk_prefix && isalnum (url->header_chk_prefix[0])) ? url->header_chk_prefix : "ClientHeader-";

        for (; c ; c--)
        {
            int len = strlen (cur_header);
            const char *val = httpp_getvar (client->parser, cur_header);
            if (val)
            {
                char *valesc = util_url_escape (val);
                int r = remaining > 0 ? snprintf (post+poffset, remaining, "&%s%s=%s", prefix, cur_header, valesc) : -1;
                free (valesc);
                if (r < 0 || r > remaining)
                {
                    WARN2 ("client from %s (on %s), rejected with too much in headers", &client->connection.ip[0], auth_user->mount);
                    return AUTH_FAILED;
                }
                poffset += r;
                remaining -= r;
            }
            cur_header += (len + 1); // get past next nul
        }
    }

    if (strchr (url->addurl, '@') == NULL)
    {
        if (url->userpwd)
            curl_easy_setopt (atd->curl, CURLOPT_USERPWD, url->userpwd);
        else
        {
            /* auth'd requests may not have a user/pass, but may use query args */
            if (client->username && client->password)
            {
                int len = strlen (client->username) + strlen (client->password) + 2;
                userpwd = malloc (len);
                snprintf (userpwd, len, "%s:%s", client->username, client->password);
                curl_easy_setopt (atd->curl, CURLOPT_USERPWD, userpwd);
            }
            else
                curl_easy_setopt (atd->curl, CURLOPT_USERPWD, "");
        }
    }
    else
    {
        /* url has user/pass but libcurl may need to clear any existing settings */
        curl_easy_setopt (atd->curl, CURLOPT_USERPWD, "");
    }
    curl_easy_setopt (atd->curl, CURLOPT_URL, url->addurl);
    curl_easy_setopt (atd->curl, CURLOPT_POSTFIELDS, post);
    curl_easy_setopt (atd->curl, CURLOPT_WRITEHEADER, auth_user);
    curl_easy_setopt (atd->curl, CURLOPT_WRITEDATA, auth_user);
    atd->errormsg[0] = '\0';
    free (atd->location);
    atd->location = NULL;
    /* setup in case intro data is returned */
    x = (void *)client->refbuf->data;
    x->type = 0;
    x->head = NULL;
    x->intro_len = 0;
    x->tailp = &x->head;

    DEBUG2 ("handler %d (%s) sending request", auth_user->handler, auth_user->mount);
    res = curl_easy_perform (atd->curl);
    DEBUG2 ("handler %d (%s) request finished", auth_user->handler, auth_user->mount);

    free (userpwd);

    if (client->flags & CLIENT_AUTHENTICATED)
    {
        if (client->flags & CLIENT_HAS_INTRO_CONTENT)
        {
            client->refbuf->next = x->head;
            DEBUG3 ("intro (%d) received %lu for %s", x->type, (unsigned long)x->intro_len, client->connection.ip);
        }
        if (x->head == NULL)
            client->flags &= ~CLIENT_HAS_INTRO_CONTENT;
        x->head = NULL;
        ret = AUTH_OK;
    }
    if (res)
    {
        url->stop_req_until = time (NULL) + url->stop_req_duration; /* prevent further attempts for a while */
        WARN3 ("auth to server %s (%s) failed with %s", url->addurl, auth_user->mount, atd->errormsg);
        INFO1 ("will not auth new listeners for %d seconds", url->stop_req_duration);
        if (auth->flags & AUTH_SKIP_IF_SLOW)
        {
            client->flags |= CLIENT_AUTHENTICATED;
            ret = AUTH_OK;
        }
    }
    /* better cleanup memory */
    while (x->head)
    {
        refbuf_t *n = x->head;
        x->head = n->next;
        n->next = NULL;
        refbuf_release (n);
    }
    if (x->type)
        mpeg_cleanup (&x->sync);
    if (atd->location)
    {
        client_send_302 (client, atd->location);
        auth_user->client = NULL;
        free (atd->location);
        atd->location = NULL;
    }
    else if (atd->errormsg[0])
    {
        INFO3 ("listener %s (%s) returned \"%s\"", client->connection.ip, url->addurl, atd->errormsg);
        if (atoi (atd->errormsg) == 403)
        {
            auth_user->client = NULL;
            client_send_403 (client, atd->errormsg+4);
        }
    }
    return ret;
}
Example #17
0
int proxy_tls_recv(rad_listen_t *listener)
{
	int rcode;
	size_t length;
	listen_socket_t *sock = listener->data;
	char buffer[256];
	RADIUS_PACKET *packet;
	uint8_t *data;

	/*
	 *	Get the maximum size of data to receive.
	 */
	if (!sock->data) sock->data = talloc_array(sock, uint8_t,
						   sock->ssn->offset);
	data = sock->data;

	DEBUG3("Proxy SSL socket has data to read");
	PTHREAD_MUTEX_LOCK(&sock->mutex);
redo:
	rcode = SSL_read(sock->ssn->ssl, data, 4);
	if (rcode <= 0) {
		int err = SSL_get_error(sock->ssn->ssl, rcode);
		switch (err) {
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			goto redo;

		case SSL_ERROR_ZERO_RETURN:
			/* remote end sent close_notify, send one back */
			SSL_shutdown(sock->ssn->ssl);

		case SSL_ERROR_SYSCALL:
		do_close:
			PTHREAD_MUTEX_UNLOCK(&sock->mutex);
			tls_socket_close(listener);
			return 0;

		default:
			while ((err = ERR_get_error())) {
				DEBUG("proxy recv says %s",
				      ERR_error_string(err, NULL));
			}
			
			goto do_close;
		}
	}

	length = (data[2] << 8) | data[3];
	DEBUG3("Proxy received header saying we have a packet of %u bytes",
	       (unsigned int) length);

	if (length > sock->ssn->offset) {
		INFO("Received packet will be too large! Set \"fragment_size=%u\"",
		       (data[2] << 8) | data[3]);
		goto do_close;
	}
	
	rcode = SSL_read(sock->ssn->ssl, data + 4, length);
	if (rcode <= 0) {
		switch (SSL_get_error(sock->ssn->ssl, rcode)) {
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			break;

		case SSL_ERROR_ZERO_RETURN:
			/* remote end sent close_notify, send one back */
			SSL_shutdown(sock->ssn->ssl);
			goto do_close;
		default:
			goto do_close;
		}
	}
	PTHREAD_MUTEX_UNLOCK(&sock->mutex);

	packet = rad_alloc(NULL, 0);
	packet->sockfd = listener->fd;
	packet->src_ipaddr = sock->other_ipaddr;
	packet->src_port = sock->other_port;
	packet->dst_ipaddr = sock->my_ipaddr;
	packet->dst_port = sock->my_port;
	packet->code = data[0];
	packet->id = data[1];
	packet->data_len = length;
	packet->data = talloc_array(packet, uint8_t, packet->data_len);
	memcpy(packet->data, data, packet->data_len);
	memcpy(packet->vector, packet->data + 4, 16);

	/*
	 *	FIXME: Client MIB updates?
	 */
	switch(packet->code) {
	case PW_AUTHENTICATION_ACK:
	case PW_ACCESS_CHALLENGE:
	case PW_AUTHENTICATION_REJECT:
		break;

#ifdef WITH_ACCOUNTING
	case PW_ACCOUNTING_RESPONSE:
		break;
#endif

	default:
		/*
		 *	FIXME: Update MIB for packet types?
		 */
		ERROR("Invalid packet code %d sent to a proxy port "
		       "from home server %s port %d - ID %d : IGNORED",
		       packet->code,
		       ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
		       packet->src_port, packet->id);
		rad_free(&packet);
		return 0;
	}

	if (!request_proxy_reply(packet)) {
		rad_free(&packet);
		return 0;
	}

	return 1;
}
Example #18
0
GLOBAL Int UMF_init_front
(
    NumericType *Numeric,
    WorkType *Work
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Int i, j, fnr_curr, row, col, *Frows, *Fcols,
	*Fcpos, *Frpos, fncols, fnrows, *Wrow, fnr2, fnc2, rrdeg, ccdeg, *Wm,
	fnrows_extended ;
    Entry *Fcblock, *Fl, *Wy, *Wx ;

    /* ---------------------------------------------------------------------- */
    /* get current frontal matrix and check for frontal growth */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    DEBUG0 (("INIT FRONT\n")) ;
    DEBUG1 (("CURR before init:\n")) ;
    UMF_dump_current_front (Numeric, Work, FALSE) ;
#endif
    if (Work->do_grow)
    {
	fnr2 = UMF_FRONTAL_GROWTH * Work->fnrows_new + 2 ;
	fnc2 = UMF_FRONTAL_GROWTH * Work->fncols_new + 2 ;
	if (!UMF_grow_front (Numeric, fnr2, fnc2, Work,
	    Work->pivrow_in_front ? 2 : 0))
	{
	    /* :: out of memory in umf_init_front :: */
	    DEBUGm4 (("out of memory: init front\n")) ;
	    return (FALSE) ;
	}
    }
#ifndef NDEBUG
    DEBUG1 (("CURR after grow:\n")) ;
    UMF_dump_current_front (Numeric, Work, FALSE) ;
    DEBUG1 (("fnrows new "ID" fncols new "ID"\n",
	Work->fnrows_new, Work->fncols_new)) ;
#endif
    ASSERT (Work->fnpiv == 0) ;
    fnr_curr = Work->fnr_curr ;
    ASSERT (Work->fnrows_new + 1 <= fnr_curr) ;
    ASSERT (Work->fncols_new + 1 <= Work->fnc_curr) ;
    ASSERT (fnr_curr >= 0) ;
    ASSERT (fnr_curr % 2 == 1) ;

    /* ---------------------------------------------------------------------- */
    /* get parameters */
    /* ---------------------------------------------------------------------- */

    /* current front is defined by pivot row and column */

    Frows = Work->Frows ;
    Fcols = Work->Fcols ;
    Frpos = Work->Frpos ;
    Fcpos = Work->Fcpos ;

    Work->fnzeros = 0 ;

    ccdeg = Work->ccdeg ;
    rrdeg = Work->rrdeg ;

    fnrows = Work->fnrows ;
    fncols = Work->fncols ;

    /* if both pivrow and pivcol are in front, then we extend the old one */
    /* in UMF_extend_front, rather than starting a new one here. */
    ASSERT (! (Work->pivrow_in_front && Work->pivcol_in_front)) ;

    /* ---------------------------------------------------------------------- */
    /* place pivot column pattern in frontal matrix */
    /* ---------------------------------------------------------------------- */

    Fl = Work->Flblock ;

    if (Work->pivcol_in_front)
    {
	/* Append the pivot column extension.
	 * Note that all we need to do is increment the size, since the
	 * candidate pivot column pattern is already in place in
	 * Frows [0 ... fnrows-1] (the old pattern), and
	 * Frows [fnrows ... fnrows + Work->ccdeg - 1] (the new
	 * pattern).  Frpos is also properly defined. */
	/* make a list of the new rows to scan */
	Work->fscan_row = fnrows ;	/* only scan the new rows */
	Work->NewRows = Work->Wrp ;
	Wy = Work->Wy ;
	for (i = 0 ; i < fnrows ; i++)
	{
	    Fl [i] = Wy [i] ;
	}
	fnrows_extended = fnrows + ccdeg ;
	for (i = fnrows ; i < fnrows_extended ; i++)
	{
	    Fl [i] = Wy [i] ;
	    /* flip the row index, since Wrp must be < 0 */
	    row = Frows [i] ;
	    Work->NewRows [i] = FLIP (row) ;
	}
	fnrows = fnrows_extended ;
    }
    else
    {
	/* this is a completely new column */
	Work->fscan_row = 0 ;			/* scan all the rows */
	Work->NewRows = Frows ;
	Wm = Work->Wm ;
	Wx = Work->Wx ;
	for (i = 0 ; i < ccdeg ; i++)
	{
	    Fl [i] = Wx [i] ;
	    row = Wm [i] ;
	    Frows [i] = row ;
	    Frpos [row] = i ;
	}
	fnrows = ccdeg ;
    }

    Work->fnrows = fnrows ;

#ifndef NDEBUG
    DEBUG3 (("New Pivot col "ID" now in front, length "ID"\n",
	Work->pivcol, fnrows)) ;
    for (i = 0 ; i < fnrows ; i++)
    {
	DEBUG4 ((" "ID": row "ID"\n", i, Frows [i])) ;
	ASSERT (Frpos [Frows [i]] == i) ;
    }
#endif

    /* ---------------------------------------------------------------------- */
    /* place pivot row pattern in frontal matrix */
    /* ---------------------------------------------------------------------- */

    Wrow = Work->Wrow ;
    if (Work->pivrow_in_front)
    {
	/* append the pivot row extension */
	Work->fscan_col = fncols ;	/* only scan the new columns */
	Work->NewCols = Work->Wp ;
#ifndef NDEBUG
	for (j = 0 ; j < fncols ; j++)
	{
	    col = Fcols [j] ;
	    ASSERT (col >= 0 && col < Work->n_col) ;
	    ASSERT (Fcpos [col] == j * fnr_curr) ;
	}
#endif
	/* Wrow == Fcol for the IN_IN case, and for the OUT_IN case when
	 * the pivrow [IN][IN] happens to be the same as pivrow [OUT][IN].
	 * See UMF_local_search for more details. */
	ASSERT (IMPLIES (Work->pivcol_in_front, Wrow == Fcols)) ;
	if (Wrow == Fcols)
	{
	    for (j = fncols ; j < rrdeg ; j++)
	    {
		col = Wrow [j] ;
		/* Fcols [j] = col ; not needed */
		/* flip the col index, since Wp must be < 0 */
		Work->NewCols [j] = FLIP (col) ;
		Fcpos [col] = j * fnr_curr ;
	    }
	}
	else
	{
	    for (j = fncols ; j < rrdeg ; j++)
	    {
		col = Wrow [j] ;
		Fcols [j] = col ;
		/* flip the col index, since Wp must be < 0 */
		Work->NewCols [j] = FLIP (col) ;
		Fcpos [col] = j * fnr_curr ;
	    }
	}
    }
    else
    {
	/* this is a completely new row */
	Work->fscan_col = 0 ;			/* scan all the columns */
	Work->NewCols = Fcols ;
	for (j = 0 ; j < rrdeg ; j++)
	{
	    col = Wrow [j] ;
	    Fcols [j] = col ;
	    Fcpos [col] = j * fnr_curr ;
	}
    }

    DEBUGm1 (("rrdeg "ID" fncols "ID"\n", rrdeg, fncols)) ;
    fncols = rrdeg ;
    Work->fncols = fncols ;

    /* ---------------------------------------------------------------------- */
    /* clear the frontal matrix */
    /* ---------------------------------------------------------------------- */

    ASSERT (fnrows == Work->fnrows_new + 1) ;
    ASSERT (fncols == Work->fncols_new + 1) ;

    Fcblock = Work->Fcblock ;
    ASSERT (Fcblock != (Entry *) NULL) ;

    zero_init_front (fncols, fnrows, Fcblock, fnr_curr) ;

#ifndef NDEBUG
    DEBUG3 (("New Pivot row "ID" now in front, length "ID" fnr_curr "ID"\n",
		Work->pivrow, fncols, fnr_curr)) ;
    for (j = 0 ; j < fncols ; j++)
    {
	DEBUG4 (("col "ID" position "ID"\n", j, Fcols [j])) ;
	ASSERT (Fcpos [Fcols [j]] == j * fnr_curr) ;
    }
#endif

    /* ---------------------------------------------------------------------- */
    /* current workspace usage: */
    /* ---------------------------------------------------------------------- */

    /* Fcblock [0..fnr_curr-1, 0..fnc_curr-1]: space for the new frontal
     * matrix.  Fcblock (i,j) is located at Fcblock [i+j*fnr_curr] */

    return (TRUE) ;

}
Example #19
0
static gpgme_error_t
status_handler (void *opaque, int fd)
{
  gpg_error_t assuan_err;
  gpgme_error_t err = 0;
  engine_gpgsm_t gpgsm = opaque;
  char *line;
  size_t linelen;

  do
    {
      assuan_err = assuan_read_line (gpgsm->assuan_ctx, &line, &linelen);
      if (assuan_err)
	{
	  /* Try our best to terminate the connection friendly.  */
	  /*	  assuan_write_line (gpgsm->assuan_ctx, "BYE"); */
	  err = map_assuan_error (assuan_err);
          DEBUG3 ("fd %d: error from assuan (%d) getting status line : %s \n",
                  fd, assuan_err, gpg_strerror (err));
	}
      else if (linelen >= 3
	       && line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
	       && (line[3] == '\0' || line[3] == ' '))
	{
	  if (line[3] == ' ')
	    err = map_assuan_error (atoi (&line[4]));
	  else
	    err = gpg_error (GPG_ERR_GENERAL);
          DEBUG2 ("fd %d: ERR line - mapped to: %s\n",
                  fd, err? gpg_strerror (err):"ok");
	}
      else if (linelen >= 2
	       && line[0] == 'O' && line[1] == 'K'
	       && (line[2] == '\0' || line[2] == ' '))
	{
	  if (gpgsm->status.fnc)
	    err = gpgsm->status.fnc (gpgsm->status.fnc_value,
				     GPGME_STATUS_EOF, "");
	  
	  if (!err && gpgsm->colon.fnc && gpgsm->colon.any )
            {
              /* We must tell a colon function about the EOF. We do
                 this only when we have seen any data lines.  Note
                 that this inlined use of colon data lines will
                 eventually be changed into using a regular data
                 channel. */
              gpgsm->colon.any = 0;
              err = gpgsm->colon.fnc (gpgsm->colon.fnc_value, NULL);
            }
	  _gpgme_io_close (gpgsm->status_cb.fd);
          DEBUG2 ("fd %d: OK line - final status: %s\n",
                  fd, err? gpg_strerror (err):"ok");
	  return err;
	}
      else if (linelen > 2
	       && line[0] == 'D' && line[1] == ' '
	       && gpgsm->colon.fnc)
        {
	  /* We are using the colon handler even for plain inline data
             - strange name for that function but for historic reasons
             we keep it.  */
          /* FIXME We can't use this for binary data because we
             assume this is a string.  For the current usage of colon
             output it is correct.  */
          char *src = line + 2;
	  char *end = line + linelen;
	  char *dst;
          char **aline = &gpgsm->colon.attic.line;
	  int *alinelen = &gpgsm->colon.attic.linelen;

	  if (gpgsm->colon.attic.linesize
	      < *alinelen + linelen + 1)
	    {
	      char *newline = realloc (*aline, *alinelen + linelen + 1);
	      if (!newline)
		err = gpg_error_from_errno (errno);
	      else
		{
		  *aline = newline;
		  gpgsm->colon.attic.linesize += linelen + 1;
		}
	    }
	  if (!err)
	    {
	      dst = *aline + *alinelen;

	      while (!err && src < end)
		{
		  if (*src == '%' && src + 2 < end)
		    {
		      /* Handle escaped characters.  */
		      ++src;
		      *dst = _gpgme_hextobyte (src);
		      (*alinelen)++;
		      src += 2;
		    }
		  else
		    {
		      *dst = *src++;
		      (*alinelen)++;
		    }
		  
		  if (*dst == '\n')
		    {
		      /* Terminate the pending line, pass it to the colon
			 handler and reset it.  */
		      
		      gpgsm->colon.any = 1;
		      if (*alinelen > 1 && *(dst - 1) == '\r')
			dst--;
		      *dst = '\0';

		      /* FIXME How should we handle the return code?  */
		      err = gpgsm->colon.fnc (gpgsm->colon.fnc_value, *aline);
		      if (!err)
			{
			  dst = *aline;
			  *alinelen = 0;
			}
		    }
		  else
		    dst++;
		}
	    }
          DEBUG2 ("fd %d: D line; final status: %s\n",
                  fd, err? gpg_strerror (err):"ok");
        }
      else if (linelen > 2
	       && line[0] == 'S' && line[1] == ' ')
	{
	  char *rest;
	  gpgme_status_code_t r;
	  
	  rest = strchr (line + 2, ' ');
	  if (!rest)
	    rest = line + linelen; /* set to an empty string */
	  else
	    *(rest++) = 0;

	  r = parse_status (line + 2);

	  if (r >= 0)
	    {
	      if (gpgsm->status.fnc)
		err = gpgsm->status.fnc (gpgsm->status.fnc_value, r, rest);
	    }
	  else
	    fprintf (stderr, "[UNKNOWN STATUS]%s %s", line + 2, rest);
          DEBUG3 ("fd %d: S line (%s) - final status: %s\n",
                  fd, line+2, err? gpg_strerror (err):"ok");
	}
    }
  while (!err && assuan_pending_line (gpgsm->assuan_ctx));
	  
  return err;
}
Example #20
0
GLOBAL Int UMF_build_tuples
(
    NumericType *Numeric,
    WorkType *Work
)
{
    /* ---------------------------------------------------------------------- */
    /* local variables */
    /* ---------------------------------------------------------------------- */

    Int e, nrows, ncols, nel, *Rows, *Cols, row, col, n_row, n_col, *E,
	*Row_tuples, *Row_degree, *Row_tlen,
	*Col_tuples, *Col_degree, *Col_tlen, n1 ;
    Element *ep ;
    Unit *p ;
    Tuple tuple, *tp ;

    /* ---------------------------------------------------------------------- */
    /* get parameters */
    /* ---------------------------------------------------------------------- */

    E = Work->E ;
    Col_degree = Numeric->Cperm ;	/* for NON_PIVOTAL_COL macro */
    Row_degree = Numeric->Rperm ;	/* for NON_PIVOTAL_ROW macro */
    Row_tuples = Numeric->Uip ;
    Row_tlen   = Numeric->Uilen ;
    Col_tuples = Numeric->Lip ;
    Col_tlen   = Numeric->Lilen ;
    n_row = Work->n_row ;
    n_col = Work->n_col ;
    nel = Work->nel ;
    n1 = Work->n1 ;

    DEBUG3 (("BUILD_TUPLES: n_row "ID" n_col "ID" nel "ID"\n",
	n_row, n_col, nel)) ;

    /* ---------------------------------------------------------------------- */
    /* allocate space for the tuple lists */
    /* ---------------------------------------------------------------------- */

    /* Garbage collection and memory reallocation have already attempted to */
    /* ensure that there is enough memory for all the tuple lists.  If */
    /* memory allocation fails here, then there is nothing more to be done. */

    for (row = n1 ; row < n_row ; row++)
    {
	if (NON_PIVOTAL_ROW (row))
	{
	    Row_tuples [row] = UMF_mem_alloc_tail_block (Numeric,
		UNITS (Tuple, TUPLES (Row_tlen [row]))) ;
	    if (!Row_tuples [row])
	    {
		/* :: out of memory for row tuples :: */
		DEBUGm4 (("out of memory: build row tuples\n")) ;
		return (FALSE) ;	/* out of memory for row tuples */
	    }
	    Row_tlen [row] = 0 ;
	}
    }

    /* push on stack in reverse order, so column tuples are in the order */
    /* that they will be deleted. */
    for (col = n_col-1 ; col >= n1 ; col--)
    {
	if (NON_PIVOTAL_COL (col))
	{
	    Col_tuples [col] = UMF_mem_alloc_tail_block (Numeric,
		UNITS (Tuple, TUPLES (Col_tlen [col]))) ;
	    if (!Col_tuples [col])
	    {
		/* :: out of memory for col tuples :: */
		DEBUGm4 (("out of memory: build col tuples\n")) ;
		return (FALSE) ;	/* out of memory for col tuples */
	    }
	    Col_tlen [col] = 0 ;
	}
    }

#ifndef NDEBUG
    UMF_dump_memory (Numeric) ;
#endif

    /* ---------------------------------------------------------------------- */
    /* create the tuple lists (exclude element 0) */
    /* ---------------------------------------------------------------------- */

    /* for all elements, in order of creation */
    for (e = 1 ; e <= nel ; e++)
    {
	DEBUG9 (("Adding tuples for element: "ID" at "ID"\n", e, E [e])) ;
	ASSERT (E [e]) ;	/* no external fragmentation */
	p = Numeric->Memory + E [e] ;
	GET_ELEMENT_PATTERN (ep, p, Cols, Rows, ncols) ;
	nrows = ep->nrows ;
	ASSERT (e != 0) ;
	ASSERT (e == 0 || nrows == ep->nrowsleft) ;
	ASSERT (e == 0 || ncols == ep->ncolsleft) ;
	tuple.e = e ;
	for (tuple.f = 0 ; tuple.f < ncols ; tuple.f++)
	{
	    col = Cols [tuple.f] ;
	    ASSERT (col >= n1 && col < n_col) ;
	    ASSERT (NON_PIVOTAL_COL (col)) ;
	    ASSERT (Col_tuples [col]) ;
	    tp = ((Tuple *) (Numeric->Memory + Col_tuples [col]))
		+ Col_tlen [col]++ ;
	    *tp = tuple ;
#ifndef NDEBUG
	    UMF_dump_rowcol (1, Numeric, Work, col, FALSE) ;
#endif
	}
	for (tuple.f = 0 ; tuple.f < nrows ; tuple.f++)
	{
	    row = Rows [tuple.f] ;
	    ASSERT (row >= n1 && row < n_row) ;
	    ASSERT (NON_PIVOTAL_COL (col)) ;
	    ASSERT (Row_tuples [row]) ;
	    tp = ((Tuple *) (Numeric->Memory + Row_tuples [row]))
		+ Row_tlen [row]++ ;
	    *tp = tuple ;
#ifndef NDEBUG
	    UMF_dump_rowcol (0, Numeric, Work, row, FALSE) ;
#endif
	}
    }

    /* ---------------------------------------------------------------------- */
    /* the tuple lists are now valid, and can be scanned */
    /* ---------------------------------------------------------------------- */

#ifndef NDEBUG
    UMF_dump_memory (Numeric) ;
    UMF_dump_matrix (Numeric, Work, FALSE) ;
#endif
    DEBUG3 (("BUILD_TUPLES: done\n")) ;
    return (TRUE) ;
}
/**
 * Transaction 5 - T5
 * 
 * Delete session
 *
 * Input:
 *   SubscriberNumber
 *   ServerId
 *   ServerBit
 *   DoRollback
 * Output:
 *   ChangedBy
 *   ChangedTime
 *   Location
 *   BranchExecuted
 */
int
T5(void * obj,
   const SubscriberNumber   inNumber,
   const SubscriberSuffix   inSuffix,
   const ServerId           inServerId,
   const ServerBit          inServerBit,
   ChangedBy          outChangedBy,
   ChangedTime        outChangedTime,
   Location         * outLocation,
   DoRollback         inDoRollback,
   BranchExecuted   * outBranchExecuted,
   BenchmarkTime    * outTransactionTime){
  
  Ndb           * pNDB = (Ndb *) obj;  
  NdbConnection * MyTransaction = 0;
  NdbOperation  * MyOperation = 0;

  GroupId        groupId;
  ActiveSessions sessions;
  Permission     permission;

  BenchmarkTime start;
  get_time(&start);

  int check;
  NdbRecAttr * check2;

  MyTransaction = pNDB->startTransaction();
  if (MyTransaction == NULL)	  
    error_handler("T5-1: startTranscation", pNDB->getNdbErrorString(), 0);

  MyOperation= MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
  CHECK_NULL(MyOperation, "T5-1: getNdbOperation", 
	     MyTransaction);
  
  
  check = MyOperation->readTupleExclusive();
  CHECK_MINUS_ONE(check, "T5-1: readTuple", 
		  MyTransaction);
  
  check = MyOperation->equal(IND_SUBSCRIBER_NUMBER, 
			     inNumber);
  CHECK_MINUS_ONE(check, "T5-1: equal subscriber",
		  MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_LOCATION, 
				 (char *)outLocation);
  CHECK_NULL(check2, "T5-1: getValue location", 
	     MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_BY, 
				 outChangedBy);
  CHECK_NULL(check2, "T5-1: getValue changed_by", 
	     MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_CHANGED_TIME, 
                                 outChangedTime);
  CHECK_NULL(check2, "T5-1: getValue changed_time",
	     MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_GROUP,
				 (char *)&groupId);
  CHECK_NULL(check2, "T5-1: getValue group", 
	     MyTransaction);

  check2 = MyOperation->getValue(IND_SUBSCRIBER_SESSIONS,
				 (char *)&sessions);
  CHECK_NULL(check2, "T5-1: getValue sessions", 
	     MyTransaction);
  
  check = MyTransaction->execute( NoCommit ); 
  CHECK_MINUS_ONE(check, "T5-1: NoCommit", 
		  MyTransaction);
  
    /* Operation 2 */

  MyOperation = MyTransaction->getNdbOperation(GROUP_TABLE);
  CHECK_NULL(MyOperation, "T5-2: getNdbOperation", 
	     MyTransaction);
  
  
  check = MyOperation->readTuple();
  CHECK_MINUS_ONE(check, "T5-2: readTuple", 
		  MyTransaction);
  
  check = MyOperation->equal(IND_GROUP_ID,
		     (char*)&groupId);
  CHECK_MINUS_ONE(check, "T5-2: equal group",
		  MyTransaction);
  
  check2 = MyOperation->getValue(IND_GROUP_ALLOW_DELETE, 
				 (char *)&permission);
  CHECK_NULL(check2, "T5-2: getValue allow_delete", 
	     MyTransaction);
  
  check = MyTransaction->execute( NoCommit ); 
  CHECK_MINUS_ONE(check, "T5-2: NoCommit", 
		  MyTransaction);
  
  DEBUG3("T5(%.*s, %.2d): ", SUBSCRIBER_NUMBER_LENGTH, inNumber, inServerId);

  if(((permission & inServerBit) == inServerBit) &&
     ((sessions   & inServerBit) == inServerBit)){
  
    DEBUG("deleting - ");
  
    /* Operation 3 */
    MyOperation = MyTransaction->getNdbOperation(SESSION_TABLE);
    CHECK_NULL(MyOperation, "T5-3: getNdbOperation", 
	       MyTransaction);
    
    check = MyOperation->deleteTuple();
    CHECK_MINUS_ONE(check, "T5-3: deleteTuple", 
		    MyTransaction);
    
    check = MyOperation->equal(IND_SESSION_SUBSCRIBER,
			       (char*)inNumber);
    CHECK_MINUS_ONE(check, "T5-3: equal number",
		    MyTransaction);

    check = MyOperation->equal(IND_SESSION_SERVER,
			       (char*)&inServerId);
    CHECK_MINUS_ONE(check, "T5-3: equal server id",
		    MyTransaction);
    
    check = MyTransaction->execute( NoCommit ); 
    CHECK_MINUS_ONE(check, "T5-3: NoCommit", 
		    MyTransaction);

    /* Operation 4 */
    MyOperation = MyTransaction->getNdbOperation(SUBSCRIBER_TABLE);
    CHECK_NULL(MyOperation, "T5-4: getNdbOperation", 
	       MyTransaction);
    
    check = MyOperation->interpretedUpdateTuple();
    CHECK_MINUS_ONE(check, "T5-4: interpretedUpdateTuple", 
		    MyTransaction);
    
    check = MyOperation->equal(IND_SUBSCRIBER_NUMBER,
			       (char*)inNumber);
    CHECK_MINUS_ONE(check, "T5-4: equal number",
		    MyTransaction);

    check = MyOperation->subValue(IND_SUBSCRIBER_SESSIONS, 
				  (uint32)inServerBit);
    CHECK_MINUS_ONE(check, "T5-4: dec value",
		    MyTransaction);
        
    check = MyTransaction->execute( NoCommit ); 
    CHECK_MINUS_ONE(check, "T5-4: NoCommit", 
		    MyTransaction);

    /* Operation 5 */
    MyOperation = MyTransaction->getNdbOperation(SERVER_TABLE);
    CHECK_NULL(MyOperation, "T5-5: getNdbOperation", 
	       MyTransaction);
    
    
    check = MyOperation->interpretedUpdateTuple();
    CHECK_MINUS_ONE(check, "T5-5: interpretedUpdateTuple", 
		    MyTransaction);
    
    check = MyOperation->equal(IND_SERVER_ID,
			       (char*)&inServerId);
    CHECK_MINUS_ONE(check, "T5-5: equal serverId",
		    MyTransaction);

    check = MyOperation->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
			       (char*)inSuffix);
    CHECK_MINUS_ONE(check, "T5-5: equal suffix",
		    MyTransaction);

    check = MyOperation->incValue(IND_SERVER_DELETES, (uint32)1);
    CHECK_MINUS_ONE(check, "T5-5: inc value",
		    MyTransaction);

    check = MyTransaction->execute( NoCommit ); 
    CHECK_MINUS_ONE(check, "T5-5: NoCommit", 
		    MyTransaction);

    (* outBranchExecuted) = 1;
  } else {
    DEBUG1("%s", ((permission & inServerBit) ? "permission - " : "no permission - "));
    DEBUG1("%s", ((sessions   & inServerBit) ? "in session - " : "no in session - "));
    (* outBranchExecuted) = 0;
  }

  if(!inDoRollback){
    DEBUG("commit\n");
    check = MyTransaction->execute( Commit ); 
    CHECK_MINUS_ONE(check, "T5: Commit", 
		    MyTransaction);
  } else {
    DEBUG("rollback\n");
    check = MyTransaction->execute(Rollback);
    CHECK_MINUS_ONE(check, "T5:Rollback", 
		    MyTransaction);
    
  }
  
  pNDB->closeTransaction(MyTransaction);
  
  get_time(outTransactionTime);
  time_diff(outTransactionTime, &start);
  return 0;
}
Example #22
0
/*
 *	Display the revision number for this program
 */
void version(void)
{
	INFO("%s: %s", progname, radiusd_version);

	DEBUG3("Server was built with: ");

#ifdef WITH_ACCOUNTING
	DEBUG3("  accounting");
#endif
	DEBUG3("  authentication"); /* always enabled */

#ifdef WITH_ASCEND_BINARY
	DEBUG3("  ascend binary attributes");
#endif
#ifdef WITH_COA
	DEBUG3("  coa");
#endif
#ifdef WITH_COMMAND_SOCKET
	DEBUG3("  control-socket");
#endif
#ifdef WITH_DETAIL
	DEBUG3("  detail");
#endif
#ifdef WITH_DHCP
	DEBUG3("  dhcp");
#endif
#ifdef WITH_DYNAMIC_CLIENTS
	DEBUG3("  dynamic clients");
#endif
#ifdef OSFC2
	DEBUG3("  OSFC2");
#endif
#ifdef WITH_PROXY
	DEBUG3("  proxy");
#endif
#ifdef HAVE_PCREPOSIX_H
	DEBUG3("  regex-pcre");
#else
#ifdef HAVE_REGEX_H
	DEBUG3("  regex-posix");
#endif
#endif

#ifdef WITH_SESSION_MGMT
	DEBUG3("  session-management");
#endif
#ifdef WITH_STATS
	DEBUG3("  stats");
#endif
#ifdef WITH_TCP
	DEBUG3("  tcp");
#endif
#ifdef WITH_THREADS
	DEBUG3("  threads");
#endif
#ifdef WITH_TLS
	DEBUG3("  tls");
#endif
#ifdef WITH_UNLANG
	DEBUG3("  unlang");
#endif
#ifdef WITH_VMPS
	DEBUG3("  vmps");
#endif

	DEBUG3("Server core libs:");
	DEBUG3("  talloc : %i.%i.*", talloc_version_major(),
	       talloc_version_minor());
	DEBUG3("  ssl    : %s", ssl_version());


	INFO("Copyright (C) 1999-2013 The FreeRADIUS server project and contributors");
	INFO("There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A");
	INFO("PARTICULAR PURPOSE");
	INFO("You may redistribute copies of FreeRADIUS under the terms of the");
	INFO("GNU General Public License");
	INFO("For more information about these matters, see the file named COPYRIGHT");

	fflush(NULL);
}
/*
 *	The "detail.work" file exists, and is open in the 'fd'.
 */
static int work_exists(proto_detail_file_thread_t *thread, int fd)
{
	proto_detail_file_t const *inst = thread->inst;
	bool			opened = false;
	proto_detail_work_thread_t     *work;
	fr_listen_t		*li = NULL;
	struct stat		st;

	fr_event_vnode_func_t	funcs = { .delete = mod_vnode_delete };

	DEBUG3("proto_detail (%s): Trying to lock %s", thread->name, inst->filename_work);

	/*
	 *	"detail.work" exists, try to lock it.
	 */
	if (rad_lockfd_nonblock(fd, 0) < 0) {
		struct timeval when, now;

		DEBUG3("proto_detail (%s): Failed locking %s: %s",
		       thread->name, inst->filename_work, fr_syserror(errno));

		close(fd);

		when.tv_usec = thread->lock_interval % USEC;
		when.tv_sec = thread->lock_interval / USEC;

		/*
		 *	Ensure that we don't do massive busy-polling.
		 */
		thread->lock_interval += thread->lock_interval / 2;
		if (thread->lock_interval > (30 * USEC)) thread->lock_interval = 30 * USEC;

		DEBUG3("proto_detail (%s): Waiting %d.%06ds for lock on file %s",
		       thread->name, (int) when.tv_sec, (int) when.tv_usec, inst->filename_work);

		gettimeofday(&now, NULL);
		fr_timeval_add(&when, &when, &now);

		if (fr_event_timer_insert(thread, thread->el, &thread->ev,
					  &when, work_retry_timer, thread) < 0) {
			ERROR("Failed inserting retry timer for %s", inst->filename_work);
		}
		return 0;
	}

	DEBUG3("proto_detail (%s): Obtained lock and starting to process file %s",
	       thread->name, inst->filename_work);

	/*
	 *	Ignore empty files.
	 */
	if (fstat(fd, &st) < 0) {
		ERROR("Failed opening %s: %s", inst->filename_work,
		      fr_syserror(errno));
		unlink(inst->filename_work);
		close(fd);
		return 1;
	}

	if (!st.st_size) {
		DEBUG3("proto_detail (%s): %s file is empty, ignoring it.",
		       thread->name, inst->filename_work);
		unlink(inst->filename_work);
		close(fd);
		return 1;
	}

	/*
	 *	This listener is allocated in a thread-specific
	 *	context, so it doesn't need a destructor,
	 */
	MEM(li = talloc_zero(NULL, fr_listen_t));

	/*
	 *	Create a new listener, and insert it into the
	 *	scheduler.  Shamelessly copied from proto_detail.c
	 *	mod_open(), with changes.
	 *
	 *	This listener is parented from the worker.  So that
	 *	when the worker goes away, so does the listener.
	 */
	li->app_io = inst->parent->work_io;

	li->app = inst->parent->self;
	li->app_instance = inst->parent;
	li->server_cs = inst->parent->server_cs;

	/*
	 *	The worker may be in a different thread, so avoid
	 *	talloc threading issues by using a NULL TALLOC_CTX.
	 */
	MEM(li->thread_instance = work = talloc_zero(li, proto_detail_work_thread_t));

	li->app_io_instance = inst->parent->work_io_instance;
	work->inst = li->app_io_instance;
	work->file_parent = li->thread_instance;
	work->ev = NULL;

	li->fd = work->fd = dup(fd);
	if (work->fd < 0) {
		DEBUG("proto_detail (%s): Failed opening %s: %s",
		      thread->name, inst->filename_work, fr_syserror(errno));

		close(fd);
		talloc_free(li);
		return -1;
	}

	/*
	 *	Don't do anything until the file has been deleted.
	 *
	 *	@todo - ensure that proto_detail_work is done the file...
	 *	maybe by creating a new instance?
	 */
	if (fr_event_filter_insert(thread, thread->el, fd, FR_EVENT_FILTER_VNODE,
				   &funcs, NULL, thread) < 0) {
		PERROR("Failed adding work socket to event loop");
		close(fd);
		talloc_free(li);
		return -1;
	}

	/*
	 *	Remember this for later.
	 */
	thread->vnode_fd = fd;

	/*
	 *	For us, this is the worker listener.
	 *	For the worker, this is it's own parent
	 */
	thread->listen = li;

	work->filename_work = talloc_strdup(work, inst->filename_work);

	/*
	 *	Set configurable parameters for message ring buffer.
	 */
	li->default_message_size = inst->parent->max_packet_size;
	li->num_messages = inst->parent->num_messages;

	pthread_mutex_lock(&thread->worker_mutex);
	thread->num_workers++;
	pthread_mutex_unlock(&thread->worker_mutex);

	/*
	 *	Open the detail.work file.
	 */
	if (li->app_io->open(li) < 0) {
		ERROR("Failed opening %s", li->app_io->name);
		goto error;
	}
	opened = true;

	rad_assert(li->app_io->get_name);
	li->name = li->app_io->get_name(li);

	if (!fr_schedule_listen_add(inst->parent->sc, li)) {
	error:
		if (fr_event_fd_delete(thread->el, thread->vnode_fd, FR_EVENT_FILTER_VNODE) < 0) {
			PERROR("Failed removing DELETE callback when opening work file");
		}
		close(thread->vnode_fd);
		thread->vnode_fd = -1;

		if (opened) {
			(void) li->app_io->close(li);
			thread->listen = NULL;
			li = NULL;
		}

		talloc_free(li);
		return -1;
	}

	/*
	 *	Tell the worker to clean itself up.
	 */
	work->listen = li;

	return 0;
}
Example #24
0
void
ib_create(pci_t *pci_p)
{
	dev_info_t *dip = pci_p->pci_dip;
	ib_t *ib_p;
	uintptr_t a;
	int i;

	/*
	 * Allocate interrupt block state structure and link it to
	 * the pci state structure.
	 */
	ib_p = kmem_zalloc(sizeof (ib_t), KM_SLEEP);
	pci_p->pci_ib_p = ib_p;
	ib_p->ib_pci_p = pci_p;

	a = pci_ib_setup(ib_p);

	/*
	 * Determine virtual addresses of interrupt mapping, clear and diag
	 * registers that have common offsets.
	 */
	ib_p->ib_slot_clear_intr_regs =
	    a + COMMON_IB_SLOT_CLEAR_INTR_REG_OFFSET;
	ib_p->ib_intr_retry_timer_reg =
	    (uint64_t *)(a + COMMON_IB_INTR_RETRY_TIMER_OFFSET);
	ib_p->ib_slot_intr_state_diag_reg =
	    (uint64_t *)(a + COMMON_IB_SLOT_INTR_STATE_DIAG_REG);
	ib_p->ib_obio_intr_state_diag_reg =
	    (uint64_t *)(a + COMMON_IB_OBIO_INTR_STATE_DIAG_REG);

	if (CHIP_TYPE(pci_p) != PCI_CHIP_XMITS) {
		ib_p->ib_upa_imr[0] = (volatile uint64_t *)
		    (a + COMMON_IB_UPA0_INTR_MAP_REG_OFFSET);
		ib_p->ib_upa_imr[1] = (volatile uint64_t *)
		    (a + COMMON_IB_UPA1_INTR_MAP_REG_OFFSET);
	}

	DEBUG2(DBG_ATTACH, dip, "ib_create: slot_imr=%x, slot_cir=%x\n",
	    ib_p->ib_slot_intr_map_regs, ib_p->ib_obio_intr_map_regs);
	DEBUG2(DBG_ATTACH, dip, "ib_create: obio_imr=%x, obio_cir=%x\n",
	    ib_p->ib_slot_clear_intr_regs, ib_p->ib_obio_clear_intr_regs);
	DEBUG2(DBG_ATTACH, dip, "ib_create: upa0_imr=%x, upa1_imr=%x\n",
	    ib_p->ib_upa_imr[0], ib_p->ib_upa_imr[1]);
	DEBUG3(DBG_ATTACH, dip,
	    "ib_create: retry_timer=%x, obio_diag=%x slot_diag=%x\n",
	    ib_p->ib_intr_retry_timer_reg,
	    ib_p->ib_obio_intr_state_diag_reg,
	    ib_p->ib_slot_intr_state_diag_reg);

	ib_p->ib_ino_lst = (ib_ino_info_t *)NULL;
	mutex_init(&ib_p->ib_intr_lock, NULL, MUTEX_DRIVER, NULL);
	mutex_init(&ib_p->ib_ino_lst_mutex, NULL, MUTEX_DRIVER, NULL);

	DEBUG1(DBG_ATTACH, dip, "ib_create: numproxy=%x\n",
	    pci_p->pci_numproxy);
	for (i = 1; i <= pci_p->pci_numproxy; i++) {
		set_intr_mapping_reg(pci_p->pci_id,
		    (uint64_t *)ib_p->ib_upa_imr[i - 1], i);
	}

	ib_configure(ib_p);
	bus_func_register(BF_TYPE_RESINTR, ib_intr_reset, ib_p);
}
Example #25
0
/*
 *	Read from the SSL socket.  Safe with either blocking or
 *	non-blocking IO.  This level of complexity is probably not
 *	necessary, as each packet gets put into one SSL application
 *	record.  When SSL has a full record, we should be able to read
 *	the entire packet via one SSL_read().
 *
 *	When SSL has a partial record, SSL_read() will return
 *	WANT_READ or WANT_WRITE, and zero application data.
 *
 *	Called with the mutex held.
 */
static ssize_t proxy_tls_read(rad_listen_t *listener)
{
	int rcode;
	size_t length;
	uint8_t *data;
	listen_socket_t *sock = listener->data;

	if (!sock->ssn->connected) {
		rcode = try_connect(sock->ssn);
		if (rcode == 0) return 0;

		if (rcode < 0) {
			SSL_shutdown(sock->ssn->ssl);
			return -1;
		}

		sock->ssn->connected = true;
	}

	/*
	 *	Get the maximum size of data to receive.
	 */
	if (!sock->data) sock->data = talloc_array(sock, uint8_t,
						   sock->ssn->mtu);

	data = sock->data;

	if (sock->partial < 4) {
		rcode = SSL_read(sock->ssn->ssl, data + sock->partial,
				 4 - sock->partial);
		if (rcode <= 0) {
			int err = SSL_get_error(sock->ssn->ssl, rcode);
			switch (err) {
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
				return 0; /* do some more work later */

			case SSL_ERROR_ZERO_RETURN:
				/* remote end sent close_notify, send one back */
				SSL_shutdown(sock->ssn->ssl);
				/* FALL-THROUGH */

			case SSL_ERROR_SYSCALL:
			do_close:
				return -1;

			default:
				tls_error_log(NULL, "Failed in proxy receive");

				goto do_close;
			}
		}

		sock->partial = rcode;
	} /* try reading the packet header */

	if (sock->partial < 4) return 0; /* read more data */

	length = (data[2] << 8) | data[3];

	/*
	 *	Do these checks only once, when we read the header.
	 */
	if (sock->partial == 4) {
		DEBUG3("Proxy received header saying we have a packet of %u bytes",
		       (unsigned int) length);

		/*
		 *	FIXME: allocate a RADIUS_PACKET, and set
		 *	"data" to be as large as necessary.
		 */
		if (length > sock->ssn->mtu) {
			INFO("Received packet will be too large! Set \"fragment_size = %u\"",
			     (data[2] << 8) | data[3]);
			goto do_close;
		}
	}

	/*
	 *	Try to read some more.
	 */
	if (sock->partial < length) {
		rcode = SSL_read(sock->ssn->ssl, data + sock->partial,
				 length - sock->partial);
		if (rcode <= 0) {
			switch (SSL_get_error(sock->ssn->ssl, rcode)) {
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
				return 0;

			case SSL_ERROR_ZERO_RETURN:
				/* remote end sent close_notify, send one back */
				SSL_shutdown(sock->ssn->ssl);
				goto do_close;
			default:
				goto do_close;
			}
		}

		sock->partial += rcode;
	}

	/*
	 *	If we're not done, say so.
	 *
	 *	Otherwise, reset the partially read data flag, and say
	 *	we have a packet.
	 */
	if (sock->partial < length) {
		return 0;
	}

	sock->partial = 0;	/* we've now read the packet */
	return length;
}
Example #26
0
/*
 *	Add a client to the tree.
 */
int client_add(RADCLIENT_LIST *clients, RADCLIENT *client)
{
	RADCLIENT *old;
	char buffer[INET6_ADDRSTRLEN + 3];

	if (!client) {
		return 0;
	}

	/*
	 *	Hack to fixup wildcard clients
	 */
	if (is_wildcard(&client->ipaddr)) client->ipaddr.prefix = 0;

	fr_ntop(buffer, sizeof(buffer), &client->ipaddr);
	DEBUG3("Adding client %s (%s) to prefix tree %i", buffer, client->longname, client->ipaddr.prefix);

	/*
	 *	If "clients" is NULL, it means add to the global list.
	 */
	if (!clients) {
		/*
		 *	Initialize it, if not done already.
		 */
		if (!root_clients) {
			root_clients = clients_init(NULL);
			if (!root_clients) return 0;
		}
		clients = root_clients;
	}

	/*
	 *	Create a tree for it.
	 */
	if (!clients->trees[client->ipaddr.prefix]) {
		clients->trees[client->ipaddr.prefix] = rbtree_create(client_ipaddr_cmp, NULL, 0);
		if (!clients->trees[client->ipaddr.prefix]) {
			return 0;
		}
	}

#define namecmp(a) ((!old->a && !client->a) || (old->a && client->a && (strcmp(old->a, client->a) == 0)))

	/*
	 *	Cannot insert the same client twice.
	 */
	old = rbtree_finddata(clients->trees[client->ipaddr.prefix], client);
	if (old) {
		/*
		 *	If it's a complete duplicate, then free the new
		 *	one, and return "OK".
		 */
		if ((fr_ipaddr_cmp(&old->ipaddr, &client->ipaddr) == 0) &&
		    (old->ipaddr.prefix == client->ipaddr.prefix) &&
		    namecmp(longname) && namecmp(secret) &&
		    namecmp(shortname) && namecmp(nas_type) &&
		    namecmp(login) && namecmp(password) && namecmp(server) &&
#ifdef WITH_DYNAMIC_CLIENTS
		    (old->lifetime == client->lifetime) &&
		    namecmp(client_server) &&
#endif
#ifdef WITH_COA
		    namecmp(coa_name) &&
		    (old->coa_server == client->coa_server) &&
		    (old->coa_pool == client->coa_pool) &&
#endif
		    (old->message_authenticator == client->message_authenticator)) {
			WARN("Ignoring duplicate client %s", client->longname);
			client_free(client);
			return 1;
		}

		ERROR("Failed to add duplicate client %s",
		       client->shortname);
		return 0;
	}
#undef namecmp

	/*
	 *	Other error adding client: likely is fatal.
	 */
	if (!rbtree_insert(clients->trees[client->ipaddr.prefix], client)) {
		return 0;
	}

#ifdef WITH_STATS
	if (!tree_num) {
		tree_num = rbtree_create(client_num_cmp, NULL, 0);
	}

#ifdef WITH_DYNAMIC_CLIENTS
	/*
	 *	More catching of clients added by rlm_sql.
	 *
	 *	The sql modules sets the dynamic flag BEFORE calling
	 *	us.  The client_from_request() function sets it AFTER
	 *	calling us.
	 */
	if (client->dynamic && (client->lifetime == 0)) {
		RADCLIENT *network;

		/*
		 *	If there IS an enclosing network,
		 *	inherit the lifetime from it.
		 */
		network = client_find(clients, &client->ipaddr, client->proto);
		if (network) {
			client->lifetime = network->lifetime;
		}
	}
#endif

	client->number = tree_num_max;
	tree_num_max++;
	if (tree_num) rbtree_insert(tree_num, client);
#endif

	if (client->ipaddr.prefix < clients->min_prefix) {
		clients->min_prefix = client->ipaddr.prefix;
	}

	(void) talloc_steal(clients, client); /* reparent it */

	return 1;
}
Example #27
0
int proxy_tls_send(rad_listen_t *listener, REQUEST *request)
{
	int rcode;
	listen_socket_t *sock = listener->data;

	VERIFY_REQUEST(request);

	if ((listener->status != RAD_LISTEN_STATUS_INIT) &&
	    (listener->status != RAD_LISTEN_STATUS_KNOWN)) return 0;

	/*
	 *	Normal proxying calls us with the data already
	 *	encoded.  The "ping home server" code does not.  So,
	 *	if there's no packet, encode it here.
	 */
	if (!request->proxy->data) {
		request->proxy_listener->encode(request->proxy_listener,
						request);
	}

	if (!sock->ssn->connected) {
		PTHREAD_MUTEX_LOCK(&sock->mutex);
		rcode = try_connect(sock->ssn);
		PTHREAD_MUTEX_UNLOCK(&sock->mutex);
		if (rcode == 0) return 0;

		if (rcode < 0) {
			SSL_shutdown(sock->ssn->ssl);
			return -1;
		}

		sock->ssn->connected = true;
	}

	DEBUG3("Proxy is writing %u bytes to SSL",
	       (unsigned int) request->proxy->data_len);
	PTHREAD_MUTEX_LOCK(&sock->mutex);
	rcode = SSL_write(sock->ssn->ssl, request->proxy->data,
			  request->proxy->data_len);
	if (rcode < 0) {
		int err;

		err = ERR_get_error();
		switch (err) {
		case SSL_ERROR_NONE:
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			break;	/* let someone else retry */

		default:
			tls_error_log(NULL, "Failed in proxy send");
			DEBUG("Closing TLS socket to home server");
			tls_socket_close(listener);
			PTHREAD_MUTEX_UNLOCK(&sock->mutex);
			return 0;
		}
	}
	PTHREAD_MUTEX_UNLOCK(&sock->mutex);

	return 1;
}
Example #28
0
File: hxput.c Project: mischasan/hx
//--------------|---------------------------------------------
HXRET
hxput(HXFILE * hp, char const *recp, int leng)
{
    HXLOCAL loc, *locp = &loc;

    if (!hp || leng < 0 || !recp || leng > hxmaxrec(hp)
        || !(hp->mode & HX_UPDATE) || !hp->test)
        return HXERR_BAD_REQUEST;

    if (leng && !hx_test(hp, recp, leng))
        return HXERR_BAD_RECORD;

    if (SCANNING(hp) && hx_diff(hp, recp, RECDATA(_hxcurrec(hp))))
        return HXERR_BAD_REQUEST;

    ENTER(locp, hp, recp, 3);
    _hxlockset(locp, leng ? HIGH_LOCK : HEAD_LOCK);
    if (IS_MMAP(hp))
        _hxremap(locp);

    int     may_find = 1, loops = HX_MAX_CHAIN;
    int     newsize = leng ? leng + sizeof(HXREC) : 0;
    HXBUF  *currp = &locp->buf[0], *prevp = &locp->buf[1];

    // If scanning is on an overflow page, and hxdel might
    //  empty the page, hxput after hxnext can't just jump to
    //  the right page, because (prevp) is not loaded,
    //  so deleting currp would hard.
    _hxload(locp, currp, SCANNING(hp) && (leng || IS_HEAD(hp->buffer.pgno))
            ? hp->buffer.pgno : locp->head);

    while (1) {
        int     pos, hindpos, skip = 0;
        PAGENO  nextpg = currp->next;

        if (!--loops)
            LEAVE(locp, HXERR_BAD_FILE);

        // Search for the key (an old record to be deleted).
        // If SCANNING: the file is locked, and the matching
        //  record must be there.
        pos = !may_find ? -1
            : !SCANNING(hp) ? _hxfind(locp, currp, locp->hash, recp, &hindpos)
            : currp->pgno == hp->buffer.pgno ? hp->currpos : -1;

        if (pos >= 0) {
            char   *oldp = currp->data + pos;
            COUNT   oldsize = RECSIZE(oldp);
            int     delta = newsize - oldsize;

            locp->ret = RECLENG(oldp);
            may_find = 0;
            assert(!currp->delta);
            currp->delpos = pos;
            currp->delta = delta;

            if (!newsize) {     // hxdel or remove after inserted previously.

                _hxremove(currp, pos, oldsize);
                currp->recs--;
                if (SCANNING(hp))
                    hp->recsize = 0;

            } else if (FITS(hp, currp, delta, 0)) { // replace

                if (delta) {
                    memmove(oldp + newsize, oldp + oldsize,
                            currp->used - pos - oldsize);
                    currp->used += delta;
                    STSH(leng, oldp + sizeof(PAGENO));
                    if (SCANNING(hp))
                        hp->recsize = newsize;
                    DEINDEX(currp); // force indexify
                }

                memcpy(oldp + sizeof(HXREC), recp, leng);
                STAIN(currp);
                newsize = 0;

            } else if (SCANNING(hp)) {
                // At this point we are stuck: if we delete the old copy of
                // the record, we are committed to inserting the new copy
                // somewhere else, but that might require changing links
                // or even growing the file: a NO-NO during a hxnext scan.
                LEAVE(locp, HXERR_BAD_REQUEST);

            } else {            // Delete old version and continue (insert elsewhere).

                _hxremove(currp, pos, oldsize);
                currp->recs--;
            }
        }

        if (currp->used && !IS_HEAD(currp->pgno) && SHRUNK(prevp))
            skip = !_hxshift(locp, locp->head, 0, currp, prevp, NULL);

        // Insert the new record if it fits.
        if (newsize && FITS(hp, currp, newsize, 1)) {

            HXREC   hdr;

            STLG(locp->hash, &hdr.hash);
            STSH(leng, &hdr.leng);
            _hxappend(currp, (char *)&hdr, sizeof hdr);
            _hxappend(currp, recp, leng);
            currp->recs++;
            newsize = 0;
        }
        // If the current page contains only data of OTHER heads 
        // -- and hence, must be at the END of a chain --
        // unlink it from this chain. If the page is empty,
        // unlink it AND put it in the freemap.
        if (IS_HEAD(currp->pgno)) {
            skip = 0;
        } else if (!currp->used) {
            skip = 1;
            _hxputfreed(locp, currp);
            if (SCANNING(hp) && hp->buffer.pgno == currp->pgno)
                hp->buffer.used = 0;
        } else if (currp->next || !SHRUNK(currp)) {
            skip = 0;
        } else if (!skip) {     // If skip not set by _hxshift above...
            char const *rp, *ep;

            FOR_EACH_REC(rp, currp, ep)
                if (locp->head == _hxhead(locp, RECHASH(rp)))
                break;
            skip = rp == ep;    // No recs for locp->head in this tail.
        }
        if (skip)
            LINK(prevp, nextpg);
        else
            SWAP(prevp, currp);

        sync_save(locp, currp);

        if (!newsize && !prevp->next)
            break;

        if (!newsize && !may_find && !SHRUNK(prevp))
            break;

        if (prevp->next) {
            _hxload(locp, currp, prevp->next);
            continue;
        }
        // We are at the end of the chain, and rec not yet inserted.

        // Unlocking is necessary even if tail is not shared;
        //  it may be hp->tail.pgno in some other process.
        if (!FILE_HELD(hp) && !IS_HEAD(prevp->pgno))
            _hxunlock(locp, prevp->pgno, 1);

        // _hxshare/_hxfindfree may update the map (root etc).
        // Split MUST be locked before root, else risk deadlock.
        _hxlockset(locp, BOTH_LOCK);
        if (IS_MMAP(hp))
            _hxremap(locp);
        // At this point assert:
        // - head is locked, split is locked,
        // - head matches hash, npages matches filesize.
        // After locking the split, no other process can change
        // the file size.
        may_find = 0;
        COUNT   need = IS_HEAD(prevp->pgno) ? newsize : 0;

        if (!_hxshare(locp, currp, need)
            && !_hxgetfreed(locp, currp)
            && !_hxfindfree(locp, currp)) {

            // _hxgrow will zero samehead if it splits locp->head.
            PAGENO  samehead = locp->head;

            // _hxgrow will change the file length. A concurrent
            //  hxget/hxdel could miscalculate locp->head as
            //  being the newly-added page.
            _hxlock(locp, locp->npages, 0);
            _hxgrow(locp, currp, need, &samehead);
            DEBUG3("head=%u samehead=%u", locp->head, samehead);
            if (!samehead) {
                _hxputfreed(locp, currp);
                _hxpoint(locp);
                _hxload(locp, currp, locp->head);
                loops = HX_MAX_CHAIN;
                continue;
            }
        }
        // _hxgrow may clobber prevp, so we reload it. Even if
        // prevp->pgno == locp->head, prevp may contain an
        // obsolete copy of the head page. The empty page is
        // always appended to head. _hxshare only returns true
        // if currp is head and currp->next is 0, so it can't
        // clobber it. 

        _hxsave(locp, prevp);
        _hxload(locp, prevp, locp->head);
        LINK(currp, prevp->next);
        LINK(prevp, currp->pgno);
        currp->orig = DATASIZE(hp); // make SHRUNK be true
    }
Example #29
0
void
T3_Callback_2(int result, NdbConnection * pCON, void * threadData){
  ThreadData * td = (ThreadData *)threadData;
  
  if (result == -1) {
    CHECK_ALLOWED_ERROR("T3-2: execute", td, pCON->getNdbError());
    td->pNDB->closeTransaction(pCON);
    start_T3(td->pNDB, td, stat_async);
    return;
  }//if
  
  Uint32 permission = td->transactionData.permission;
  Uint32 sessions   = td->transactionData.sessions;
  Uint32 server_bit = td->transactionData.server_bit;

  if(((permission & server_bit) == server_bit) &&
     ((sessions   & server_bit) == server_bit)){
    
    memcpy(td->transactionData.suffix,
	   &td->transactionData.number[SFX_START],
	   SUBSCRIBER_NUMBER_SUFFIX_LENGTH);
    DEBUG5("T3(%.*s, %.2d): - Callback 2 - reading(%.*s)", 
	   SUBSCRIBER_NUMBER_LENGTH, 
	   td->transactionData.number, 
	   td->transactionData.server_id,
	   SUBSCRIBER_NUMBER_SUFFIX_LENGTH, 
	   td->transactionData.suffix);
    
    /* Operation 3 */
    NdbOperation * MyOp = pCON->getNdbOperation(SESSION_TABLE);
    CHECK_NULL(MyOp, "T3-3: getNdbOperation", td,
	       pCON->getNdbError());
    
    MyOp->simpleRead();
    MyOp->equal(IND_SESSION_SUBSCRIBER,
		(char*)td->transactionData.number);
    MyOp->equal(IND_SESSION_SERVER,
		(char*)&td->transactionData.server_id);
    MyOp->getValue(IND_SESSION_DATA, 
		   (char *)td->transactionData.session_details);
    
    /* Operation 4 */
    MyOp = pCON->getNdbOperation(SERVER_TABLE);
    CHECK_NULL(MyOp, "T3-4: getNdbOperation", td,
	       pCON->getNdbError());
    
    MyOp->interpretedUpdateTuple();
    MyOp->equal(IND_SERVER_ID,
		(char*)&td->transactionData.server_id);
    MyOp->equal(IND_SERVER_SUBSCRIBER_SUFFIX,
		(char*)td->transactionData.suffix);
    MyOp->incValue(IND_SERVER_READS, (uint32)1);
    td->transactionData.branchExecuted = 1;
  } else {
    DEBUG3("T3(%.*s, %.2d): - Callback 2 - no read",
	   SUBSCRIBER_NUMBER_LENGTH, 
	   td->transactionData.number, 
	   td->transactionData.server_id);
    td->transactionData.branchExecuted = 0;
  }
  if (stat_async == 1) {
    pCON->executeAsynchPrepare( Commit , T3_Callback_3, td);
  } else {
    int result = pCON->execute( Commit );
    T3_Callback_3(result, pCON, (void*)td);
    return;
  }//if
}
Example #30
0
/** Build a JSON object map from the configuration "map" section
 *
 * Parse the "map" section from the module configuration file and store this
 * as a JSON object (key/value list) in the module instance.  This map will be
 * used to lookup and map attributes for all incoming accounting requests.
 *
 * @param  conf     Configuration section.
 * @param  instance The module instance.
 * @return
 *	 - 0 on success.
 *	- -1 on failure.
 */
int mod_build_attribute_element_map(CONF_SECTION *conf, void *instance)
{
	rlm_couchbase_t *inst = instance;   /* our module instance */
	CONF_SECTION *cs;                   /* module config section */
	CONF_ITEM *ci;                      /* config item */
	CONF_PAIR *cp;                      /* conig pair */
	const char *attribute, *element;    /* attribute and element names */

	/* find update section */
	cs = cf_section_sub_find(conf, "update");

	/* backwards compatibility */
	if (!cs) {
		cs = cf_section_sub_find(conf, "map");
		WARN("rlm_couchbase: found deprecated 'map' section - please change to 'update'");
	}

	/* check section */
	if (!cs) {
		ERROR("rlm_couchbase: failed to find 'update' section in config");
		/* fail */
		return -1;
	}

	/* create attribute map object */
	inst->map = json_object_new_object();

	/* parse update section */
	for (ci = cf_item_find_next(cs, NULL); ci != NULL; ci = cf_item_find_next(cs, ci)) {
		/* validate item */
		if (!cf_item_is_pair(ci)) {
			ERROR("rlm_couchbase: failed to parse invalid item in 'update' section");
			/* free map */
			if (inst->map) {
				json_object_put(inst->map);
			}
			/* fail */
			return -1;
		}

		/* get value pair from item */
		cp = cf_item_to_pair(ci);

		/* get pair name (attribute name) */
		attribute = cf_pair_attr(cp);

		/* get pair value (element name) */
		element = cf_pair_value(cp);

		/* add pair name and value */
		json_object_object_add(inst->map, attribute, json_object_new_string(element));

		/* debugging */
		DEBUG3("rlm_couchbase: added attribute '%s' to element '%s' mapping", attribute, element);
	}

	/* debugging */
	DEBUG3("rlm_couchbase: built attribute to element mapping %s", json_object_to_json_string(inst->map));

	/* return */
	return 0;
}