Esempio n. 1
0
/*
 *   logoff(msg): traegt einen wartenden LOGOFF: Header mit der <msg> ein,
 *		  der gesendet wird, sobald im ping-pong Platz dafuer ist.
 *		  "auflegen" wird gesetzt, "auflegen_gesendet" erst, wenn der
 *		  Header wirklich verschickt wurde.
 */
void
logoff(const char *msg)
{
	auflegen = 1;
	auflegen_gesendet = 0;
	auflegen_msg = dstrdup(msg);
}
Esempio n. 2
0
/*
 * Look up the FMRI corresponding to the node in the global
 * hash table and return the pointer stored (if any).  Save the
 * FMRI string in *str if str is non-NULL.
 */
static void *
fmri2ptr(topo_hdl_t *thp, tnode_t *node, char **str, int *err)
{
	nvlist_t	*fmri = NULL;
	char		*cstr = NULL;
	uint64_t	u64val;
	void		*p = NULL;

	if (topo_node_resource(node, &fmri, err) != 0)
		return (NULL);

	if (topo_fmri_nvl2str(thp, fmri, &cstr, err) != 0) {
		nvlist_free(fmri);
		return (NULL);
	}

	if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &u64val) == 0) {

		p = (void *)(uintptr_t)u64val;
	}

	nvlist_free(fmri);
	if (str != NULL)
		*str = dstrdup(cstr);
	topo_hdl_strfree(thp, cstr);
	return (p);
}
Esempio n. 3
0
static dm_plugin_t *
new_dm_plugin(const char *protocol)
{
	dm_plugin_t *newpi = (dm_plugin_t *)dmalloc(sizeof (dm_plugin_t));

	newpi->protocol = dstrdup(protocol);
	newpi->state = DMPS_NONE;
	newpi->ops = NULL;
	newpi->next = NULL;

	return (newpi);
}
Esempio n. 4
0
int init_track(const char *pattern)
{
	int i, j, pat_nr;

	/* Suche ein leeres Pattern */
	for (pat_nr = 0; pat_nr < last_track; pat_nr++) {
		if (pat[pat_nr] == NULL)
			break;
	}

	/* Es war kein leeres Pattern zwischendrin frei */
	if (pat_nr >= last_track) {
		if (last_track <= MAXTRACKS) {
			last_track++;
		} else {
			return -1;
		}
	}

	/* Suchstring merken */
	pat[pat_nr] = dstrdup(pattern);
	m[pat_nr] = strlen(pattern);

	/* procedure initnext, Sedgewick p. 282 */
	i = 0; j = -1; next[pat_nr][0] = -1;
	do {
		if ((j<0) || (pattern[i] == pattern[j])) {
			i++;
			j++;
			if (pattern[i] != pattern[j])
				next[pat_nr][i] = j;
			else
				next[pat_nr][i] = next[pat_nr][j];
		} else {
			j = next[pat_nr][j];
		}
	} while (i <= m[pat_nr]);

	for (i = 0; i <= m[pat_nr]; i++)
		if (next[pat_nr][i] < 0)
			next[pat_nr][i] = 0;

	/* Position im String auf Stringanfang setzen */
	gj[pat_nr] = 0;

	return pat_nr;
}
Esempio n. 5
0
static dm_plugin_action_handle_impl_t *
new_action_handle(const char *action, dm_plugin_t *pluginp)
{
	dm_plugin_action_handle_impl_t *hip;

	hip = (dm_plugin_action_handle_impl_t *)dmalloc(
	    sizeof (dm_plugin_action_handle_impl_t));

	hip->actionString = dstrdup(action);
	hip->plugin = pluginp;
	hip->handle = (dm_plugin_action_handle_t)NULL;

	/* Add the handle to the global list */
	dm_assert(pthread_mutex_lock(&handle_list_mutex) == 0);
	hip->next = handle_list;
	handle_list = hip;
	dm_assert(pthread_mutex_unlock(&handle_list_mutex) == 0);

	return (hip);
}
Esempio n. 6
0
File: main.c Progetto: ajdavis/mongo
static void
uri_init(void)
{
	WT_CURSOR *cursor;
	WT_SESSION *session;
	u_int i, key;
	char buf[128];

	for (i = 0; i < uris; ++i)
		if (uri_list[i] == NULL) {
			testutil_check(
			    __wt_snprintf(buf, sizeof(buf), "table:%u", i));
			uri_list[i] = dstrdup(buf);
		}

	testutil_check(conn->open_session(conn, NULL, NULL, &session));

	/* Initialize the file contents. */
	for (i = 0; i < uris; ++i) {
		testutil_check(__wt_snprintf(buf, sizeof(buf),
		    "key_format=S,value_format=S,"
		    "allocation_size=4K,leaf_page_max=32KB,"));
		testutil_check(session->create(session, uri_list[i], buf));
		testutil_check(session->open_cursor(
		    session, uri_list[i], NULL, NULL, &cursor));
		for (key = 1; key < MAXKEY; ++key) {
			testutil_check(__wt_snprintf(
			    buf, sizeof(buf), "key:%020u", key));
			cursor->set_key(cursor, buf);
			cursor->set_value(cursor, buf);
			testutil_check(cursor->insert(cursor));
		}
		testutil_check(cursor->close(cursor));
	}

	/* Create a checkpoint we can use for readonly handles. */
	testutil_check(session->checkpoint(session, NULL));

	testutil_check(session->close(session, NULL));
}
Esempio n. 7
0
static int
topo_add_bay(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp)
{
	diskmon_t *target_diskp = wdp->target;
	nvlist_t	*nvlp = find_disk_monitor_private_pgroup(node);
	nvlist_t	*prop_nvlp;
	nvpair_t	*nvp = NULL;
	char		*prop_name, *prop_value;
#define	PNAME_MAX 128
	char		pname[PNAME_MAX];
	char		msgbuf[MAX_CONF_MSG_LEN];
	char		*indicator_name, *indicator_action;
	char		*indrule_states, *indrule_actions;
	int		err = 0, i;
	conf_err_t	conferr;
	boolean_t	conf_failure = B_FALSE;
	char		*unadj_physid = NULL;
	char		physid[MAXPATHLEN];
	char		*label;
	nvlist_t	*diskprops = NULL;
	char		*cstr = NULL;
	indicator_t	*indp = NULL;
	indrule_t	*indrp = NULL;
	void		*p;
	diskmon_t	*diskp;
	void		*ptr;

	/* No private properties -- just ignore the port */
	if (nvlp == NULL)
		return (0);

	/*
	 * Look for a diskmon based on this node's FMRI string.
	 * Once a diskmon has been created, it's not re-created.  This is
	 * essential for the times when the tree-walk is called after a
	 * disk is inserted (or removed) -- in that case, the disk node
	 * handler simply updates the FRU information in the diskmon.
	 */
	if ((p = fmri2ptr(thp, node, &cstr, &err)) != NULL) {

		diskp = (diskmon_t *)p;

		/*
		 * Delete the FRU information from the diskmon.  If a disk
		 * is connected, its FRU information will be refreshed by
		 * the disk node code.
		 */
		if (diskp->frup && (target_diskp == NULL ||
		    diskp == target_diskp)) {
			dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
			dmfru_free(diskp->frup);
			diskp->frup = NULL;
			dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);
		}

		wdp->pfmri = cstr;
		nvlist_free(nvlp);
		return (0);
	}

	/*
	 * Determine the physical path to the attachment point
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO,
	    TOPO_IO_AP_PATH, &unadj_physid, &err) == 0) {

		adjust_dynamic_ap(unadj_physid, physid);
		topo_hdl_strfree(thp, unadj_physid);
	} else {

		/* unadj_physid cannot have been allocated */
		if (cstr)
			dstrfree(cstr);
		nvlist_free(nvlp);
		return (-1);
	}

	/*
	 */

	/*
	 * Process the properties.  If we encounter a property that
	 * is not an indicator name, action, or rule, add it to the
	 * disk's props list.
	 */

	/* Process indicators */
	i = 0;
	indicator_name = NULL;
	indicator_action = NULL;
	do {
		if (indicator_name != NULL && indicator_action != NULL) {

			if (topoprop_indicator_add(&indp, indicator_name,
			    indicator_action) != 0) {

				conf_failure = B_TRUE;
			}

			topo_hdl_strfree(thp, indicator_name);
			topo_hdl_strfree(thp, indicator_action);
		}

		(void) snprintf(pname, PNAME_MAX, BAY_IND_NAME "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indicator_name, &err) != 0)
			break;

		(void) snprintf(pname, PNAME_MAX, BAY_IND_ACTION "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indicator_action, &err) != 0)
			break;

		i++;
	} while (!conf_failure && indicator_name != NULL &&
	    indicator_action != NULL);

	if (!conf_failure && indp != NULL &&
	    (conferr = check_inds(indp)) != E_NO_ERROR) {
		conf_error_msg(conferr, msgbuf, MAX_CONF_MSG_LEN, NULL);
		log_msg(MM_CONF, "%s: Not adding disk to list\n", msgbuf);
		conf_failure = B_TRUE;
	}

	/* Process state rules and indicator actions */
	i = 0;
	indrule_states = NULL;
	indrule_actions = NULL;
	do {
		if (indrule_states != NULL && indrule_actions != NULL) {

			if (topoprop_indrule_add(&indrp, indrule_states,
			    indrule_actions) != 0) {

				conf_failure = B_TRUE;
			}

			topo_hdl_strfree(thp, indrule_states);
			topo_hdl_strfree(thp, indrule_actions);
		}

		(void) snprintf(pname, PNAME_MAX, BAY_INDRULE_STATES "-%d", i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indrule_states, &err) != 0)
			break;

		(void) snprintf(pname, PNAME_MAX, BAY_INDRULE_ACTIONS "-%d",
		    i);
		if (topo_prop_get_string(node, DISK_MONITOR_PROPERTIES,
		    pname, &indrule_actions, &err) != 0)
			break;

		i++;
	} while (!conf_failure && indrule_states != NULL &&
	    indrule_actions != NULL);

	if (!conf_failure && indrp != NULL && indp != NULL &&
	    ((conferr = check_indrules(indrp, (state_transition_t **)&ptr))
	    != E_NO_ERROR ||
	    (conferr = check_consistent_ind_indrules(indp, indrp,
	    (ind_action_t **)&ptr)) != E_NO_ERROR)) {

		conf_error_msg(conferr, msgbuf, MAX_CONF_MSG_LEN, ptr);
		log_msg(MM_CONF, "%s: Not adding disk to list\n", msgbuf);
		conf_failure = B_TRUE;

	}

	/*
	 * Now collect miscellaneous properties.
	 * Each property is stored as an embedded nvlist named
	 * TOPO_PROP_VAL.  The property name is stored in the value for
	 * key=TOPO_PROP_VAL_NAME and the property's value is
	 * stored in the value for key=TOPO_PROP_VAL_VAL.  This is all
	 * necessary so we can subtractively decode the properties that
	 * we do not directly handle (so that these properties are added to
	 * the per-disk properties nvlist), increasing flexibility.
	 */
	(void) nvlist_alloc(&diskprops, NV_UNIQUE_NAME, 0);
	while ((nvp = nvlist_next_nvpair(nvlp, nvp)) != NULL) {
		/* Only care about embedded nvlists named TOPO_PROP_VAL */
		if (nvpair_type(nvp) != DATA_TYPE_NVLIST ||
		    strcmp(nvpair_name(nvp), TOPO_PROP_VAL) != 0 ||
		    nvpair_value_nvlist(nvp, &prop_nvlp) != 0)
			continue;

		if (nonunique_nvlist_lookup_string(prop_nvlp,
		    TOPO_PROP_VAL_NAME, &prop_name) != 0)
			continue;

		/* Filter out indicator properties */
		if (strstr(prop_name, BAY_IND_NAME) != NULL ||
		    strstr(prop_name, BAY_IND_ACTION) != NULL ||
		    strstr(prop_name, BAY_INDRULE_STATES) != NULL ||
		    strstr(prop_name, BAY_INDRULE_ACTIONS) != NULL)
			continue;

		if (nonunique_nvlist_lookup_string(prop_nvlp, TOPO_PROP_VAL_VAL,
		    &prop_value) != 0)
			continue;

		/* Add the property to the disk's prop list: */
		if (nvlist_add_string(diskprops, prop_name, prop_value) != 0)
			log_msg(MM_TOPO,
			    "Could not add disk property `%s' with "
			    "value `%s'\n", prop_name, prop_value);
	}

	nvlist_free(nvlp);

	if (cstr != NULL) {
		namevalpr_t nvpr;
		nvlist_t *dmap_nvl;

		nvpr.name = DISK_AP_PROP_APID;
		nvpr.value = strncmp(physid, "/devices", 8) == 0 ?
		    (physid + 8) : physid;

		/*
		 * Set the diskmon's location to the value in this port's label.
		 * If there's a disk plugged in, the location will be updated
		 * to be the disk label (e.g. HD_ID_00).  Until a disk is
		 * inserted, though, there won't be a disk libtopo node
		 * created.
		 */

		/* Pass physid without the leading "/devices": */
		dmap_nvl = namevalpr_to_nvlist(&nvpr);

		diskp = new_diskmon(dmap_nvl, indp, indrp, diskprops);

		if (topo_node_label(node, &label, &err) == 0) {
			diskp->location = dstrdup(label);
			topo_hdl_strfree(thp, label);
		} else
			diskp->location = dstrdup("unknown location");

		if (!conf_failure && diskp != NULL) {
			/* Add this diskmon to the disk list */
			cfgdata_add_diskmon(config_data, diskp);
			if (nvlist_add_uint64(g_topo2diskmon, cstr,
			    (uint64_t)(uintptr_t)diskp) != 0) {
				log_msg(MM_TOPO,
				    "Could not add pointer to nvlist "
				    "for `%s'!\n", cstr);
			}
		} else if (diskp != NULL) {
			diskmon_free(diskp);
		} else {
			if (dmap_nvl)
				nvlist_free(dmap_nvl);
			if (indp)
				ind_free(indp);
			if (indrp)
				indrule_free(indrp);
			if (diskprops)
				nvlist_free(diskprops);
		}

		wdp->pfmri = cstr;
	}


	return (0);
}
Esempio n. 8
0
static int
topoprop_indrule_add(indrule_t **indrp, char *sts, char *acts)
{
	ind_action_t		*indactp = NULL;
	ind_state_t		state;
	char			*name, *lasts, *p;
	int			stateslen = strlen(sts) + 1;
	int			actionslen = strlen(acts) + 1;
	char			*states = dstrdup(sts);
	char			*actions = dstrdup(acts);
	state_transition_t	strans;
	boolean_t		failed = B_FALSE;
	conf_err_t		err;
	char			msgbuf[MAX_CONF_MSG_LEN];

	/* The state string is of the form "{STATE}>{STATE}" */
	p = strchr(states, '>');
	dm_assert(p != NULL);
	*p = 0;
	strans.begin = str2dmstate(states);
	*p = '>';
	strans.end = str2dmstate(p + 1);

	if (strans.begin == HPS_UNKNOWN || strans.end == HPS_UNKNOWN) {
		log_msg(MM_CONF, "Invalid states property `%s'\n", sts);
		failed = B_TRUE;
	} else if ((err = check_state_transition(strans.begin, strans.end))
	    != E_NO_ERROR) {
		conf_error_msg(err, msgbuf, MAX_CONF_MSG_LEN, &strans);
		log_msg(MM_CONF, "%s: Not adding disk to list!\n", msgbuf);
		failed = B_TRUE;
	}

	/* Actions are of the form "{ACTION}[&{ACTION}]" */
	if (!failed && (p = strtok_r(actions, "&", &lasts)) != NULL) {
		/* At least 2 tokens */
		do {
			if (indicator_breakup(p, &state, &name) != 0) {
				failed = B_TRUE;
				break;
			}

			link_indaction(&indactp, new_indaction(state, name));

		} while ((p = strtok_r(NULL, "&", &lasts)) != NULL);
	} else if (!failed) {
		/* One token */
		if (indicator_breakup(actions, &state, &name) != 0)
			return (-1);
		indactp = new_indaction(state, name);
	}

	dfree(states, stateslen);
	dfree(actions, actionslen);

	if (!failed && (err = check_indactions(indactp)) != E_NO_ERROR) {
		conf_error_msg(err, msgbuf, MAX_CONF_MSG_LEN, NULL);
		log_msg(MM_CONF, "%s: Not adding disk to list!\n", msgbuf);
		failed = B_TRUE;
	}

	if (failed) {
		indaction_free(indactp);
		return (-1);
	} else
		link_indrule(indrp, new_indrule(&strans, indactp));
	return (0);
}
Esempio n. 9
0
static int
topo_add_disk(topo_hdl_t *thp, tnode_t *node, walk_diskmon_t *wdp)
{
	diskmon_t *target_diskp = wdp->target;
	char		*devpath = NULL;
	char		*capacity = NULL;
	char		*firmrev = NULL;
	char		*serial = NULL;
	char		*manuf = NULL;
	char		*model = NULL;
	char		*label;
	uint64_t	ptr = 0;
	int		err;
	dm_fru_t	*frup;
	diskmon_t	*diskp;

	if (wdp->pfmri == NULL) {
		log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node);
		return (0);
	}

	if (nvlist_lookup_uint64(g_topo2diskmon, wdp->pfmri, &ptr) != 0) {
		log_msg(MM_TOPO, "No diskmon for %s: parent of node %p.\n",
		    wdp->pfmri, node);
		dstrfree(wdp->pfmri);
		/* Skip this disk: */
		return (0);
	}

	dstrfree(wdp->pfmri);
	wdp->pfmri = NULL;

	diskp = (diskmon_t *)(uintptr_t)ptr;

	/* If we were called upon to update a particular disk, do it */
	if (target_diskp != NULL && diskp != target_diskp) {
		return (0);
	}

	/*
	 * Update the diskmon's location field with the disk's label
	 */
	if (diskp->location)
		dstrfree(diskp->location);
	if (topo_node_label(node, &label, &err) == 0) {
		diskp->location = dstrdup(label);
		topo_hdl_strfree(thp, label);
	} else
		diskp->location = dstrdup("unknown location");

	/*
	 * Check for a device path property (if the disk is configured,
	 * it will be present) and add it to the diskmon's properties)
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
	    &devpath, &err) == 0) {
		char devp[PATH_MAX];
		/*
		 * Consumers of the DISK_PROP_DEVPATH property expect a raw
		 * minor device node
		 */
		(void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath);
		(void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH,
		    devp);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the logical disk node, if it exists
	 */
	if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) {
		(void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME,
		    devpath);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the FRU information (if present in the node) to the diskmon's
	 * fru data structure:
	 */
	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MODEL, &model, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MANUFACTURER, &manuf, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_SERIAL_NUM, &serial, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_CAPACITY, &capacity, &err);

	frup = new_dmfru(manuf, model, firmrev, serial,
	    capacity == NULL ? 0 : strtoull(capacity, 0, 0));

	if (model)
		topo_hdl_strfree(thp, model);
	if (manuf)
		topo_hdl_strfree(thp, manuf);
	if (serial)
		topo_hdl_strfree(thp, serial);
	if (firmrev)
		topo_hdl_strfree(thp, firmrev);
	if (capacity)
		topo_hdl_strfree(thp, capacity);

	/* Add the fru information to the diskmon: */
	dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
	dm_assert(diskp->frup == NULL);
	diskp->frup = frup;
	dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);

	return (0);
}
Esempio n. 10
0
File: util.c Progetto: Machyne/mongo
/*
 * path_setup --
 *	Build the standard paths and shell commands we use.
 */
void
path_setup(const char *home)
{
	size_t len;

	/* Home directory. */
	g.home = dstrdup(home == NULL ? "RUNDIR" : home);

	/* Log file. */
	len = strlen(g.home) + strlen("log") + 2;
	g.home_log = dmalloc(len);
	snprintf(g.home_log, len, "%s/%s", g.home, "log");

	/* RNG log file. */
	len = strlen(g.home) + strlen("rand") + 2;
	g.home_rand = dmalloc(len);
	snprintf(g.home_rand, len, "%s/%s", g.home, "rand");

	/* Run file. */
	len = strlen(g.home) + strlen("CONFIG") + 2;
	g.home_config = dmalloc(len);
	snprintf(g.home_config, len, "%s/%s", g.home, "CONFIG");

	/* Statistics file. */
	len = strlen(g.home) + strlen("stats") + 2;
	g.home_stats = dmalloc(len);
	snprintf(g.home_stats, len, "%s/%s", g.home, "stats");

	/* BDB directory. */
	len = strlen(g.home) + strlen("bdb") + 2;
	g.home_bdb = dmalloc(len);
	snprintf(g.home_bdb, len, "%s/%s", g.home, "bdb");

	/*
	 * Home directory initialize command: create the directory if it doesn't
	 * exist, else remove everything except the RNG log file, create the KVS
	 * subdirectory.
	 *
	 * Redirect the "cd" command to /dev/null so chatty cd implementations
	 * don't add the new working directory to our output.
	 */
#undef	CMD
#ifdef _WIN32
#define	CMD  "del /q rand.copy & " \
	     "(IF EXIST %s\\rand copy /y %s\\rand rand.copy) & "	\
	     "(IF EXIST %s rd /s /q %s) & mkdir %s & "			\
	     "(IF EXIST rand.copy copy rand.copy %s\\rand) & " \
	     "cd %s & mkdir KVS"
	len = strlen(g.home) * 7 + strlen(CMD) + 1;
	g.home_init = dmalloc(len);
	snprintf(g.home_init, len, CMD,
	    g.home, g.home, g.home, g.home, g.home, g.home, g.home);
#else
#define	CMD	"test -e %s || mkdir %s; "				\
		"cd %s > /dev/null && rm -rf `ls | sed /rand/d`; "	\
		"mkdir KVS"
	len = strlen(g.home) * 3 + strlen(CMD) + 1;
	g.home_init = dmalloc(len);
	snprintf(g.home_init, len, CMD, g.home, g.home, g.home);
#endif

	/* Primary backup directory. */
	len = strlen(g.home) + strlen("BACKUP") + 2;
	g.home_backup = dmalloc(len);
	snprintf(g.home_backup, len, "%s/%s", g.home, "BACKUP");

	/*
	 * Backup directory initialize command, remove and re-create the primary
	 * backup directory, plus a copy we maintain for recovery testing.
	 */
#undef	CMD
#ifdef _WIN32
#define	CMD	"rd /s /q %s\\%s %s\\%s & mkdir %s\\%s %s\\%s"
#else
#define	CMD	"rm -rf %s/%s %s/%s && mkdir %s/%s %s/%s"
#endif
	len = strlen(g.home) * 4 +
	    strlen("BACKUP") * 2 + strlen("BACKUP_COPY") * 2 + strlen(CMD) + 1;
	g.home_backup_init = dmalloc(len);
	snprintf(g.home_backup_init, len, CMD,
	    g.home, "BACKUP", g.home, "BACKUP_COPY",
	    g.home, "BACKUP", g.home, "BACKUP_COPY");

	/*
	 * Salvage command, save the interesting files so we can replay the
	 * salvage command as necessary.
	 *
	 * Redirect the "cd" command to /dev/null so chatty cd implementations
	 * don't add the new working directory to our output.
	 */
#undef	CMD
#ifdef _WIN32
#define	CMD								\
	"cd %s && "							\
	"rd /q /s slvg.copy & mkdir slvg.copy && "			\
	"copy WiredTiger* slvg.copy\\ >:nul && copy wt* slvg.copy\\ >:nul"
#else
#define	CMD								\
	"cd %s > /dev/null && "						\
	"rm -rf slvg.copy && mkdir slvg.copy && "			\
	"cp WiredTiger* wt* slvg.copy/"
#endif
	len = strlen(g.home) + strlen(CMD) + 1;
	g.home_salvage_copy = dmalloc(len);
	snprintf(g.home_salvage_copy, len, CMD, g.home);
}
Esempio n. 11
0
static int
topo_add_disk(topo_hdl_t *thp, tnode_t *node, diskmon_t *target_diskp)
{
	nvlist_t	*fmri = NULL;
	nvlist_t	*asru_fmri;
	nvlist_t	*fru_fmri;
	char		*devpath = NULL;
	char		*capacity = NULL;
	char		*firmrev = NULL;
	char		*serial = NULL;
	char		*manuf = NULL;
	char		*model = NULL;
	char		*cstr = NULL;
	char		*buf;
	char		*label;
	char		*p;
	uint64_t	ptr = 0;
	int		buflen;
	int		err;
	int		orig_cstr_len;
	dm_fru_t	*frup;
	diskmon_t	*diskp;

	/*
	 * Match this node to a disk in the configuration by looking at
	 * our parent's fmri (and do that by getting our FMRI and chopping
	 * off the last part).
	 */
	if (topo_node_resource(node, &fmri, &err) != 0) {
		log_msg(MM_TOPO, "topo_add_disk: Could not generate FMRI for "
		    "node %p!\n", (void *)node);
		return (-1);
	}

	if (topo_fmri_nvl2str(thp, fmri, &cstr, &err) != 0) {
		log_msg(MM_TOPO, "topo_add_disk: Could not create string for "
		    "node %p's FMRI!\n", (void *)node);
		nvlist_free(fmri);
		return (-1);
	}

	nvlist_free(fmri);

	/*
	 * Chop off all but last path (since there's no way to get
	 * the node's parent in the libtopo API).
	 */
	orig_cstr_len = strlen(cstr) + 1;
	p = strrchr(cstr, '/');
	dm_assert(p != NULL);
	*p = 0;
	if (nvlist_lookup_uint64(g_topo2diskmon, cstr, &ptr) != 0) {
		log_msg(MM_TOPO, "No diskmon for parent of node %p.\n", node);
		topo_hdl_free(thp, cstr, orig_cstr_len);
		/* Skip this disk: */
		return (0);
	}

	topo_hdl_free(thp, cstr, orig_cstr_len);

	diskp = (diskmon_t *)(uintptr_t)ptr;

	/* If we were called upon to update a particular disk, do it */
	if (target_diskp != NULL && diskp != target_diskp) {
		return (0);
	}

	/*
	 * Update the diskmon's ASRU and FRU with our information (this
	 * information is cached in the diskmon so we don't have to do a
	 * time-consuming topo traversal when we get an ereport).
	 */
	if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_ASRU,
	    &asru_fmri, &err) == 0) {
		diskmon_add_asru(diskp, asru_fmri);
		nvlist_free(asru_fmri);
	}
	if (topo_prop_get_fmri(node, TOPO_PGROUP_PROTOCOL, TOPO_PROP_FRU,
	    &fru_fmri, &err) == 0) {
		diskmon_add_fru(diskp, fru_fmri);
		nvlist_free(fru_fmri);
	}
	if (topo_node_resource(node, &fmri, &err) == 0) {
		diskmon_add_disk_fmri(diskp, fmri);
		nvlist_free(fmri);
	}

	/*
	 * Update the diskmon's location field with the disk's label
	 */
	if (diskp->location)
		dstrfree(diskp->location);
	if (topo_node_label(node, &label, &err) == 0) {
		diskp->location = dstrdup(label);
		topo_hdl_strfree(thp, label);
	} else
		diskp->location = dstrdup("unknown location");

	/*
	 * Check for a device path property (if the disk is configured,
	 * it will be present) and add it to the diskmon's properties)
	 */
	if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV_PATH,
	    &devpath, &err) == 0) {
		char devp[PATH_MAX];
		/*
		 * Consumers of the DISK_PROP_DEVPATH property expect a raw
		 * minor device node
		 */
		(void) snprintf(devp, PATH_MAX, "%s:q,raw", devpath);
		(void) nvlist_add_string(diskp->props, DISK_PROP_DEVPATH,
		    devp);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the logical disk node, if it exists
	 */
	if (topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_LOGICAL_DISK_NAME, &devpath, &err) == 0) {
		(void) nvlist_add_string(diskp->props, DISK_PROP_LOGNAME,
		    devpath);
		topo_hdl_strfree(thp, devpath);
	}

	/*
	 * Add the FRU information (if present in the node) to the diskmon's
	 * fru data structure:
	 */
	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MODEL, &model, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_MANUFACTURER, &manuf, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_SERIAL_NUM, &serial, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_FIRMWARE_REV, &firmrev, &err);

	(void) topo_prop_get_string(node, TOPO_STORAGE_PGROUP,
	    TOPO_STORAGE_CAPACITY, &capacity, &err);

	frup = new_dmfru(manuf, model, firmrev, serial,
	    capacity == NULL ? 0 : strtoull(capacity, 0, 0));

	/*
	 * Update the disk's resource FMRI with the
	 * SunService-required members:
	 * FM_FMRI_HC_SERIAL_ID, FM_FMRI_HC_PART, and
	 * FM_FMRI_HC_REVISION
	 */
	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_SERIAL_ID, serial);

	transform_model_string(manuf, model, &buf, &buflen);

	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_PART, buf);

	/*
	 * Add the serial number to the ASRU so that when the resource
	 * is marked faulty in the fmd resource cache, the hc scheme
	 * plugin can detect when the disk is no longer installed (and so,
	 * can clear the faulty state automatically across fmd restarts).
	 *
	 * The serial number is only updated when a disk comes online
	 * because that's when the disk node exists in the topo tree.
	 * It's ok to keep a stale value in the ASRU when the disk is removed
	 * because it's only used as part of fault creation when the disk
	 * is configured (online), at which point it will be updated with
	 * the (current) serial number of the disk inserted.
	 */
	(void) nvlist_add_string(diskp->asru_fmri,
	    FM_FMRI_HC_SERIAL_ID, serial);

	dfree(buf, buflen);

	(void) nvlist_add_string(diskp->disk_res_fmri,
	    FM_FMRI_HC_REVISION, firmrev);

	if (model) {
		topo_hdl_strfree(thp, model);
	}

	if (manuf) {
		topo_hdl_strfree(thp, manuf);
	}

	if (serial) {
		topo_hdl_strfree(thp, serial);
	}

	if (firmrev) {
		topo_hdl_strfree(thp, firmrev);
	}

	if (capacity) {
		topo_hdl_strfree(thp, capacity);
	}

	/* Add the fru information to the diskmon: */
	dm_assert(pthread_mutex_lock(&diskp->fru_mutex) == 0);
	dm_assert(diskp->frup == NULL);
	diskp->frup = frup;
	dm_assert(pthread_mutex_unlock(&diskp->fru_mutex) == 0);

	return (0);
}
Esempio n. 12
0
/*
 * testutil_parse_opts --
 *    Parse command line options for a test case.
 */
int
testutil_parse_opts(int argc, char * const *argv, TEST_OPTS *opts)
{
	int ch;
	size_t len;

	opts->preserve = false;
	opts->running = true;
	opts->verbose = false;

	opts->progname = testutil_set_progname(argv);

	while ((ch = __wt_getopt(opts->progname,
		argc, argv, "A:h:n:o:pR:T:t:vW:")) != EOF)
		switch (ch) {
		case 'A': /* Number of append threads */
			opts->n_append_threads = (uint64_t)atoll(__wt_optarg);
			break;
		case 'h': /* Home directory */
			opts->home = dstrdup(__wt_optarg);
			break;
		case 'n': /* Number of records */
			opts->nrecords = (uint64_t)atoll(__wt_optarg);
			break;
		case 'o': /* Number of operations */
			opts->nops = (uint64_t)atoll(__wt_optarg);
			break;
		case 'p': /* Preserve directory contents */
			opts->preserve = true;
			break;
		case 'R': /* Number of reader threads */
			opts->n_read_threads = (uint64_t)atoll(__wt_optarg);
			break;
		case 'T': /* Number of threads */
			opts->nthreads = (uint64_t)atoll(__wt_optarg);
			break;
		case 't': /* Table type */
			switch (__wt_optarg[0]) {
			case 'C':
			case 'c':
				opts->table_type = TABLE_COL;
				break;
			case 'F':
			case 'f':
				opts->table_type = TABLE_FIX;
				break;
			case 'R':
			case 'r':
				opts->table_type = TABLE_ROW;
				break;
			}
			break;
		case 'v':
			opts->verbose = true;
			break;
		case 'W': /* Number of writer threads */
			opts->n_write_threads = (uint64_t)atoll(__wt_optarg);
			break;
		case '?':
		default:
			(void)fprintf(stderr, "usage: %s "
			    "[-A append thread count] "
			    "[-h home] "
			    "[-n record count] "
			    "[-o op count] "
			    "[-p] "
			    "[-R read thread count] "
			    "[-T thread count] "
			    "[-t c|f|r table type] "
			    "[-v] "
			    "[-W write thread count] ",
			    opts->progname);
			return (1);
		}

	/*
	 * Setup the home directory if not explicitly specified. It needs to be
	 * unique for every test or the auto make parallel tester gets upset.
	 */
	if (opts->home == NULL) {
		len = strlen("WT_TEST.")  + strlen(opts->progname) + 10;
		opts->home = dmalloc(len);
		testutil_check(__wt_snprintf(
		    opts->home, len, "WT_TEST.%s", opts->progname));
	}

	/* Setup the default URI string */
	len = strlen("table:") + strlen(opts->progname) + 10;
	opts->uri = dmalloc(len);
	testutil_check(__wt_snprintf(
	    opts->uri, len, "table:%s", opts->progname));

	return (0);
}
Esempio n. 13
0
int
anruf( header_p sys, header_p ich, int lmodem, int tries )
{
	char dialstr[80];
	char lockname[FILENAME_MAX];
	header_p p;
	char *name, *pw;
	const char **v;
	int i, err;
	int dial_cnt = 1;

	/* fuer Janus */
	char *arcer=NULL, *arcerin=NULL, *transfer=NULL, *domain;
	header_p t, d;
	int netcall_error;
	char filename[FILENAME_MAX];
	char tmpname[FILENAME_MAX];
	char outname[FILENAME_MAX];
	char inname[FILENAME_MAX];
	char sysname[FILENAME_MAX];
	struct stat st;
	/* ende fuer Janus */

	t = find(HD_ARCEROUT, sys);
	if (!t) {
		newlog(ERRLOG,
			"Kein ausgehender Packer definiert");
		return 1;
	}
	arcer = t->text;
	strlwr(arcer);

	t = find(HD_ARCERIN, sys);
	if (!t) {
		newlog(ERRLOG,
			"Kein eingehender Packer definiert");
		return 1;
	}
	arcerin = t->text;
	strlwr(arcerin);

	t = find(HD_PROTO, sys);
	if (!t) {
		newlog(ERRLOG,
			"Kein Uebertragungsprotokoll definiert");
		return 1;
	}
	transfer = t->text;
	strlwr(transfer);

	name = NULL;
	p = find(HD_SYS, ich);
	if (p) name = p->text;

	pw = NULL;
	p = find(HD_PASSWD, sys);
	if (p) pw = p->text;

	p = find(HD_X_CALL, sys);
	if (!p) {
		fprintf(stderr, "Welches Netcall-Verfahren????\n");
		exit(20);
	}
	for (i = 0, v = verf; *v; i++, v++)
		if (stricmp(*v, p->text) == 0)
			break;
	if (!*v) return 1;

	if (i < ZCONNECT) {
		t = find(HD_SYS, sys);
		if (!t) {
			newlog(ERRLOG,
				"Illegale Systemdatei: Kein " HN_SYS
				": Header oder falscher Name: %s", filename);
			return 1;
		}
		d = find(HD_DOMAIN, sys);
		if (!d) {
			newlog(ERRLOG,
				"Illegale Systemdatei: Kein " HN_DOMAIN
				": Header: %s", filename);
			return 1;
		}

		for (domain = strtok(d->text, " ;,:");
				domain;
				domain = strtok(NULL, " ;,:")) {
			sprintf(sysname, "%s.%s", t->text, domain);
			strlwr(sysname);
			sprintf(tmpname, "%s/%s", netcalldir, sysname);
			newlog(logname,
				"Suche Verzeichnis, versuche %s...", tmpname);
			if (access(tmpname, R_OK|X_OK) == 0)
				break;
		}

		if(access(tmpname, R_OK|X_OK)) {
			/* Problem: temp. Verzeichnis nicht zu haben */
			newlog(logname,
				"Problem beim Netcall: Verzeichnis "
				"nicht gefunden");
			return 1;
		}
	}

	/* ##### HIER WIRD ANGEWAEHLT ##### */
	p = find(HD_TEL, sys);
	while(tries) {
		if(!p) p = find(HD_TEL, sys);
		make_dialstr(dialstr, sizeof(dialstr), p->text);

		fprintf(stderr, "%3d. Anwahlversuch (noch %d): %-.25s\n",
			dial_cnt++, tries, dialstr);                     

		if (redial(dialstr, lmodem, 1) != 0 ) {
			tries--;
			p = p->other;
		} else {
			/* connect */
			break;
		}
	}

	set_local(lmodem, 0);
	time(&online_start);

	if (i < ZCONNECT) {
		if (name) dfree(name);
		name = dstrdup(boxstat.boxname);
		strupr(name);
#ifdef ENABLE_CAPS_IN_PASSWORD
		strupr(pw);
#endif
	}
	if(login(lmodem, i, name, pw)) return 0;

	if (i < ZCONNECT) { /* JANUS */
		int have_file = 0;

		netcall_error = 0;

		if ( janus_wait(lmodem) != 0 )
			return 0;

		sprintf(tmpname, "%s/%s.%d.dir", netcalldir, sysname, getpid());
		mkdir(tmpname, 0755);
		chdir(tmpname);
		/* outname: ausgehendes Archiv
		 * filename: */
		sprintf(outname, "%s/caller.%s", tmpname, arcer);
		sprintf(filename, "%s/%s.%s", netcalldir, sysname, arcer);
		sprintf(lockname, "%s/%s/" PREARC_LOCK, netcalldir, sysname);
		if (access(filename, R_OK) != 0) {
			FILE *f;
			if(access(filename, F_OK) == 0) {
				newlog(ERRLOG,
					"Leerer Puffer, weil keine Erlaubnis "
					"zum Lesen von %s: %s",
					outname, strerror(errno));
			}

			f = fopen(outname, "wb");
			if (!f) {
				newlog(ERRLOG,
					"Kann Netcall %s nicht erzeugen: %s",
					outname, strerror(errno));
				fclose(deblogfile);
				return 1;
			}
			fputs("\r\n", f);
			fclose(f);
		} else { /* can read filename */
			if (waitnolock(lockname, 180)) {
				fclose(deblogfile);
				newlog(OUTGOING, "System %s Prearc LOCK: %s",
					sysname, lockname );
				return 1;
			}
			fprintf(stderr, "Link: %s -> %s\n",
				filename, outname);
			if(link(filename, outname)) {
				fclose(deblogfile);
				newlog(ERRLOG,
					"Linken: %s -> %s fehlgeschlagen: %s",
					filename, outname, strerror(errno));
				netcall_error = 1;
				goto finish;
			}
			have_file = 1;
		}
		sprintf(inname, "called.%s", arcer);

		st.st_size = 0;
		if(stat(outname, &st)) {
			fprintf(stderr,
				"Zugriff auf %s fehlgeschlagen: %s\n",
				outname, strerror(errno));
			netcall_error = 1;
			goto finish;
		}

		newlog(logname, "Sende %s (%ld Bytes) per %s",
		       outname, (long)st.st_size, transfer);

		err = sendfile(transfer, outname);
		if (err) {
			newlog(logname,
				"Versand der Daten fehlgeschlagen");
			netcall_error = 1;
			goto finish;
		}

		newlog(logname, "Empfange mit %s", transfer);
		if (recvfile(transfer, inname)) {
			newlog(logname,
				"Empfang der Daten fehlgeschlagen");
			netcall_error = 1;
			goto finish;
		}
		st.st_size = 0;
		if(stat(inname, &st)) {
			newlog(logname,
				"Zugriff auf %s fehlgeschlagen: %s",
				inname, strerror(errno));
		}
		newlog(logname, "%ld Bytes empfangen", (long)st.st_size);


	finish:

		/* Fertig, Modem auflegen */
		signal(SIGHUP, SIG_IGN);
		fclose(stdin);
		fclose(stdout);
		hayes_hangup(lmodem); DMLOG("hayes hangup modem");
		hangup(lmodem); DMLOG("hangup modem");
		anrufdauer();

		restore_linesettings(lmodem);
		DMLOG("restoring modem parameters");
		close(lmodem); lmodem=-1; DMLOG("close modem");
		/* neuer stdin */
		fopen("/dev/null", "r");
		/* stderr wird in stdout kopiert */
		dup2(fileno(stderr),fileno(stdout));

		if(!netcall_error) {
			/* Netcall war erfolgreich, also Daten loeschen */
		if(have_file) {
			/* Backups von Nullpuffern sind
			   uninteressant */
			backup3(backoutdir,filename,sysname,arcer);
		}
		/* das ist nur ein Link, den putzen wir weg */
		if ( unlink(outname)) {
			newlog(ERRLOG,
			       "Loeschen von %s fehlgeschlagen: %s",
			       outname, strerror(errno));
		}

		fclose(deblogfile);

		/*
		 * Und empfangene Daten (im Hintergrund) einlesen,
		 * das Modem wird sofort wieder freigegeben.
		 */
		switch(fork()) {
		case -1:
			{ /* cannot fork */
				perror("forking import");
				newlog(ERRLOG,
				       "Forken des Importteils "
				       "fehlgeschlagen: %s",
				       strerror(errno));
				break;
			}
		case 0:
			{
				/* Ich bin child */
				deblogfile=fopen("/tmp/import.deblogfile", "a");
				DMLOG("child forked");
				import_all(arcerin, sysname);
				chdir ("/");
				if(rmdir(tmpname)) {
					newlog(ERRLOG,
						"Loeschen von %s "
						"fehlgeschlagen: %s",
						tmpname, strerror(errno));
				}
				fclose(deblogfile);
				exit(0);
			}
		default: /* parent */
			break;
		}
		}
		return(1);

	} else {
		/* ZCONNECT */

		system_master(ich, sys);
		if (auflegen) return 1;
		bereitstellen();
		files = 1;
		senden_queue = todo;
		todo = NULL;
		while (!auflegen) {
			datei_master(ich, sys);
		}
		anrufdauer();
		close(lmodem); DMLOG("close modem");
		aufraeumen();
		exit (0);
	}

	return 1;
}
Esempio n. 14
0
int
main(int argc, const char **argv)
{
	const char *sysname, *speed;
	char sysfile[FILENAME_MAX];
	char deblogname[FILENAME_MAX];
	FILE *f;
	header_p sys, ich, p;
	int i;

	initlog("call");

	if (0 == strcmp(argv[0], "-h")) usage();
	if (argc < 4 || argc > 5) usage();

	gmodem=-1;
	atexit(cleanup);

	sysname = strlwr( dstrdup( argv[1] ));
	if (!strchr(argv[2], '/'))
		snprintf(tty, sizeof(tty), "/dev/%s", argv[2]);
	else
		strcpy(tty, argv[2]);

	speed = argv[3];

	maxtry = 1;
	if (argc > 4)
		maxtry = atoi(argv[4]);

	minireadstat();
	sprintf(deblogname, "%s/" DEBUGLOG_FILE, logdir);
	if(debuglevel>0) {
		deblogfile = fopen(deblogname, "w");
		if (!deblogfile) {
			printf("Ich kann das Logfile nicht oeffnen. "
				"Probiere /dev/null...\n");
			deblogfile = fopen("/dev/null", "w");
			if (!deblogfile) {
				printf("Hmm... - /dev/null "
					"nicht schreibbar??\n");
				return 10;
			}
		}
	} else {
		deblogfile = fopen("/dev/null", "w");
		if (!deblogfile) {
			printf("Arghl! - kann /dev/null "
				"nicht zum Schreiben oeffnen!\n\n");
			return 10;
		}
	}
	sprintf(sysfile, "%s/%s", systemedir, sysname);
	f = fopen(sysfile, "r");
	if (!f) {
		perror(sysfile);
		newlog(ERRLOG, "File <%s> not readable: %s",
			sysfile, strerror(errno));
		return 1;
	}
	sys = rd_para(f);
	fclose(f);

	ich = get_myself();

	for (i=maxtry; i; i--) {
	   if (lock_device(1, tty)) break;
	   fputs(" ... unser Modem ist belegt\n", stderr);
	   sleep(60);
	}
	if (!i) {
		newlog(ERRLOG, "Cannot lock device: %s", tty);
		return 9;
	}

#ifdef LEAVE_CTRL_TTY
	/*
	 * Bisheriges Controlling-TTY verlassen, damit "modem" das neue
	 * wird.
	 */
#ifdef BSD
	setpgrp(0, getpid());	/* set process group id to process id */
#ifdef SIGTTOU
	signal(SIGTTOU, SIG_IGN);
#endif
#ifdef SIGTTIN
	signal(SIGTTIN, SIG_IGN);
#endif
#ifdef SIGTSTP
	signal(SIGTSTP, SIG_IGN);
#endif
#else	/* !BSD */
#if !defined(USE_SETSID) && !defined(USE_SETPGRP)
#error Controlling TTY kann nicht verlassen werden: definieren Sie eine Methode dazu
#endif /* !BSD und keine SysV-Methode definiert */

#ifdef USE_SETSID
#error	Dies funktioniert nicht!
	setsid();
#endif /* USE_SETSID */
#ifdef USE_SETPGRP
	setpgrp();
#endif /* USE_SETPGRP */
#endif /* !BSD */
#endif /* LEAVE_CTRL_TTY */

	gmodem = open(tty,
#if !defined(__NetBSD__)
			O_RDWR | O_NDELAY
#else
			O_RDWR
#endif
		); DMLOG("open modem");
	if (gmodem < 0) {
		newlog(ERRLOG,
			"Can not access device %s: %s", tty, strerror(errno));
		return 10;
	}
#if !defined(__NetBSD__)
	else {
		/* Nonblock abschalten */
		int n;
		n=fcntl(gmodem, F_GETFL, 0);
		(void)fcntl(gmodem, F_SETFL, n & ~O_NDELAY);
	}
#endif
	save_linesettings(gmodem); DMLOG("saving modem parameters");
	set_rawmode(gmodem); DMLOG("set modem to rawmode");
	set_local(gmodem, 1);
	set_speed(gmodem, speed); DMLOG("set modem speed");
#ifdef TIOCSCTTY
	ioctl(gmodem, TIOCSCTTY, NULL);
#endif

	files = 0;
	online_start = 0;
	fprintf(stderr, "Netcall bei %s [%s]\n", sysname, tty);

	fclose(stdin);
	fclose(stdout);
	dup(gmodem); dup(gmodem); DMLOG("dup modem 2x to stdin and stdout");

	if (setjmp(timeout)) {
		newlog(ERRLOG, "ABBRUCH: Timeout");
		lock_device(0, tty);
		anrufdauer();
		if (files) aufraeumen();

		return 11;
	}
	if (setjmp(nocarrier)) {
		if (!auflegen) {
			newlog(ERRLOG, "ABBRUCH: Gegenstelle hat aufgelegt");
		}
		lock_device(0, tty);
		anrufdauer();
		if (files) aufraeumen();

		return auflegen ? 0 : 12;
	}
	signal(SIGHUP, handle_nocarrier);
	signal(SIGALRM, handle_timeout);
	setup_dial_info(ortsnetz, g_int_prefix, g_ovst, NULL);

	p = find(HD_TEL, sys);
	if (!p) {
		newlog(ERRLOG,
			"Keine Telefonnummer fuer %s gefunden",
			sysname);
		return 2;
	}

	anruf(sys, ich, gmodem, maxtry);

	if (online_start) {
		anrufdauer();
	} else {
		fprintf(stderr, "Keine Verbindung hergestellt.\n");
	}

	lock_device(0, tty);
	/* Device ist freigegeben, aber wir warten noch auf das Ende
	   der Importphase, bevor wir zurueckkehren. */
	wait(NULL);
	return 0;
}