Ejemplo n.º 1
0
int switch_p_libstate_restore(char *dir_name, bool recover)
{
#ifdef HAVE_NATIVE_CRAY
	char *data = NULL, *file_name;
	Buf buffer = NULL;
	int error_code = SLURM_SUCCESS;
	int state_fd, data_allocated = 0, data_read = 0, data_size = 0;

	xassert(dir_name != NULL);

	if (debug_flags & DEBUG_FLAG_SWITCH) {
		CRAY_INFO("restore from %s, recover %d",
			  dir_name,  (int) recover);
	}

	if (!recover)		/* clean start, no recovery */
		return SLURM_SUCCESS;

	file_name = xstrdup(dir_name);
	xstrcat(file_name, "/switch_cray_state");
	state_fd = open (file_name, O_RDONLY);
	if (state_fd >= 0) {
		data_allocated = SWITCH_BUF_SIZE;
		data = xmalloc(data_allocated);
		while (1) {
			data_read = read (state_fd, &data[data_size],
					  SWITCH_BUF_SIZE);
			if ((data_read < 0) && (errno == EINTR))
				continue;
			if (data_read < 0) {
				CRAY_ERR("Read error on %s, %m", file_name);
				error_code = SLURM_ERROR;
				break;
			} else if (data_read == 0)
				break;
			data_size      += data_read;
			data_allocated += data_read;
			xrealloc(data, data_allocated);
		}
		close (state_fd);
		(void) unlink(file_name);	/* One chance to recover */
		xfree(file_name);
	} else {
		CRAY_ERR("No %s file for switch/cray state recovery",
			 file_name);
		CRAY_ERR("Starting switch/cray with clean state");
		xfree(file_name);
		return SLURM_SUCCESS;
	}

	if (error_code == SLURM_SUCCESS) {
		buffer = create_buf (data, data_size);
		data = NULL;	/* now in buffer, don't xfree() */
		_state_read_buf(buffer);
	}

	if (buffer)
		free_buf(buffer);
	xfree(data);
#endif
	return SLURM_SUCCESS;
}
Ejemplo n.º 2
0
Archivo: grep.c Proyecto: atispor/git
static void grep_file_async(struct grep_opt *opt, char *name,
			    const char *filename)
{
	add_work(WORK_FILE, name, xstrdup(filename));
}
Ejemplo n.º 3
0
static unsigned int
get_filenum (const char *filename, unsigned int num)
{
  static unsigned int last_used, last_used_dir_len;
  const char *file;
  size_t dir_len;
  unsigned int i, dir;

  if (num == 0 && last_used)
    {
      if (! files[last_used].dir
	  && strcmp (filename, files[last_used].filename) == 0)
	return last_used;
      if (files[last_used].dir
	  && strncmp (filename, dirs[files[last_used].dir],
		      last_used_dir_len) == 0
	  && IS_DIR_SEPARATOR (filename [last_used_dir_len])
	  && strcmp (filename + last_used_dir_len + 1,
		     files[last_used].filename) == 0)
	return last_used;
    }

  file = lbasename (filename);
  /* Don't make empty string from / or A: from A:/ .  */
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
  if (file <= filename + 3)
    file = filename;
#else
  if (file == filename + 1)
    file = filename;
#endif
  dir_len = file - filename;

  dir = 0;
  if (dir_len)
    {
      --dir_len;
      for (dir = 1; dir < dirs_in_use; ++dir)
	if (strncmp (filename, dirs[dir], dir_len) == 0
	    && dirs[dir][dir_len] == '\0')
	  break;

      if (dir >= dirs_in_use)
	{
	  if (dir >= dirs_allocated)
	    {
	      dirs_allocated = dir + 32;
	      dirs = (char **)
		     xrealloc (dirs, (dir + 32) * sizeof (const char *));
	    }

	  dirs[dir] = xmalloc (dir_len + 1);
	  memcpy (dirs[dir], filename, dir_len);
	  dirs[dir][dir_len] = '\0';
	  dirs_in_use = dir + 1;
	}
    }

  if (num == 0)
    {
      for (i = 1; i < files_in_use; ++i)
	if (files[i].dir == dir
	    && files[i].filename
	    && strcmp (file, files[i].filename) == 0)
	  {
	    last_used = i;
	    last_used_dir_len = dir_len;
	    return i;
	  }
    }
  else
    i = num;

  if (i >= files_allocated)
    {
      unsigned int old = files_allocated;

      files_allocated = i + 32;
      files = (struct file_entry *)
	xrealloc (files, (i + 32) * sizeof (struct file_entry));

      memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
    }

  files[i].filename = num ? file : xstrdup (file);
  files[i].dir = dir;
  files_in_use = i + 1;
  last_used = i;
  last_used_dir_len = dir_len;

  return i;
}
Ejemplo n.º 4
0
/*
 * Parse a comma separated list of RLIMIT names.
 *
 * Return 0 on success, or -1 if the 'rlimits_str' input parameter contains
 * a name that is not in rlimits_info[].
 */
int
parse_rlimits( char *rlimits_str, int propagate_flag )
{
	slurm_rlimits_info_t *rli;	/* ptr iterator for rlimits_info[] */
	char		     *tp;	/* token ptr */
	bool		     found;
	bool		     propagate_none = false;
	char		     *rlimits_str_dup;

	xassert( rlimits_str );

	if (xstrcmp(rlimits_str, "NONE") == 0) {
		propagate_none = true;
		propagate_flag = !propagate_flag;
	}

	if (propagate_none || xstrcmp( rlimits_str, "ALL" ) == 0) {
		/*
		 * Propagate flag value applies to all rlimits
		 */
		for (rli = rlimits_info; rli->name; rli++)
			rli->propagate_flag = propagate_flag;
		rlimits_were_parsed = true;
		return( 0 );
	}

	/*
	 * Since parse_rlimits may be called multiple times, we
	 * need to reinitialize the propagate flags when individual
	 * rlimits are specified.
	 */
	if (rlimits_were_parsed)
		for (rli = rlimits_info; rli->name; rli++)
			rli->propagate_flag = PROPAGATE_RLIMITS_NOT_SET;

	rlimits_str_dup = xstrdup( rlimits_str );
	tp = strtok( rlimits_str_dup, RLIMIT_DELIMS );
	while (tp != NULL) {
		found = false;
		for (rli = rlimits_info; rli->name; rli++) {
			/*
			 * Accept either "RLIMIT_CORE" or "CORE"
			 */
			if (xstrncmp( tp, RLIMIT_, LEN_RLIMIT_ ) == 0)
				tp += LEN_RLIMIT_;
			if (xstrcmp( tp, rli->name ))
				continue;
			rli->propagate_flag = propagate_flag;
			found = true;
			break;
		}
		if (found == false) {
			error( "Bad rlimit name: %s", tp );
			xfree( rlimits_str_dup );
			return( -1 );
		}
		tp = strtok( NULL, RLIMIT_DELIMS );
	}
	xfree( rlimits_str_dup );

	/*
	 * Any rlimits that weren't in the 'rlimits_str' parameter get the
	 * opposite propagate flag value.
	 */
	for (rli = rlimits_info; rli->name; rli++)
		if (rli->propagate_flag == PROPAGATE_RLIMITS_NOT_SET)
			rli->propagate_flag = ( ! propagate_flag );

	rlimits_were_parsed = true;
	return( 0 );
}
Ejemplo n.º 5
0
static List _create_block_list(partition_info_msg_t *part_info_ptr,
			       block_info_msg_t *block_info_ptr)
{
	int i;
	static List block_list = NULL;
	static partition_info_msg_t *last_part_info_ptr = NULL;
	static block_info_msg_t *last_block_info_ptr = NULL;
	List last_list = NULL;
	ListIterator last_list_itr = NULL;
	sview_block_info_t *block_ptr = NULL;
	char tmp_mp_str[50];

	if (block_list && (part_info_ptr == last_part_info_ptr)
	    && (block_info_ptr == last_block_info_ptr))
		return block_list;

	last_part_info_ptr = part_info_ptr;
	if (block_list) {
		/* Only the partition info changed so lets update just
		   that part.
		*/
		if (block_info_ptr == last_block_info_ptr) {
			ListIterator itr = list_iterator_create(block_list);

			while ((block_ptr = list_next(itr)))
				_set_block_partition(part_info_ptr, block_ptr);

			return block_list;
		}
		last_list = block_list;
	}

	block_list = list_create(_block_list_del);

	last_block_info_ptr = block_info_ptr;

	if (last_list)
		last_list_itr = list_iterator_create(last_list);
	for (i=0; i<block_info_ptr->record_count; i++) {
		/* If we don't have a block name just continue since
		   ths block hasn't been made in the system yet. */
		if (!block_info_ptr->block_array[i].bg_block_id)
			continue;

		block_ptr = NULL;

		if (last_list_itr) {
			while ((block_ptr = list_next(last_list_itr))) {
				if (!xstrcmp(block_ptr->bg_block_name,
					     block_info_ptr->
					     block_array[i].bg_block_id)) {
					list_remove(last_list_itr);
					_block_info_free(block_ptr);
					break;
				}
			}
			list_iterator_reset(last_list_itr);
		}

		if (!block_ptr)
			block_ptr = xmalloc(sizeof(sview_block_info_t));
		block_ptr->pos = i;
		block_ptr->bg_block_name
			= xstrdup(block_info_ptr->
				  block_array[i].bg_block_id);


		block_ptr->color_inx =
			atoi(block_ptr->bg_block_name+7);

		/* on some systems they make there own blocks named
		   whatever they want, so doing this fixes what could
		   be a negative number.
		*/
		if (block_ptr->color_inx < 0)
			block_ptr->color_inx = i;

		block_ptr->color_inx %= sview_colors_cnt;

		block_ptr->mp_str
			= xstrdup(block_info_ptr->block_array[i].mp_str);
		if (block_info_ptr->block_array[i].ionode_str) {
			block_ptr->small_block = 1;
			snprintf(tmp_mp_str, sizeof(tmp_mp_str),
				 "%s[%s]",
				 block_ptr->mp_str,
				 block_info_ptr->block_array[i].ionode_str);
			xfree(block_ptr->mp_str);
			block_ptr->mp_str = xstrdup(tmp_mp_str);
		}
		block_ptr->reason
			= xstrdup(block_info_ptr->block_array[i].reason);

		block_ptr->imagemloader = xstrdup(
			block_info_ptr->block_array[i].mloaderimage);

		block_ptr->state
			= block_info_ptr->block_array[i].state;
		memcpy(block_ptr->bg_conn_type,
		       block_info_ptr->block_array[i].conn_type,
		       sizeof(block_ptr->bg_conn_type));

		block_ptr->cnode_cnt
			= block_info_ptr->block_array[i].cnode_cnt;
		block_ptr->cnode_err_cnt
			= block_info_ptr->block_array[i].cnode_err_cnt;
		block_ptr->mp_inx
			= block_info_ptr->block_array[i].mp_inx;
		_set_block_partition(part_info_ptr, block_ptr);

		block_ptr->job_list = list_create(slurm_free_block_job_info);
		if (block_info_ptr->block_array[i].job_list)
			list_transfer(block_ptr->job_list,
				      block_info_ptr->block_array[i].job_list);

		if (block_ptr->bg_conn_type[0] >= SELECT_SMALL)
			block_ptr->size = 0;

		list_append(block_list, block_ptr);
	}

	list_sort(block_list,
		  (ListCmpF)_sview_block_sort_aval_dec);

	if (last_list) {
		list_iterator_destroy(last_list_itr);
		FREE_NULL_LIST(last_list);
	}

	return block_list;
}
Ejemplo n.º 6
0
static int delete_branches(int argc, const char **argv, int force, int kinds)
{
	struct commit *rev, *head_rev = NULL;
	unsigned char sha1[20];
	char *name = NULL;
	const char *fmt, *remote;
	int i;
	int ret = 0;
	struct strbuf bname = STRBUF_INIT;

	switch (kinds) {
	case REF_REMOTE_BRANCH:
		fmt = "refs/remotes/%s";
		/* TRANSLATORS: This is "remote " in "remote branch '%s' not found" */
		remote = _("remote ");
		force = 1;
		break;
	case REF_LOCAL_BRANCH:
		fmt = "refs/heads/%s";
		remote = "";
		break;
	default:
		die(_("cannot use -a with -d"));
	}

	if (!force) {
		head_rev = lookup_commit_reference(head_sha1);
		if (!head_rev)
			die(_("Couldn't look up commit object for HEAD"));
	}
	for (i = 0; i < argc; i++, strbuf_release(&bname)) {
		strbuf_branchname(&bname, argv[i]);
		if (kinds == REF_LOCAL_BRANCH && !strcmp(head, bname.buf)) {
			error(_("Cannot delete the branch '%s' "
			      "which you are currently on."), bname.buf);
			ret = 1;
			continue;
		}

		free(name);

		name = xstrdup(mkpath(fmt, bname.buf));
		if (read_ref(name, sha1)) {
			error(_("%sbranch '%s' not found."),
					remote, bname.buf);
			ret = 1;
			continue;
		}

		rev = lookup_commit_reference(sha1);
		if (!rev) {
			error(_("Couldn't look up commit object for '%s'"), name);
			ret = 1;
			continue;
		}

		if (!force && !branch_merged(kinds, bname.buf, rev, head_rev)) {
			error(_("The branch '%s' is not fully merged.\n"
			      "If you are sure you want to delete it, "
			      "run 'git branch -D %s'."), bname.buf, bname.buf);
			ret = 1;
			continue;
		}

		if (delete_ref(name, sha1, 0)) {
			error(_("Error deleting %sbranch '%s'"), remote,
			      bname.buf);
			ret = 1;
		} else {
			struct strbuf buf = STRBUF_INIT;
			printf(_("Deleted %sbranch %s (was %s).\n"), remote,
			       bname.buf,
			       find_unique_abbrev(sha1, DEFAULT_ABBREV));
			strbuf_addf(&buf, "branch.%s", bname.buf);
			if (git_config_rename_section(buf.buf, NULL) < 0)
				warning(_("Update of config-file failed"));
			strbuf_release(&buf);
		}
	}

	free(name);

	return(ret);
}
Ejemplo n.º 7
0
/*
 * Parse a multi-prog input file line
 * line IN - line to parse
 * command_pos IN/OUT - where in opt.argv we are
 * count IN - which command we are on
 * return 0 if empty line, 1 if added
 */
static int _parse_prog_line(char *in_line, int *command_pos, int count)
{
	int i, cmd_inx;
	int first_task_inx, last_task_inx;
	hostset_t hs = NULL;
	char *tmp_str = NULL;

	xassert(opt.ntasks);

	/* Get the task ID string */
	for (i = 0; in_line[i]; i++)
		if (!isspace(in_line[i]))
			break;

	if (!in_line[i]) /* empty line */
		return 0;
	else if (in_line[i] == '#')
		return 0;
	else if (!isdigit(in_line[i]))
		goto bad_line;
	first_task_inx = i;
	for (i++; in_line[i]; i++) {
		if (isspace(in_line[i]))
			break;
	}
	if (!isspace(in_line[i]))
		goto bad_line;
	last_task_inx = i;


	/* Now transfer data to the function arguments */
	in_line[last_task_inx] = '\0';
	xstrfmtcat(tmp_str, "[%s]", in_line + first_task_inx);
	hs = hostset_create(tmp_str);
	xfree(tmp_str);
	in_line[last_task_inx] = ' ';
	if (!hs)
		goto bad_line;


	if (count) {
		opt.argc += 1;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[(*command_pos)++] = xstrdup(":");
	}
	opt.argc += 2;
	xrealloc(opt.argv, opt.argc * sizeof(char *));
	opt.argv[(*command_pos)++] = xstrdup("-n");
	opt.argv[(*command_pos)++] = xstrdup_printf("%d", hostset_count(hs));
	hostset_destroy(hs);

	/* Get the command */
	for (i++; in_line[i]; i++) {
		if (!isspace(in_line[i]))
			break;
	}
	if (in_line[i] == '\0')
		goto bad_line;

	cmd_inx = i;
	for ( ; in_line[i]; i++) {
		if (isspace(in_line[i])) {
			if (i > cmd_inx) {
				int diff = i - cmd_inx + 1;
				char tmp_char[diff + 1];
				snprintf(tmp_char, diff, "%s",
					 in_line + cmd_inx);
				opt.argc += 1;
				xrealloc(opt.argv, opt.argc * sizeof(char *));
				opt.argv[(*command_pos)++] = xstrdup(tmp_char);
			}
			cmd_inx = i + 1;
		} else if (in_line[i] == '\n')
			break;
	}

	return 1;

bad_line:
	error("invalid input line: %s", in_line);

	return 0;
}
Ejemplo n.º 8
0
int main(int argc, char **argv)
{
    bool expert_mode = false;

    const char *prgname = "abrt";
    abrt_init(argv);

    /* I18n */
    setlocale(LC_ALL, "");
#if ENABLE_NLS
    bindtextdomain(PACKAGE, LOCALEDIR);
    textdomain(PACKAGE);
#endif

    /* without this the name is set to argv[0] which confuses
     * desktops which uses the name to find the corresponding .desktop file
     * trac#180
     *
     * env variable can be used to override the default prgname, so it's the
     * same as the application which is calling us (trac#303)
     *
     * note that g_set_prgname has to be called before gtk_init
     */
    char *env_prgname = getenv("LIBREPORT_PRGNAME");
    g_set_prgname(env_prgname ? env_prgname : prgname);

    gtk_init(&argc, &argv);

    /* Can't keep these strings/structs static: _() doesn't support that */
    const char *program_usage_string = _(
        "& [-vpdx] [-e EVENT]... [-g GUI_FILE] PROBLEM_DIR\n"
        "\n"
        "GUI tool to analyze and report problem saved in specified PROBLEM_DIR"
    );
    enum {
        OPT_v = 1 << 0,
        OPT_g = 1 << 1,
        OPT_p = 1 << 2,
        OPT_d = 1 << 3,
        OPT_e = 1 << 4,
        OPT_x = 1 << 5,
    };
    /* Keep enum above and order of options below in sync! */
    struct options program_options[] = {
        OPT__VERBOSE(&g_verbose),
        OPT_STRING('g', NULL, &g_glade_file, "FILE",          _("Alternate GUI file")),
        OPT_BOOL(  'p', NULL, NULL,                           _("Add program names to log")),
        OPT_BOOL(  'd', "delete", NULL,                       _("Remove PROBLEM_DIR after reporting")),
        OPT_LIST(  'e', "event", &g_auto_event_list, "EVENT", _("Run only these events")),
        OPT_BOOL(  'x', "expert", &expert_mode,               _("Expert mode")),
        OPT_END()
    };
    unsigned opts = parse_opts(argc, argv, program_options, program_usage_string);
    argv += optind;
    if (!argv[0] || argv[1]) /* zero or >1 arguments */
        show_usage_and_die(program_usage_string, program_options);

    /* Allow algorithms to add mallocated strings */
    for (GList *elem = g_auto_event_list; elem; elem = g_list_next(elem))
        elem->data = xstrdup((const char *)elem->data);

    export_abrt_envvars(opts & OPT_p);

    g_dump_dir_name = xstrdup(argv[0]);

    /* load /etc/abrt/events/foo.{conf,xml} stuff
       and $XDG_CACHE_HOME/abrt/events/foo.conf */
    g_event_config_list = load_event_config_data();
    load_event_config_data_from_user_storage(g_event_config_list);
    load_user_settings("report-gtk");

    load_workflow_config_data(WORKFLOWS_DIR);

    /* list of workflows applicable to the currently processed problem */
    GHashTable *possible_workflows = load_workflow_config_data_from_list(
                list_possible_events_glist(g_dump_dir_name, "workflow"),
                WORKFLOWS_DIR);

    /* if we have only 1 workflow, we can use the events from it as default */
    if (!expert_mode && g_auto_event_list == NULL && g_hash_table_size(possible_workflows) == 1)
    {
        GHashTableIter iter;
        gpointer key, value;

        g_hash_table_iter_init(&iter, possible_workflows);
        if (g_hash_table_iter_next(&iter, &key, &value))
        {
            VERB1 log("autoselected workflow: '%s'", (char *)key);
            g_auto_event_list = wf_get_event_names((workflow_t *)value);
        }
    }

    problem_data_reload_from_dump_dir();

    create_assistant(expert_mode);

    g_custom_logger = &show_error_as_msgbox;

    update_gui_state_from_problem_data(UPDATE_SELECTED_EVENT);

    /* Enter main loop */
    gtk_main();

    if (opts & OPT_d)
        delete_dump_dir_possibly_using_abrtd(g_dump_dir_name);

    save_user_settings();

    return 0;
}
Ejemplo n.º 9
0
static void
input_userauth_request(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	Authmethod *m = NULL;
	char *user, *service, *method, *style = NULL;

	if (authctxt == NULL)
		fatal("input_userauth_request: no authctxt");

	user = packet_get_string(NULL);
	service = packet_get_string(NULL);
	method = packet_get_string(NULL);
	debug("userauth-request for user %s service %s method %s", user,
		service, method);
	debug("attempt %d initial attempt %d failures %d initial failures %d",
		authctxt->attempt, authctxt->init_attempt,
		authctxt->failures, authctxt->init_failures);

	m = authmethod_lookup(method);

	if ((style = strchr(user, ':')) != NULL)
		*style++ = 0;

	authctxt->attempt++;
	if (m != NULL && m->is_initial)
		authctxt->init_attempt++;

	if (authctxt->attempt == 1) {
		/* setup auth context */
		authctxt->pw = PRIVSEP(getpwnamallow(user));
		/* May want to abstract SSHv2 services someday */
		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
			/* enforced in userauth_finish() below */
			authctxt->valid = 1;
			debug2("input_userauth_request: setting up authctxt for %s", user);
		} else {
			log("input_userauth_request: illegal user %s", user);
		}
		setproctitle("%s%s", authctxt->pw ? user : "******",
		    use_privsep ? " [net]" : "");
		authctxt->user = xstrdup(user);
		authctxt->service = xstrdup(service);
		authctxt->style = style ? xstrdup(style) : NULL;
		userauth_reset_methods();
		if (use_privsep)
			mm_inform_authserv(service, style);
	} else {
		char *abandoned;

		/*
		 * Check for abandoned [multi-round-trip] userauths
		 * methods (e.g., kbdint).  Userauth method abandonment
		 * should be treated as userauth method failure and
		 * counted against max_auth_tries.
		 */
		abandoned = authmethods_check_abandonment(authctxt, m);

		if (abandoned != NULL &&
		    authctxt->failures > options.max_auth_tries) {
			/* userauth_finish() will now packet_disconnect() */
			userauth_finish(authctxt, abandoned);
			/* NOTREACHED */
		}

		/* Handle user|service changes, possibly packet_disconnect() */
		userauth_user_svc_change(authctxt, user, service);
	}

	authctxt->method = m;

	/* run userauth method, try to authenticate user */
	if (m != NULL && userauth_method_can_run(m)) {
		debug2("input_userauth_request: try method %s", method);

		m->postponed = 0;
		m->abandoned = 0;
		m->authenticated = 0;

		if (!m->is_initial ||
		    authctxt->init_failures < options.max_init_auth_tries)
			m->userauth(authctxt);

		authmethod_count_attempt(m);

		if (authctxt->unwind_dispatch_loop) {
			/*
			 * Method ran nested dispatch loop but was
			 * abandoned.  Cleanup and return without doing
			 * anything else; we're just unwinding the stack.
			 */
			authctxt->unwind_dispatch_loop = 0;
			goto done;
		}

		if (m->postponed)
			goto done; /* multi-round trip userauth not finished */

		if (m->abandoned) {
			/* multi-round trip userauth abandoned, log failure */
			auth_log(authctxt, 0, method, " ssh2");
			goto done;
		}
	}

	userauth_finish(authctxt, method);

done:
	xfree(service);
	xfree(user);
	xfree(method);
}
Ejemplo n.º 10
0
/* Parse and sanity check user_spec.
 *
 * If successful, set global variables 'uid' and 'gid'
 * with the parsed results. Global variable 'user'
 * will be pointing to a string that stores the name
 * of the user to be switched into.
 *
 * Also set 'switch_to_new_user' to true, The actual
 * user switching is done as soon as daemonize_start()
 * is called. I/O access before calling daemonize_start()
 * will still be with root's credential.  */
void
daemon_set_new_user(const char *user_spec)
{
    char *pos = strchr(user_spec, ':');
    size_t init_bufsize, bufsize;

    init_bufsize = get_sysconf_buffer_size();
    uid = getuid();
    gid = getgid();

    if (geteuid() || uid) {
        VLOG_FATAL("%s: only root can use --user option", pidfile);
    }

    user_spec += strspn(user_spec, " \t\r\n");
    size_t len = pos ? pos - user_spec : strlen(user_spec);
    char *buf;
    struct passwd pwd, *res;
    int e;

    bufsize = init_bufsize;
    buf = xmalloc(bufsize);
    if (len) {
        user = xmemdup0(user_spec, len);

        while ((e = getpwnam_r(user, &pwd, buf, bufsize, &res)) == ERANGE) {
            if (!enlarge_buffer(&buf, &bufsize)) {
                break;
            }
        }

        if (e != 0) {
            VLOG_FATAL("%s: Failed to retrive user %s's uid (%s), aborting.",
                       pidfile, user, ovs_strerror(e));
        }
        if (res == NULL) {
            VLOG_FATAL("%s: user %s not found, aborting.", pidfile, user);
        }
    } else {
        /* User name is not specified, use current user.  */
        while ((e = getpwuid_r(uid, &pwd, buf, bufsize, &res)) == ERANGE) {
            if (!enlarge_buffer(&buf, &bufsize)) {
                break;
            }
        }

        if (e != 0) {
            VLOG_FATAL("%s: Failed to retrive current user's name "
                       "(%s), aborting.", pidfile, ovs_strerror(e));
        }
        user = xstrdup(pwd.pw_name);
    }

    uid = pwd.pw_uid;
    gid = pwd.pw_gid;
    free(buf);

    if (pos) {
        char *grpstr = pos + 1;
        grpstr += strspn(grpstr, " \t\r\n");

        if (*grpstr) {
            struct group grp, *res;

            bufsize = init_bufsize;
            buf = xmalloc(bufsize);
            while ((e = getgrnam_r(grpstr, &grp, buf, bufsize, &res))
                         == ERANGE) {
                if (!enlarge_buffer(&buf, &bufsize)) {
                    break;
                }
            }

            if (e) {
                VLOG_FATAL("%s: Failed to get group entry for %s, "
                           "(%s), aborting.", pidfile, grpstr,
                           ovs_strerror(e));
            }
            if (res == NULL) {
                VLOG_FATAL("%s: group %s not found, aborting.", pidfile,
                           grpstr);
            }

            if (gid != grp.gr_gid) {
                char **mem;

                for (mem = grp.gr_mem; *mem; ++mem) {
                    if (!strcmp(*mem, user)) {
                        break;
                    }
                }

                if (!*mem) {
                    VLOG_FATAL("%s: Invalid --user option %s (user %s is "
                               "not in group %s), aborting.", pidfile,
                               user_spec, user, grpstr);
                }
                gid = grp.gr_gid;
            }
            free(buf);
        }
    }

    switch_user = true;
}
Ejemplo n.º 11
0
static int
parse_settings (unsigned char *prop,
                long unsigned int bytes,
                struct xsettings *settings)
{
  Lisp_Object byteorder = Fbyteorder ();
  int my_bo = XFASTINT (byteorder) == 'B' ? MSBFirst : LSBFirst;
  int that_bo = prop[0];
  CARD32 n_settings;
  int bytes_parsed = 0;
  int settings_seen = 0;
  int i = 0;

  /* First 4 bytes is a serial number, skip that.  */

  if (bytes < 12) return BadLength;
  memcpy (&n_settings, prop+8, 4);
  if (my_bo != that_bo) n_settings = SWAP32 (n_settings);
  bytes_parsed = 12;

  memset (settings, 0, sizeof (*settings));

  while (bytes_parsed+4 < bytes && settings_seen < 7
         && i < n_settings)
    {
      int type = prop[bytes_parsed++];
      CARD16 nlen;
      CARD32 vlen, ival = 0;
      char name[128]; /* The names we are looking for are not this long.  */
      char sval[128]; /* The values we are looking for are not this long.  */
      int want_this;
      int to_cpy;

      sval[0] = '\0';
      ++i;
      ++bytes_parsed; /* Padding */

      memcpy (&nlen, prop+bytes_parsed, 2);
      bytes_parsed += 2;
      if (my_bo != that_bo) nlen = SWAP16 (nlen);
      if (bytes_parsed+nlen > bytes) return BadLength;
      to_cpy = nlen > 127 ? 127 : nlen;
      memcpy (name, prop+bytes_parsed, to_cpy);
      name[to_cpy] = '\0';

      bytes_parsed += nlen;
      bytes_parsed = PAD (bytes_parsed);

      bytes_parsed += 4; /* Skip serial for this value */
      if (bytes_parsed > bytes) return BadLength;

      want_this =
#ifdef HAVE_XFT
        (nlen > 6 && strncmp (name, "Xft/", 4) == 0)
        || strcmp (XSETTINGS_FONT_NAME, name) == 0
        ||
#endif
        strcmp (XSETTINGS_TOOL_BAR_STYLE, name) == 0;

      switch (type)
        {
        case 0: /* Integer */
          if (bytes_parsed+4 > bytes) return BadLength;
          if (want_this)
            {
              memcpy (&ival, prop+bytes_parsed, 4);
              if (my_bo != that_bo) ival = SWAP32 (ival);
            }
          bytes_parsed += 4;
          break;

        case 1: /* String */
          if (bytes_parsed+4 > bytes) return BadLength;
          memcpy (&vlen, prop+bytes_parsed, 4);
          bytes_parsed += 4;
          if (my_bo != that_bo) vlen = SWAP32 (vlen);
          if (want_this)
            {
              to_cpy = vlen > 127 ? 127 : vlen;
              memcpy (sval, prop+bytes_parsed, to_cpy);
              sval[to_cpy] = '\0';
            }
          bytes_parsed += vlen;
          bytes_parsed = PAD (bytes_parsed);
          break;

        case 2: /* RGB value */
          /* No need to parse this */
          if (bytes_parsed+8 > bytes) return BadLength;
          bytes_parsed += 8; /* 4 values (r, b, g, alpha), 2 bytes each.  */
          break;

        default: /* Parse Error */
          return BadValue;
        }

      if (want_this)
        {
          ++settings_seen;
          if (strcmp (name, XSETTINGS_TOOL_BAR_STYLE) == 0)
            {
              settings->tb_style = xstrdup (sval);
              settings->seen |= SEEN_TB_STYLE;
            }
#ifdef HAVE_XFT
          else if (strcmp (name, XSETTINGS_FONT_NAME) == 0)
            {
              settings->font = xstrdup (sval);
              settings->seen |= SEEN_FONT;
            }
          else if (strcmp (name, "Xft/Antialias") == 0)
            {
              settings->seen |= SEEN_AA;
              settings->aa = ival != 0;
            }
          else if (strcmp (name, "Xft/Hinting") == 0)
            {
              settings->seen |= SEEN_HINTING;
              settings->hinting = ival != 0;
            }
# ifdef FC_HINT_STYLE
          else if (strcmp (name, "Xft/HintStyle") == 0)
            {
              settings->seen |= SEEN_HINTSTYLE;
              if (strcmp (sval, "hintnone") == 0)
                settings->hintstyle = FC_HINT_NONE;
              else if (strcmp (sval, "hintslight") == 0)
                settings->hintstyle = FC_HINT_SLIGHT;
              else if (strcmp (sval, "hintmedium") == 0)
                settings->hintstyle = FC_HINT_MEDIUM;
              else if (strcmp (sval, "hintfull") == 0)
                settings->hintstyle = FC_HINT_FULL;
              else
                settings->seen &= ~SEEN_HINTSTYLE;
            }
# endif
          else if (strcmp (name, "Xft/RGBA") == 0)
            {
              settings->seen |= SEEN_RGBA;
              if (strcmp (sval, "none") == 0)
                settings->rgba = FC_RGBA_NONE;
              else if (strcmp (sval, "rgb") == 0)
                settings->rgba = FC_RGBA_RGB;
              else if (strcmp (sval, "bgr") == 0)
                settings->rgba = FC_RGBA_BGR;
              else if (strcmp (sval, "vrgb") == 0)
                settings->rgba = FC_RGBA_VRGB;
              else if (strcmp (sval, "vbgr") == 0)
                settings->rgba = FC_RGBA_VBGR;
              else
                settings->seen &= ~SEEN_RGBA;
            }
          else if (strcmp (name, "Xft/DPI") == 0)
            {
              settings->seen |= SEEN_DPI;
              settings->dpi = (double)ival/1024.0;
            }
          else if (strcmp (name, "Xft/lcdfilter") == 0)
            {
              settings->seen |= SEEN_LCDFILTER;
              if (strcmp (sval, "none") == 0)
                settings->lcdfilter = FC_LCD_NONE;
              else if (strcmp (sval, "lcddefault") == 0)
                settings->lcdfilter = FC_LCD_DEFAULT;
              else
                settings->seen &= ~SEEN_LCDFILTER;
            }
#endif /* HAVE_XFT */
        }
    }

  return settings_seen;
}
Ejemplo n.º 12
0
static void
monitor_daemon(pid_t daemon_pid)
{
    /* XXX Should log daemon's stderr output at startup time. */
    time_t last_restart;
    char *status_msg;
    int crashes;
    bool child_ready = true;

    set_subprogram_name("monitor");
    status_msg = xstrdup("healthy");
    last_restart = TIME_MIN;
    crashes = 0;
    for (;;) {
        int retval;
        int status;

        ovs_cmdl_proctitle_set("monitoring pid %lu (%s)",
                               (unsigned long int) daemon_pid, status_msg);

        if (child_ready) {
            do {
                retval = waitpid(daemon_pid, &status, 0);
            } while (retval == -1 && errno == EINTR);
            if (retval == -1) {
                VLOG_FATAL("waitpid failed (%s)", ovs_strerror(errno));
            }
        }

        if (!child_ready || retval == daemon_pid) {
            char *s = process_status_msg(status);
            if (should_restart(status)) {
                free(status_msg);
                status_msg = xasprintf("%d crashes: pid %lu died, %s",
                                       ++crashes,
                                       (unsigned long int) daemon_pid, s);
                free(s);

                if (WCOREDUMP(status)) {
                    /* Disable further core dumps to save disk space. */
                    struct rlimit r;

                    r.rlim_cur = 0;
                    r.rlim_max = 0;
                    if (setrlimit(RLIMIT_CORE, &r) == -1) {
                        VLOG_WARN("failed to disable core dumps: %s",
                                  ovs_strerror(errno));
                    }
                }

                /* Throttle restarts to no more than once every 10 seconds. */
                if (time(NULL) < last_restart + 10) {
                    VLOG_WARN("%s, waiting until 10 seconds since last "
                              "restart", status_msg);
                    for (;;) {
                        time_t now = time(NULL);
                        time_t wakeup = last_restart + 10;
                        if (now >= wakeup) {
                            break;
                        }
                        xsleep(wakeup - now);
                    }
                }
                last_restart = time(NULL);

                VLOG_ERR("%s, restarting", status_msg);
                child_ready = !fork_and_wait_for_startup(&daemonize_fd,
                                                         &daemon_pid);
                if (child_ready && !daemon_pid) {
                    /* Child process needs to break out of monitoring
                     * loop. */
                    break;
                }
            } else {
                VLOG_INFO("pid %lu died, %s, exiting",
                          (unsigned long int) daemon_pid, s);
                free(s);
                exit(0);
            }
        }
    }
    free(status_msg);

    /* Running in new daemon process. */
    ovs_cmdl_proctitle_restore();
    set_subprogram_name("");
}
Ejemplo n.º 13
0
int
enqueue(int argc, char *argv[])
{
	int			 i, ch, tflag = 0, noheader;
	char			*fake_from = NULL, *buf;
	struct passwd		*pw;
	FILE			*fp, *fout;
	size_t			 len, envid_sz = 0;
	int			 fd;
	char			 sfn[] = "/tmp/smtpd.XXXXXXXXXX";
	char			*line;
	int			 dotted;
	int			 inheaders = 0;
	int			 save_argc;
	char			**save_argv;

	memset(&msg, 0, sizeof(msg));
	time(&timestamp);

	save_argc = argc;
	save_argv = argv;

	while ((ch = getopt(argc, argv,
	    "A:B:b:E::e:F:f:iJ::L:mN:o:p:qR:tvV:x")) != -1) {
		switch (ch) {
		case 'f':
			fake_from = optarg;
			break;
		case 'F':
			msg.fromname = optarg;
			break;
		case 'N':
			msg.dsn_notify = optarg;
			break;
		case 'R':
			msg.dsn_ret = optarg;
			break;
		case 't':
			tflag = 1;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'V':
			msg.dsn_envid = optarg;
			break;
		/* all remaining: ignored, sendmail compat */
		case 'A':
		case 'B':
		case 'b':
		case 'E':
		case 'e':
		case 'i':
		case 'L':
		case 'm':
		case 'o':
		case 'p':
		case 'x':
			break;
		case 'q':
			/* XXX: implement "process all now" */
			return (EX_SOFTWARE);
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (getmailname(host, sizeof(host)) == -1)
		err(EX_NOHOST, "getmailname");
	if ((pw = getpwuid(getuid())) == NULL)
		user = "******";
	if (pw != NULL)
		user = xstrdup(pw->pw_name, "enqueue");

	build_from(fake_from, pw);

	while (argc > 0) {
		rcpt_add(argv[0]);
		argv++;
		argc--;
	}

	if ((fd = mkstemp(sfn)) == -1 ||
	    (fp = fdopen(fd, "w+")) == NULL) {
		int saved_errno = errno;
		if (fd != -1) {
			unlink(sfn);
			close(fd);
		}
		errc(EX_UNAVAILABLE, saved_errno, "mkstemp");
	}
	unlink(sfn);
	noheader = parse_message(stdin, fake_from == NULL, tflag, fp);

	if (msg.rcpt_cnt == 0)
		errx(EX_SOFTWARE, "no recipients");

	/* init session */
	rewind(fp);

	/* try to connect */
	/* If the server is not running, enqueue the message offline */

	if (!srv_connect())
		return (enqueue_offline(save_argc, save_argv, fp));

	if ((msg.fd = open_connection()) == -1)
		errx(EX_UNAVAILABLE, "server too busy");

	fout = fdopen(msg.fd, "a+");
	if (fout == NULL)
		err(EX_UNAVAILABLE, "fdopen");

	/* 
	 * We need to call get_responses after every command because we don't
	 * support PIPELINING on the server-side yet.
	 */

	/* banner */
	get_responses(fout, 1);

	send_line(fout, verbose, "EHLO localhost\n");
	get_responses(fout, 1);

	if (msg.dsn_envid != NULL)
		envid_sz = strlen(msg.dsn_envid);

	send_line(fout, verbose, "MAIL FROM:<%s> %s%s %s%s\n",
	    msg.from,
	    msg.dsn_ret ? "RET=" : "",
	    msg.dsn_ret ? msg.dsn_ret : "",
	    envid_sz ? "ENVID=" : "",
	    envid_sz ? msg.dsn_envid : "");
	get_responses(fout, 1);

	for (i = 0; i < msg.rcpt_cnt; i++) {
		send_line(fout, verbose, "RCPT TO:<%s> %s%s\n",
		    msg.rcpts[i],
		    msg.dsn_notify ? "NOTIFY=" : "",
		    msg.dsn_notify ? msg.dsn_notify : "");
		get_responses(fout, 1);
	}

	send_line(fout, verbose, "DATA\n");
	get_responses(fout, 1);

	/* add From */
	if (!msg.saw_from)
		send_line(fout, 0, "From: %s%s<%s>\n",
		    msg.fromname ? msg.fromname : "",
		    msg.fromname ? " " : "",
		    msg.from);

	/* add Date */
	if (!msg.saw_date)
		send_line(fout, 0, "Date: %s\n", time_to_text(timestamp));

	/* add Message-Id */
	if (!msg.saw_msgid)
		send_line(fout, 0, "Message-Id: <%"PRIu64".enqueue@%s>\n",
		    generate_uid(), host);

	if (msg.need_linesplit) {
		/* we will always need to mime encode for long lines */
		if (!msg.saw_mime_version)
			send_line(fout, 0, "MIME-Version: 1.0\n");
		if (!msg.saw_content_type)
			send_line(fout, 0, "Content-Type: text/plain; "
			    "charset=unknown-8bit\n");
		if (!msg.saw_content_disposition)
			send_line(fout, 0, "Content-Disposition: inline\n");
		if (!msg.saw_content_transfer_encoding)
			send_line(fout, 0, "Content-Transfer-Encoding: "
			    "quoted-printable\n");
	}

	/* add separating newline */
	if (noheader)
		send_line(fout, 0, "\n");
	else
		inheaders = 1;

	for (;;) {
		buf = fgetln(fp, &len);
		if (buf == NULL && ferror(fp))
			err(EX_UNAVAILABLE, "fgetln");
		if (buf == NULL && feof(fp))
			break;
		/* newlines have been normalized on first parsing */
		if (buf[len-1] != '\n')
			errx(EX_SOFTWARE, "expect EOL");

		dotted = 0;
		if (buf[0] == '.') {
			fputc('.', fout);
			dotted = 1;
		}

		line = buf;

		if (msg.saw_content_transfer_encoding || noheader ||
		    inheaders || !msg.need_linesplit) {
			if (inheaders)
				send_header(fout, line, len);
			else
				send_line(fout, 0, "%.*s", (int)len, line);
			if (inheaders && buf[0] == '\n')
				inheaders = 0;
			continue;
		}

		/* we don't have a content transfer encoding, use our default */
		do {
			if (len < LINESPLIT) {
				qp_encoded_write(fout, line, len);
				break;
			}
			else {
				qp_encoded_write(fout, line,
				    LINESPLIT - 2 - dotted);
				send_line(fout, 0, "=\n");
				line += LINESPLIT - 2 - dotted;
				len -= LINESPLIT - 2 - dotted;
			}
		} while (len);
	}
	send_line(fout, verbose, ".\n");
	get_responses(fout, 1);

	send_line(fout, verbose, "QUIT\n");
	get_responses(fout, 1);

	fclose(fp);
	fclose(fout);

	exit(EX_OK);
}
Ejemplo n.º 14
0
/**
 * basil_geometry - Check node attributes, resolve (X,Y,Z) coordinates.
 *
 * Checks both SDB database and ALPS inventory for consistency. The inventory
 * part is identical to basil_inventory(), with the difference of being called
 * before valid bitmaps exist, from select_g_node_init().
 * Its dependencies are:
 * - it needs reset_job_bitmaps() in order to rebuild node_bitmap fields,
 * - it relies on _sync_nodes_to_jobs() to
 *   o kill active jobs on nodes now marked DOWN,
 *   o reset node state to ALLOCATED if it has been marked IDLE here (which is
 *     an error case, since there is no longer an ALPS reservation for the job,
 *     this is caught by the subsequent basil_inventory()).
 */
extern int basil_geometry(struct node_record *node_ptr_array, int node_cnt)
{
    struct node_record *node_ptr, *end = node_ptr_array + node_cnt;
    enum basil_version version = get_basil_version();
    struct basil_inventory *inv;

    /* General mySQL */
    MYSQL		*handle;
    MYSQL_STMT	*stmt = NULL;
    /* Input parameters */
    unsigned int	node_id;
    /*
     * Use a left outer join here since the attributes table may not be
     * populated for a given nodeid (e.g. when the node has been disabled
     * on the SMW via 'xtcli disable').
     * The processor table has more authoritative information, if a nodeid
     * is not listed there, it does not exist.
     */
    const char query[] =	"SELECT x_coord, y_coord, z_coord,"
                            "       cab_position, cab_row, cage, slot, cpu,"
                            "	LOG2(coremask+1), availmem, "
                            "       processor_type  "
                            "FROM  processor LEFT JOIN attributes "
                            "ON    processor_id = nodeid "
                            "WHERE processor_id = ? ";
    const int	PARAM_COUNT = 1;	/* node id */
    MYSQL_BIND	params[PARAM_COUNT];

    int		x_coord, y_coord, z_coord;
    int		cab, row, cage, slot, cpu;
    unsigned int	node_cpus, node_mem;
    char		proc_type[BASIL_STRING_SHORT];
    MYSQL_BIND	bind_cols[COLUMN_COUNT];
    my_bool		is_null[COLUMN_COUNT];
    my_bool		is_error[COLUMN_COUNT];
    int		is_gemini, i;

    memset(params, 0, sizeof(params));
    params[0].buffer_type = MYSQL_TYPE_LONG;
    params[0].is_unsigned = true;
    params[0].is_null     = (my_bool *)0;
    params[0].buffer      = (char *)&node_id;

    memset(bind_cols, 0, sizeof(bind_cols));
    for (i = 0; i < COLUMN_COUNT; i ++) {
        bind_cols[i].is_null = &is_null[i];
        bind_cols[i].error   = &is_error[i];

        if (i == COL_TYPE) {
            bind_cols[i].buffer_type   = MYSQL_TYPE_STRING;
            bind_cols[i].buffer_length = sizeof(proc_type);
            bind_cols[i].buffer	   = proc_type;
        } else {
            bind_cols[i].buffer_type   = MYSQL_TYPE_LONG;
            bind_cols[i].is_unsigned   = (i >= COL_CORES);
        }
    }
    bind_cols[COL_X].buffer	     = (char *)&x_coord;
    bind_cols[COL_Y].buffer	     = (char *)&y_coord;
    bind_cols[COL_Z].buffer	     = (char *)&z_coord;
    bind_cols[COL_CAB].buffer    = (char *)&cab;
    bind_cols[COL_ROW].buffer    = (char *)&row;
    bind_cols[COL_CAGE].buffer   = (char *)&cage;
    bind_cols[COL_SLOT].buffer   = (char *)&slot;
    bind_cols[COL_CPU].buffer    = (char *)&cpu;
    bind_cols[COL_CORES].buffer  = (char *)&node_cpus;
    bind_cols[COL_MEMORY].buffer = (char *)&node_mem;

    inv = get_full_inventory(version);
    if (inv == NULL)
        fatal("failed to get initial BASIL inventory");

    info("BASIL %s initial INVENTORY: %d/%d batch nodes available",
         bv_names_long[version], inv->batch_avail, inv->batch_total);

    handle = cray_connect_sdb();
    if (handle == NULL)
        fatal("can not connect to XTAdmin database on the SDB");

    is_gemini = cray_is_gemini_system(handle);
    if (is_gemini < 0)
        fatal("can not determine Cray XT/XE system type");

    stmt = prepare_stmt(handle, query, params, PARAM_COUNT,
                        bind_cols, COLUMN_COUNT);
    if (stmt == NULL)
        fatal("can not prepare statement to resolve Cray coordinates");

    for (node_ptr = node_record_table_ptr; node_ptr < end; node_ptr++) {
        struct basil_node *node;
        char *reason = NULL;

        if ((node_ptr->name == NULL) ||
                (sscanf(node_ptr->name, "nid%05u", &node_id) != 1)) {
            error("can not read basil_node_id from %s",
                  node_ptr->name);
            continue;
        }

        if (exec_stmt(stmt, query, bind_cols, COLUMN_COUNT) < 0)
            fatal("can not resolve %s coordinates", node_ptr->name);

        if (fetch_stmt(stmt) == 0) {
#if _DEBUG
            info("proc_type:%s cpus:%u memory:%u",
                 proc_type, node_cpus, node_mem);
            info("row:%u cage:%u slot:%u cpu:%u xyz:%u:%u:%u",
                 row, cage, slot, cpu, x_coord, y_coord, z_coord);
#endif
            if (strcmp(proc_type, "compute") != 0) {
                /*
                 * Switching a compute node to be a service node
                 * can not happen at runtime: requires a reboot.
                 */
                fatal("Node '%s' is a %s node. "
                      "Only compute nodes can appear in slurm.conf.",
                      node_ptr->name, proc_type);
            } else if (is_null[COL_CORES] || is_null[COL_MEMORY]) {
                /*
                 * This can happen if a node has been disabled
                 * on the SMW (using 'xtcli disable <nid>'). The
                 * node will still be listed in the 'processor'
                 * table, but have no 'attributes' entry (NULL
                 * values for CPUs/memory). Also, the node will
                 * be invisible to ALPS, which is why we need to
                 * set it down here already.
                 */
                node_cpus = node_mem = 0;
                reason = "node data unknown - disabled on SMW?";
            } else if (is_null[COL_X] || is_null[COL_Y]
                       || is_null[COL_Z]) {
                /*
                 * Similar case to the one above, observed when
                 * a blade has been removed. Node will not
                 * likely show up in ALPS.
                 */
                x_coord = y_coord = z_coord = 0;
                reason = "unknown coordinates - hardware failure?";
            } else if (node_cpus < node_ptr->config_ptr->cpus) {
                /*
                 * FIXME: Might reconsider this policy.
                 *
                 * FastSchedule is ignored here, it requires the
                 * slurm.conf to be consistent with hardware.
                 *
                 * Assumption is that CPU/Memory do not change
                 * at runtime (Cray has no hot-swappable parts).
                 *
                 * Hence checking it in basil_inventory() would
                 * mean a lot of runtime overhead.
                 */
                fatal("slurm.conf: node %s has only Procs=%d",
                      node_ptr->name, node_cpus);
            } else if (node_mem < node_ptr->config_ptr->real_memory) {
                fatal("slurm.conf: node %s has RealMemory=%d",
                      node_ptr->name, node_mem);
            }

        } else if (is_gemini) {
            fatal("Non-existing Gemini node '%s' in slurm.conf",
                  node_ptr->name);
        } else {
            fatal("Non-existing SeaStar node '%s' in slurm.conf",
                  node_ptr->name);
        }

        if (!is_gemini) {
            /*
             * SeaStar: each node has unique coordinates
             */
            if (node_ptr->arch == NULL)
                node_ptr->arch = xstrdup("XT");
        } else {
            /*
             * Gemini: each 2 nodes share the same network
             * interface (i.e., nodes 0/1 and 2/3 each have
             * the same coordinates).
             */
            if (node_ptr->arch == NULL)
                node_ptr->arch = xstrdup("XE");
        }

        xfree(node_ptr->node_hostname);
        xfree(node_ptr->comm_name);
        /*
         * Convention: since we are using SLURM in frontend-mode,
         *             we use Node{Addr,HostName} as follows.
         *
         * NodeAddr:      <X><Y><Z> coordinates in base-36 encoding
         *
         * NodeHostName:  c#-#c#s#n# using the  NID convention
         *                <cabinet>-<row><chassis><slot><node>
         * - each cabinet can accommodate 3 chassis (c1..c3)
         * - each chassis has 8 slots               (s0..s7)
         * - each slot contains 2 or 4 nodes        (n0..n3)
         *   o either 2 service nodes (n0/n3)
         *   o or 4 compute nodes     (n0..n3)
         *   o or 2 gemini chips      (g0/g1 serving n0..n3)
         *
         * Example: c0-0c1s0n1
         *          - c0- = cabinet 0
         *          - 0   = row     0
         *          - c1  = chassis 1
         *          - s0  = slot    0
         *          - n1  = node    1
         */
        node_ptr->node_hostname = xstrdup_printf("c%u-%uc%us%un%u", cab,
                                  row, cage, slot, cpu);
        node_ptr->comm_name = xstrdup_printf("%c%c%c",
                                             _enc_coord(x_coord),
                                             _enc_coord(y_coord),
                                             _enc_coord(z_coord));
        dim_size[0] = MAX(dim_size[0], (x_coord - 1));
        dim_size[1] = MAX(dim_size[1], (y_coord - 1));
        dim_size[2] = MAX(dim_size[2], (z_coord - 1));
#if _DEBUG
        info("%s  %s  %s  cpus=%u, mem=%u", node_ptr->name,
             node_ptr->node_hostname, node_ptr->comm_name,
             node_cpus, node_mem);
#endif
        /*
         * Check the current state reported by ALPS inventory, unless it
         * is already evident that the node has some other problem.
         */
        if (reason == NULL) {
            for (node = inv->f->node_head; node; node = node->next)
                if (node->node_id == node_id)
                    break;
            if (node == NULL) {
                reason = "not visible to ALPS - check hardware";
            } else if (node->state == BNS_DOWN) {
                reason = "ALPS marked it DOWN";
            } else if (node->state == BNS_UNAVAIL) {
                reason = "node is UNAVAILABLE";
            } else if (node->state == BNS_ROUTE) {
                reason = "node does ROUTING";
            } else if (node->state == BNS_SUSPECT) {
                reason = "entered SUSPECT mode";
            } else if (node->state == BNS_ADMINDOWN) {
                reason = "node is ADMINDOWN";
            } else if (node->state != BNS_UP) {
                reason = "state not UP";
            } else if (node->role != BNR_BATCH) {
                reason = "mode not BATCH";
            } else if (node->arch != BNA_XT) {
                reason = "arch not XT/XE";
            }
        }

        /* Base state entirely derives from ALPS */
        node_ptr->node_state &= NODE_STATE_FLAGS;
        if (reason) {
            if (node_ptr->reason) {
                debug("Initial DOWN node %s - %s",
                      node_ptr->name, node_ptr->reason);
            } else {
                info("Initial DOWN node %s - %s",
                     node_ptr->name, reason);
                node_ptr->reason = xstrdup(reason);
            }
            node_ptr->node_state |= NODE_STATE_DOWN;
        } else {
            if (node_is_allocated(node))
                node_ptr->node_state |= NODE_STATE_ALLOCATED;
            else
                node_ptr->node_state |= NODE_STATE_IDLE;
            xfree(node_ptr->reason);
        }

        free_stmt_result(stmt);
    }

    if (stmt_close(stmt))
        error("error closing statement: %s", mysql_stmt_error(stmt));
    cray_close_sdb(handle);
    free_inv(inv);

    return SLURM_SUCCESS;
}
Ejemplo n.º 15
0
void
mi_cmd_disassemble (char *command, char **argv, int argc)
{
  struct gdbarch *gdbarch = get_current_arch ();
  struct ui_out *uiout = current_uiout;
  CORE_ADDR start;

  int mode, disasm_flags;
  struct symtab *s;

  /* Which options have we processed ... */
  int file_seen = 0;
  int line_seen = 0;
  int num_seen = 0;
  int start_seen = 0;
  int end_seen = 0;

  /* ... and their corresponding value. */
  char *file_string = NULL;
  int line_num = -1;
  int how_many = -1;
  CORE_ADDR low = 0;
  CORE_ADDR high = 0;
  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);

  /* Options processing stuff.  */
  int oind = 0;
  char *oarg;
  enum opt
  {
    FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT
  };
  static const struct mi_opt opts[] =
    {
      {"f", FILE_OPT, 1},
      {"l", LINE_OPT, 1},
      {"n", NUM_OPT, 1},
      {"s", START_OPT, 1},
      {"e", END_OPT, 1},
      { 0, 0, 0 }
    };

  /* Get the options with their arguments. Keep track of what we
     encountered.  */
  while (1)
    {
      int opt = mi_getopt ("-data-disassemble", argc, argv, opts,
			   &oind, &oarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case FILE_OPT:
	  file_string = xstrdup (oarg);
	  file_seen = 1;
	  make_cleanup (xfree, file_string);
	  break;
	case LINE_OPT:
	  line_num = atoi (oarg);
	  line_seen = 1;
	  break;
	case NUM_OPT:
	  how_many = atoi (oarg);
	  num_seen = 1;
	  break;
	case START_OPT:
	  low = parse_and_eval_address (oarg);
	  start_seen = 1;
	  break;
	case END_OPT:
	  high = parse_and_eval_address (oarg);
	  end_seen = 1;
	  break;
	}
    }
  argv += oind;
  argc -= oind;

  /* Allow only filename + linenum (with how_many which is not
     required) OR start_addr + end_addr.  */

  if (!((line_seen && file_seen && num_seen && !start_seen && !end_seen)
	|| (line_seen && file_seen && !num_seen && !start_seen && !end_seen)
	|| (!line_seen && !file_seen && !num_seen && start_seen && end_seen)))
    error (_("-data-disassemble: Usage: ( [-f filename -l linenum [-n "
	     "howmany]] | [-s startaddr -e endaddr]) [--] mode."));

  if (argc != 1)
    error (_("-data-disassemble: Usage: [-f filename -l linenum "
	     "[-n howmany]] [-s startaddr -e endaddr] [--] mode."));

  mode = atoi (argv[0]);
  if (mode < 0 || mode > 3)
    error (_("-data-disassemble: Mode argument must be 0, 1, 2, or 3."));

  /* Convert the mode into a set of disassembly flags.  */

  disasm_flags = 0;
  if (mode & 0x1)
    disasm_flags |= DISASSEMBLY_SOURCE;
  if (mode & 0x2)
    disasm_flags |= DISASSEMBLY_RAW_INSN;

  /* We must get the function beginning and end where line_num is
     contained.  */

  if (line_seen && file_seen)
    {
      s = lookup_symtab (file_string);
      if (s == NULL)
	error (_("-data-disassemble: Invalid filename."));
      if (!find_line_pc (s, line_num, &start))
	error (_("-data-disassemble: Invalid line number"));
      if (find_pc_partial_function (start, NULL, &low, &high) == 0)
	error (_("-data-disassemble: "
		 "No function contains specified address"));
    }

  gdb_disassembly (gdbarch, uiout,
  		   file_string,
  		   disasm_flags,
		   how_many, low, high);

  do_cleanups (cleanups);
}
Ejemplo n.º 16
0
static char *
authmethods_get(void)
{
	Buffer b;
	char *list;
	int i;
	int sufficient = 0;
	int required = 0;
	int authenticated = 0;
	int partial = 0;

	/*
	 * If at least one method succeeded partially then at least one
	 * authmethod will be required and only required methods should
	 * continue.
	 */
	for (i = 0; authmethods[i] != NULL; i++) {
		if (authmethods[i]->authenticated)
			authenticated++;
		if (authmethods[i]->required)
			required++;
		if (authmethods[i]->sufficient)
			sufficient++;
	}

	partial = (required + sufficient) > 0;

	buffer_init(&b);
	for (i = 0; authmethods[i] != NULL; i++) {
		if (strcmp(authmethods[i]->name, "none") == 0)
			continue;
		if (required && !authmethods[i]->required)
			continue;
		if (sufficient && !required && !authmethods[i]->sufficient)
			continue;
		if (authmethods[i]->not_again)
			continue;

		if (authmethods[i]->required) {
			if (buffer_len(&b) > 0)
				buffer_append(&b, ",", 1);
			buffer_append(&b, authmethods[i]->name,
			    strlen(authmethods[i]->name));
			continue;
		}

		/*
		 * A method can be enabled (marked sufficient)
		 * dynamically provided that at least one other method
		 * has succeeded partially.
		 */
		if ((partial && authmethods[i]->sufficient) ||
		    (authmethods[i]->enabled != NULL &&
		    *(authmethods[i]->enabled) != 0)) {
			if (buffer_len(&b) > 0)
				buffer_append(&b, ",", 1);
			buffer_append(&b, authmethods[i]->name,
			    strlen(authmethods[i]->name));
		}
	}
	buffer_append(&b, "\0", 1);
	list = xstrdup(buffer_ptr(&b));
	buffer_free(&b);
	return list;
}
Ejemplo n.º 17
0
rpmRC rpmgiNext(/*@null@*/ rpmgi gi)
{
    char hnum[32];
    rpmRC rpmrc = RPMRC_NOTFOUND;
    int xx;

    if (gi == NULL)
	return rpmrc;

if (_rpmgi_debug)
fprintf(stderr, "--> %s(%p) tag %s\n", __FUNCTION__, gi, tagName(gi->tag));

    /* Free header from previous iteration. */
    (void)headerFree(gi->h);
    gi->h = NULL;
    gi->hdrPath = _free(gi->hdrPath);
    hnum[0] = '\0';

    if (++gi->i >= 0)
    switch (gi->tag) {
    default:
	if (!gi->active) {
nextkey:
	    rpmrc = rpmgiLoadNextKey(gi);
	    if (rpmrc != RPMRC_OK)
		goto enditer;
	    rpmrc = rpmgiInitFilter(gi);
	    if (rpmrc != RPMRC_OK || gi->mi == NULL) {
		gi->mi = rpmmiFree(gi->mi);	/* XXX unnecessary */
		gi->i++;
		goto nextkey;
	    }
	    rpmrc = RPMRC_NOTFOUND;	/* XXX hack */
	    gi->active = 1;
	}
	if (gi->mi != NULL) {	/* XXX unnecessary */
	    Header h = rpmmiNext(gi->mi);
	    if (h != NULL) {
		if (!(gi->flags & RPMGI_NOHEADER))
		    gi->h = headerLink(h);
		/* XXX use h->origin instead. */
		sprintf(hnum, "%u", (unsigned)rpmmiInstance(gi->mi));
		gi->hdrPath = rpmExpand("rpmdb h# ", hnum, NULL);
		rpmrc = RPMRC_OK;
		/* XXX header reference held by iterator, so no headerFree */
	    }
	}
	if (rpmrc != RPMRC_OK) {
	    gi->mi = rpmmiFree(gi->mi);
	    goto nextkey;
	}
	break;
    case RPMDBI_PACKAGES:
	if (!gi->active) {
	    rpmrc = rpmgiInitFilter(gi);
	    if (rpmrc != RPMRC_OK) {
		gi->mi = rpmmiFree(gi->mi);	/* XXX unnecessary */
		goto enditer;
	    }
	    rpmrc = RPMRC_NOTFOUND;	/* XXX hack */
	    gi->active = 1;
	}
	if (gi->mi != NULL) {	/* XXX unnecessary */
	    Header h = rpmmiNext(gi->mi);
	    if (h != NULL) {
		if (!(gi->flags & RPMGI_NOHEADER))
		    gi->h = headerLink(h);
		/* XXX use h->origin instead. */
		sprintf(hnum, "%u", (unsigned)rpmmiInstance(gi->mi));
		gi->hdrPath = rpmExpand("rpmdb h# ", hnum, NULL);
		rpmrc = RPMRC_OK;
		/* XXX header reference held by iterator, so no headerFree */
	    }
	}
	if (rpmrc != RPMRC_OK) {
	    gi->mi = rpmmiFree(gi->mi);
	    goto enditer;
	}
	break;
    case RPMDBI_REMOVED:
    case RPMDBI_ADDED:
    {	rpmte p;
	int teType = 0;
	const char * teTypeString = NULL;

	if (!gi->active) {
	    gi->tsi = rpmtsiInit(gi->ts);
	    gi->active = 1;
	}
	if ((p = rpmtsiNext(gi->tsi, teType)) != NULL) {
	    Header h = rpmteHeader(p);
	    if (h != NULL)
		if (!(gi->flags & RPMGI_NOHEADER)) {
		    gi->h = headerLink(h);
		switch(rpmteType(p)) {
		case TR_ADDED:	teTypeString = "+++";	/*@switchbreak@*/break;
		case TR_REMOVED: teTypeString = "---";	/*@switchbreak@*/break;
		}
		sprintf(hnum, "%u", (unsigned)gi->i);
		gi->hdrPath = rpmExpand("%s h# ", teTypeString, hnum, NULL);
		rpmrc = RPMRC_OK;
		(void)headerFree(h);
		h = NULL;
	    }
	}
	if (rpmrc != RPMRC_OK) {
	    gi->tsi = rpmtsiFree(gi->tsi);
	    goto enditer;
	}
    }	break;
    case RPMDBI_HDLIST:
	if (!gi->active) {
	    const char * path = rpmExpand("%{?_query_hdlist_path}", NULL);
	    if (path == NULL || *path == '\0') {
		path = _free(path);
		path = rpmExpand(_query_hdlist_path, NULL);
	    }
	    gi->fd = rpmgiOpen(path, "rm%{?_rpmgio}");
	    gi->active = 1;
	    path = _free(path);
	}
	if (gi->fd != NULL) {
	    Header h = NULL;
	    const char item[] = "Header";
	    const char * msg = NULL;
/*@+voidabstract@*/
	    rpmrc = rpmpkgRead(item, gi->fd, &h, &msg);
/*@=voidabstract@*/
	    switch(rpmrc) {
		default:
		    rpmlog(RPMLOG_ERR, "%s: %s: %s\n", "rpmpkgRead", item, msg);
		case RPMRC_NOTFOUND:
		    h = NULL;
		case RPMRC_OK:
		    break;
	    }
	    msg = _free(msg);
	    if (h != NULL) {
		if (!(gi->flags & RPMGI_NOHEADER))
		    gi->h = headerLink(h);
		sprintf(hnum, "%u", (unsigned)gi->i);
		gi->hdrPath = rpmExpand("hdlist h# ", hnum, NULL);
		rpmrc = RPMRC_OK;
		(void)headerFree(h);
		h = NULL;
	    }
	}
	if (rpmrc != RPMRC_OK) {
	    if (gi->fd != NULL) (void) Fclose(gi->fd);
	    gi->fd = NULL;
	    goto enditer;
	}
	break;
    case RPMDBI_ARGLIST:
	/* XXX gi->active initialize? */
if (_rpmgi_debug  < 0)
fprintf(stderr, "*** gi %p\t%p[%d]: %s\n", gi, gi->argv, gi->i, gi->argv[gi->i]);
	/* Read next header, lazily expanding manifests as found. */
	rpmrc = rpmgiLoadReadHeader(gi);

	if (rpmrc != RPMRC_OK)	/* XXX check this */
	    goto enditer;

	gi->hdrPath = xstrdup(gi->argv[gi->i]);
	break;
    case RPMDBI_FTSWALK:
	if (gi->argv == NULL || gi->argv[0] == NULL)		/* HACK */
	    goto enditer;

	if (!gi->active) {
	    gi->ftsp = Fts_open((char *const *)gi->argv, gi->ftsOpts, NULL);
	    /* XXX NULL with open(2)/malloc(3) errno set */
	    gi->active = 1;
	}

	/* Read next header, lazily walking file tree. */
	rpmrc = rpmgiWalkReadHeader(gi);

	if (rpmrc != RPMRC_OK) {
	    xx = Fts_close(gi->ftsp);
	    gi->ftsp = NULL;
	    goto enditer;
	}

	if (gi->fts != NULL)
	    gi->hdrPath = xstrdup(gi->fts->fts_path);
	break;
    }

    if ((gi->flags & RPMGI_TSADD) && gi->h != NULL) {
	/* XXX rpmgi hack: Save header in transaction element. */
	if (gi->flags & RPMGI_ERASING) {
	    uint32_t hdrNum = headerGetInstance(gi->h);
	    xx = rpmtsAddEraseElement(gi->ts, gi->h, hdrNum);
	} else
	    xx = rpmtsAddInstallElement(gi->ts, gi->h, (fnpyKey)gi->hdrPath, 2, NULL);
    }
    goto exit;

enditer:
    if (gi->flags & RPMGI_TSORDER) {
	rpmts ts = gi->ts;

	/* Block access to indices used for depsolving. */
	if (!(gi->flags & RPMGI_ERASING)) {
	    (void) rpmtsSetGoal(ts, TSM_INSTALL);
	    xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMDBI_DEPCACHE);
	    xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMTAG_BASENAMES);
	    xx = rpmdbBlockDBI(rpmtsGetRdb(ts), -RPMTAG_PROVIDENAME);
	} else {
	    (void) rpmtsSetGoal(ts, TSM_ERASE);
	}

	/* XXX query/verify will need the glop added to a buffer instead. */
	xx = rpmcliInstallCheck(ts);
	xx = rpmcliInstallSuggests(ts);

	/* Permit access to indices used for depsolving. */
	if (!(gi->flags & RPMGI_ERASING)) {
	    xx = rpmdbBlockDBI(rpmtsGetRdb(ts), RPMTAG_PROVIDENAME);
	    xx = rpmdbBlockDBI(rpmtsGetRdb(ts), RPMTAG_BASENAMES);
	    xx = rpmdbBlockDBI(rpmtsGetRdb(ts), RPMDBI_DEPCACHE);
	}

	/* XXX Display dependency loops with rpm -qvT. */
	if (rpmIsVerbose())
	    (void) rpmtsSetDFlags(ts, (rpmtsDFlags(ts) | RPMDEPS_FLAG_DEPLOOPS));

	xx = (*gi->tsOrder) (ts);

	/* XXX hackery alert! */
	gi->tag = (!(gi->flags & RPMGI_ERASING) ? RPMDBI_ADDED : RPMDBI_REMOVED);
	gi->flags &= ~(RPMGI_TSADD|RPMGI_TSORDER);

    }

    (void)headerFree(gi->h);
    gi->h = NULL;
    gi->hdrPath = _free(gi->hdrPath);
    gi->i = -1;
    gi->active = 0;

exit:
if (_rpmgi_debug)
fprintf(stderr, "<-- %s(%p) rc %d\n", __FUNCTION__, gi, rpmrc);
    return rpmrc;
}
Ejemplo n.º 18
0
/* Execute a script, wait for termination and return its stdout.
 * script_name IN - Name of program being run (e.g. "StartStageIn")
 * script_path IN - Fully qualified program of the program to execute
 * script_args IN - Arguments to the script
 * max_wait IN - Maximum time to wait in milliseconds,
 *		 -1 for no limit (asynchronous)
 * data_in IN - data to use as program STDIN (NULL if not STDIN)
 * status OUT - Job exit code
 * Return stdout+stderr of spawned program, value must be xfreed. */
extern char *power_run_script(char *script_name, char *script_path,
			      char **script_argv, int max_wait, char *data_in,
			      int *status)
{
	int i, new_wait, resp_size = 0, resp_offset = 0;
	int send_size = 0, send_offset = 0;
	pid_t cpid;
	char *resp = NULL;
	int fd_stdout[2] = { -1, -1 };
	int fd_stdin[2] = { -1, -1 };

	if ((script_path == NULL) || (script_path[0] == '\0')) {
		error("%s: no script specified", __func__);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (slurm_get_debug_flags() & DEBUG_FLAG_POWER) {
		for (i = 0; i < 10; i++) {
			if (!script_argv[i])
				break;
		}
		if (i == 0) {
			info("%s:", __func__);
		} else if (i == 1) {
			info("%s: %s", __func__, script_name);
		} else if (i == 2) {
			info("%s: %s %s", __func__, script_name,
			     script_argv[1]);
		} else if (i == 3) {
			info("%s: %s %s %s", __func__, script_name,
			     script_argv[1], script_argv[2]);
		} else if (i == 4) {
			info("%s: %s %s %s %s", __func__, script_name,
			     script_argv[1], script_argv[2], script_argv[3]);
		} else if (i == 5) {
			info("%s: %s %s %s %s %s", __func__, script_name,
			     script_argv[1], script_argv[2], script_argv[3],
			     script_argv[4]);
		} else if (i == 6) {
			info("%s: %s %s %s %s %s %s", __func__, script_name,
			     script_argv[1], script_argv[2], script_argv[3],
			     script_argv[4], script_argv[5]);
		} else if (i == 7) {
			info("%s: %s %s %s %s %s %s %s", __func__,
			     script_name, script_argv[1], script_argv[2],
			     script_argv[3], script_argv[4], script_argv[5],
			     script_argv[6]);
		} else {	/* 8 or more args here, truncate as needed */
			info("%s: %s %s %s %s %s %s %s %s", __func__,
			     script_name, script_argv[1], script_argv[2],
			     script_argv[3], script_argv[4], script_argv[5],
			     script_argv[6], script_argv[7]);
		}
		if (data_in)
			info("%s: %s", __func__, data_in);
	}
	if (script_path[0] != '/') {
		error("%s: %s is not fully qualified pathname (%s)",
		      __func__, script_name, script_path);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (access(script_path, R_OK | X_OK) < 0) {
		error("%s: %s can not be executed (%s) %m",
		      __func__, script_name, script_path);
		*status = 127;
		resp = xstrdup("Slurm burst buffer configuration error");
		return resp;
	}
	if (data_in) {
		if (pipe(fd_stdin) != 0) {
			error("%s: pipe(): %m", __func__);
			*status = 127;
			resp = xstrdup("System error");
			return resp;
		}
	}
	if (max_wait != -1) {
		if (pipe(fd_stdout) != 0) {
			error("%s: pipe(): %m", __func__);
			*status = 127;
			resp = xstrdup("System error");
			return resp;
		}
	}
	if ((cpid = fork()) == 0) {
		int cc;

		cc = sysconf(_SC_OPEN_MAX);
		if (data_in)
			dup2(fd_stdin[0], STDIN_FILENO);
		if (max_wait != -1) {
			dup2(fd_stdout[1], STDERR_FILENO);
			dup2(fd_stdout[1], STDOUT_FILENO);
			for (i = 0; i < cc; i++) {
				if ((i != STDERR_FILENO) &&
				    (i != STDIN_FILENO)  &&
				    (i != STDOUT_FILENO))
					close(i);
			}
		} else {
			for (i = 0; i < cc; i++) {
				if (!data_in || (i != STDERR_FILENO))
					close(i);
			}
			if ((cpid = fork()) < 0)
				exit(127);
			else if (cpid > 0)
				exit(0);
		}
		setpgid(0, 0);
		execv(script_path, script_argv);
		error("%s: execv(%s): %m", __func__, script_path);
		exit(127);
	} else if (cpid < 0) {
		if (data_in) {
			close(fd_stdin[0]);
			close(fd_stdin[1]);
		}
		if (max_wait != -1) {
			close(fd_stdout[0]);
			close(fd_stdout[1]);
		}
		error("%s: fork(): %m", __func__);
	} else if (max_wait != -1) {
		struct pollfd fds;
		time_t start_time = time(NULL);
		if (data_in) {
			close(fd_stdin[0]);
			send_size = strlen(data_in);
			while (send_size > send_offset) {
				i = write(fd_stdin[1], data_in + send_offset,
					 send_size - send_offset);
				if (i == 0) {
					break;
				} else if (i < 0) {
					if (errno == EAGAIN)
						continue;
					error("%s: write(%s): %m", __func__,
					      script_path);
					break;
				} else {
					send_offset += i;
				}
			}
			close(fd_stdin[1]);
		}
		resp_size = 1024;
		resp = xmalloc(resp_size);
		close(fd_stdout[1]);
		while (1) {
			fds.fd = fd_stdout[0];
			fds.events = POLLIN | POLLHUP | POLLRDHUP;
			fds.revents = 0;
			if (max_wait <= 0) {
				new_wait = -1;
			} else {
				new_wait = (time(NULL) - start_time) * 1000
					   + max_wait;
				if (new_wait <= 0)
					break;
			}
			i = poll(&fds, 1, new_wait);
			if (i == 0) {
				error("%s: %s poll timeout",
				      __func__, script_name);
				break;
			} else if (i < 0) {
				error("%s: %s poll:%m", __func__, script_name);
				break;
			}
			if ((fds.revents & POLLIN) == 0)
				break;
			i = read(fd_stdout[0], resp + resp_offset,
				 resp_size - resp_offset);
			if (i == 0) {
				break;
			} else if (i < 0) {
				if (errno == EAGAIN)
					continue;
				error("%s: read(%s): %m", __func__,
				      script_path);
				break;
			} else {
				resp_offset += i;
				if (resp_offset + 1024 >= resp_size) {
					resp_size *= 2;
					resp = xrealloc(resp, resp_size);
				}
			}
		}
		killpg(cpid, SIGKILL);
		waitpid(cpid, status, 0);
		close(fd_stdout[0]);
	} else {
		waitpid(cpid, status, 0);
	}
	return resp;
}
Ejemplo n.º 19
0
static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
{
	struct append_ref_cb *cb = (struct append_ref_cb *)(cb_data);
	struct ref_list *ref_list = cb->ref_list;
	struct ref_item *newitem;
	struct commit *commit;
	int kind, i;
	const char *prefix, *orig_refname = refname;

	static struct {
		int kind;
		const char *prefix;
		int pfxlen;
	} ref_kind[] = {
		{ REF_LOCAL_BRANCH, "refs/heads/", 11 },
		{ REF_REMOTE_BRANCH, "refs/remotes/", 13 },
	};

	/* Detect kind */
	for (i = 0; i < ARRAY_SIZE(ref_kind); i++) {
		prefix = ref_kind[i].prefix;
		if (strncmp(refname, prefix, ref_kind[i].pfxlen))
			continue;
		kind = ref_kind[i].kind;
		refname += ref_kind[i].pfxlen;
		break;
	}
	if (ARRAY_SIZE(ref_kind) <= i)
		return 0;

	/* Don't add types the caller doesn't want */
	if ((kind & ref_list->kinds) == 0)
		return 0;

	if (!match_patterns(cb->pattern, refname))
		return 0;

	commit = NULL;
	if (ref_list->verbose || ref_list->with_commit || merge_filter != NO_FILTER) {
		commit = lookup_commit_reference_gently(sha1, 1);
		if (!commit) {
			cb->ret = error(_("branch '%s' does not point at a commit"), refname);
			return 0;
		}

		/* Filter with with_commit if specified */
		if (!is_descendant_of(commit, ref_list->with_commit))
			return 0;

		if (merge_filter != NO_FILTER)
			add_pending_object(&ref_list->revs,
					   (struct object *)commit, refname);
	}

	ALLOC_GROW(ref_list->list, ref_list->index + 1, ref_list->alloc);

	/* Record the new item */
	newitem = &(ref_list->list[ref_list->index++]);
	newitem->name = xstrdup(refname);
	newitem->kind = kind;
	newitem->commit = commit;
	newitem->len = strlen(refname);
	newitem->dest = resolve_symref(orig_refname, prefix);
	/* adjust for "remotes/" */
	if (newitem->kind == REF_REMOTE_BRANCH &&
	    ref_list->kinds != REF_REMOTE_BRANCH)
		newitem->len += 8;
	if (newitem->len > ref_list->maxwidth)
		ref_list->maxwidth = newitem->len;

	return 0;
}
Ejemplo n.º 20
0
/* Saves the state of all jobcomp data for further indexing retries */
static int _save_state(void)
{
	int fd, rc = SLURM_SUCCESS;
	char *state_file, *new_file, *old_file;
	ListIterator iter;
	static int high_buffer_size = (1024 * 1024);
	Buf buffer = init_buf(high_buffer_size);
	uint32_t job_cnt;
	struct job_node *jnode;

	job_cnt = list_count(jobslist);
	pack32(job_cnt, buffer);
	iter = list_iterator_create(jobslist);
	while ((jnode = (struct job_node *)list_next(iter))) {
		packstr(jnode->serialized_job, buffer);
	}
	list_iterator_destroy(iter);

	state_file = slurm_get_state_save_location();
	if (state_file == NULL || state_file[0] == '\0') {
		error("%s: Could not retrieve StateSaveLocation from conf",
		      plugin_type);
		return SLURM_ERROR;
	}

	if (state_file[strlen(state_file) - 1] != '/')
		xstrcat(state_file, "/");

	xstrcat(state_file, save_state_file);
	old_file = xstrdup(state_file);
	new_file = xstrdup(state_file);
	xstrcat(new_file, ".new");
	xstrcat(old_file, ".old");

	slurm_mutex_lock(&save_lock);
	fd = open(new_file, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR);
	if (fd < 0) {
		error("%s: Can't save jobcomp state, open file %s error %m",
		      plugin_type, new_file);
		rc = SLURM_ERROR;
	} else {
		int pos = 0, nwrite, amount, rc2;
		char *data;
		fd_set_close_on_exec(fd);
		nwrite = get_buf_offset(buffer);
		data = (char *) get_buf_data(buffer);
		high_buffer_size = MAX(nwrite, high_buffer_size);
		while (nwrite > 0) {
			amount = write(fd, &data[pos], nwrite);
			if ((amount < 0) && (errno != EINTR)) {
				error("%s: Error writing file %s, %m",
				      plugin_type, new_file);
				rc = SLURM_ERROR;
				break;
			}
			nwrite -= amount;
			pos += amount;
		}
		if ((rc2 = fsync_and_close(fd, save_state_file)))
			rc = rc2;
	}

	if (rc == SLURM_ERROR)
		(void) unlink(new_file);
	else {
		(void) unlink(old_file);
		if (link(state_file, old_file)) {
			error("%s: Unable to create link for %s -> %s: %m",
			      plugin_type, state_file, old_file);
			rc = SLURM_ERROR;
		}
		(void) unlink(state_file);
		if (link(new_file, state_file)) {
			error("%s: Unable to create link for %s -> %s: %m",
			      plugin_type, new_file, state_file);
			rc = SLURM_ERROR;
		}
		(void) unlink(new_file);
	}

	xfree(old_file);
	xfree(state_file);
	xfree(new_file);
	slurm_mutex_unlock(&save_lock);

	free_buf(buffer);

	return rc;
}
Ejemplo n.º 21
0
extern int launch_p_setup_srun_opt(char **rest)
{
	int command_pos = 0;

	if (opt.test_only) {
		error("--test-only not supported with aprun");
		exit (1);
	} else if (opt.no_alloc) {
		error("--no-allocate not supported with aprun");
		exit (1);
	}
	if (opt.slurmd_debug != LOG_LEVEL_QUIET) {
		error("--slurmd-debug not supported with aprun");
		opt.slurmd_debug = LOG_LEVEL_QUIET;
	}

	opt.argc += 2;

	opt.argv = (char **) xmalloc(opt.argc * sizeof(char *));

	opt.argv[command_pos++] = xstrdup("aprun");
	/* Set default job name to the executable name rather than
	 * "aprun" */
	if (!opt.job_name_set_cmd && (1 < opt.argc)) {
		opt.job_name_set_cmd = true;
		opt.job_name = xstrdup(rest[0]);
	}

	if (opt.cpus_per_task) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-d");
		opt.argv[command_pos++] = xstrdup_printf(
			"%u", opt.cpus_per_task);
	}

	if (opt.shared != (uint16_t)NO_VAL) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-F");
		opt.argv[command_pos++] = xstrdup("share");
	} else if (opt.exclusive) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-F");
		opt.argv[command_pos++] = xstrdup("exclusive");
	}

	if (opt.nodelist) {
		char *nids = _get_nids(opt.nodelist);
		if (nids) {
			opt.argc += 2;
			xrealloc(opt.argv, opt.argc * sizeof(char *));
			opt.argv[command_pos++] = xstrdup("-L");
			opt.argv[command_pos++] = xstrdup(nids);
			xfree(nids);
		}
	}

	if (opt.mem_per_cpu != NO_VAL) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-m");
		opt.argv[command_pos++] = xstrdup_printf("%u", opt.mem_per_cpu);
	}

	if (opt.ntasks_per_node != NO_VAL) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-N");
		opt.argv[command_pos++] = xstrdup_printf(
			"%u", opt.ntasks_per_node);
		if (!opt.ntasks && opt.min_nodes)
			opt.ntasks = opt.ntasks_per_node *  opt.min_nodes;
	} else if (opt.nodes_set && opt.min_nodes) {
		uint32_t tasks_per_node;
		opt.ntasks = MAX(opt.ntasks, opt.min_nodes);
		tasks_per_node = (opt.ntasks + opt.min_nodes - 1) /
			opt.min_nodes;
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-N");
		opt.argv[command_pos++] = xstrdup_printf("%u", tasks_per_node);
	}

	if (opt.ntasks && !opt.multi_prog) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-n");
		opt.argv[command_pos++] = xstrdup_printf("%u", opt.ntasks);
	}

	if ((_verbose < 3) || opt.quiet) {
		opt.argc += 1;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-q");
	}

	if (opt.ntasks_per_socket != NO_VAL) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-S");
		opt.argv[command_pos++] = xstrdup_printf(
			"%u", opt.ntasks_per_socket);
	}

	if (opt.sockets_per_node != NO_VAL) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-sn");
		opt.argv[command_pos++] = xstrdup_printf(
			"%u", opt.sockets_per_node);
	}

	if (opt.mem_bind_type & MEM_BIND_LOCAL) {
		opt.argc += 1;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-ss");
	}

	if (opt.time_limit_str) {
		opt.argc += 2;
		xrealloc(opt.argv, opt.argc * sizeof(char *));
		opt.argv[command_pos++] = xstrdup("-t");
		opt.argv[command_pos++] = xstrdup_printf(
			"%d", time_str2secs(opt.time_limit_str));
	}

	if (opt.launcher_opts) {
		char *save_ptr = NULL, *tok;
		char *tmp = xstrdup(opt.launcher_opts);
		tok = strtok_r(tmp, " ", &save_ptr);
		while (tok) {
			opt.argc++;
			xrealloc(opt.argv, opt.argc * sizeof(char *));
			opt.argv[command_pos++]  = xstrdup(tok);
			tok = strtok_r(NULL, " ", &save_ptr);
		}
		xfree(tmp);
	}


	/* These are srun options that are not supported by aprun, but
	   here just in case in the future they add them.

	   if (opt.disable_status) {
	   xstrcat(cmd_line, " --disable-status");
	   }

	   if (opt.epilog) {
	   xstrfmtcat(cmd_line, " --epilog=", opt.epilog);
	   }

	   if (kill_on_bad_exit) {
	   xstrcat(cmd_line, " --kill-on-bad-exit");
	   }

	   if (label) {
	   xstrcat(cmd_line, " --label");
	   }

	   if (opt.mpi_type) {
	   xstrfmtcat(cmd_line, " --mpi=", opt.mpi_type);
	   }

	   if (opt.msg_timeout) {
	   xstrfmtcat(cmd_line, " --msg-timeout=", opt.msg_timeout);
	   }

	   if (no_allocate) {
	   xstrcat(cmd_line, " --no-allocate");
	   }

	   if (opt.open_mode) {
	   xstrcat(cmd_line, " --open-mode=", opt.open_mode);
	   }

	   if (preserve_env) {
	   xstrcat(cmd_line, " --preserve_env");
	   }


	   if (opt.prolog) {
	   xstrcat(cmd_line, " --prolog=", opt.prolog );
	   }


	   if (opt.propagate) {
	   xstrcat(cmd_line, " --propagate", opt.propagate );
	   }

	   if (pty) {
	   xstrcat(cmd_line, " --pty");
	   }

	   if (quit_on_interrupt) {
	   xstrcat(cmd_line, " --quit-on-interrupt");
	   }


	   if (opt.relative) {
	   xstrfmtcat(cmd_line, " --relative=", opt.relative);
	   }

	   if (restart_dir) {
	   xstrfmtcat(cmd_line, " --restart-dir=", opt.restart_dir);
	   }


	   if (resv_port) {
	   xstrcat(cmd_line, "--resv-port");
	   }

	   if (opt.slurm_debug) {
	   xstrfmtcat(cmd_line, " --slurmd-debug=", opt.slurm_debug);
	   }

	   if (opttask_epilog) {
	   xstrfmtcat(cmd_line, " --task-epilog=", opt.task_epilog);
	   }

	   if (opt.task_prolog) {
	   xstrfmtcat(cmd_line, " --task-prolog", opt.task_prolog);
	   }

	   if (test_only) {
	   xstrcat(cmd_line, " --test-only");
	   }

	   if (unbuffered) {
	   xstrcat(cmd_line, " --unbuffered");
	   }

	*/

	if (opt.multi_prog) {
		_handle_multi_prog(rest[0], &command_pos);
		/* just so we don't tack on the script to the aprun line */
		command_pos = opt.argc;
	}

	return command_pos;
}
Ejemplo n.º 22
0
static char *
unpack_mangled_go_symbol (const char *mangled_name,
			  const char **packagep,
			  const char **objectp,
			  const char **method_type_packagep,
			  const char **method_type_objectp,
			  int *method_type_is_pointerp)
{
  char *buf;
  char *p;
  int len = strlen (mangled_name);
  /* Pointer to last digit in "N<digit(s)>_".  */
  char *saw_digit;
  /* Pointer to "N" if valid "N<digit(s)>_" found.  */
  char *method_type;
  /* Pointer to the first '.'.  */
  char *first_dot;
  /* Pointer to the last '.'.  */
  char *last_dot;
  /* Non-zero if we saw a pointer indicator.  */
  int saw_pointer;

  *packagep = *objectp = NULL;
  *method_type_packagep = *method_type_objectp = NULL;
  *method_type_is_pointerp = 0;

  /* main.init is mangled specially.  */
  if (strcmp (mangled_name, "__go_init_main") == 0)
    {
      char *package = xstrdup ("main");

      *packagep = package;
      *objectp = "init";
      return package;
    }

  /* main.main is mangled specially (missing prefix).  */
  if (strcmp (mangled_name, "main.main") == 0)
    {
      char *package = xstrdup ("main");

      *packagep = package;
      *objectp = "main";
      return package;
    }

  /* We may get passed, e.g., "main.T.Foo", which is *not* mangled.
     Alas it looks exactly like "prefix.package.object."
     To cope for now we only recognize the following prefixes:

     go: the default
     libgo_.*: used by gccgo's runtime

     Thus we don't support -fgo-prefix (except as used by the runtime).  */
  if (!startswith (mangled_name, "go.")
      && !startswith (mangled_name, "libgo_"))
    return NULL;

  /* Quick check for whether a search may be fruitful.  */
  /* Ignore anything with @plt, etc. in it.  */
  if (strchr (mangled_name, '@') != NULL)
    return NULL;
  /* It must have at least two dots.  */
  first_dot = strchr (mangled_name, '.');
  if (first_dot == NULL)
    return NULL;
  /* Treat "foo.bar" as unmangled.  It can collide with lots of other
     languages and it's not clear what the consequences are.
     And except for main.main, all gccgo symbols are at least
     prefix.package.object.  */
  last_dot = strrchr (mangled_name, '.');
  if (last_dot == first_dot)
    return NULL;

  /* More quick checks.  */
  if (last_dot[1] == '\0' /* foo. */
      || last_dot[-1] == '.') /* foo..bar */
    return NULL;

  /* At this point we've decided we have a mangled Go symbol.  */

  buf = xstrdup (mangled_name);

  /* Search backwards looking for "N<digit(s)>".  */
  p = buf + len;
  saw_digit = method_type = NULL;
  saw_pointer = 0;
  while (p > buf)
    {
      int current = *(const unsigned char *) --p;
      int current_is_digit = isdigit (current);

      if (saw_digit)
	{
	  if (current_is_digit)
	    continue;
	  if (current == 'N'
	      && ((p > buf && p[-1] == '.')
		  || (p > buf + 1 && p[-1] == 'p' && p[-2] == '.')))
	    {
	      if (atoi (p + 1) == strlen (saw_digit + 2))
		{
		  if (p[-1] == '.')
		    method_type = p - 1;
		  else
		    {
		      gdb_assert (p[-1] == 'p');
		      saw_pointer = 1;
		      method_type = p - 2;
		    }
		  break;
		}
	    }
	  /* Not what we're looking for, reset and keep looking.  */
	  saw_digit = NULL;
	  saw_pointer = 0;
	  continue;
	}
      if (current_is_digit && p[1] == '_')
	{
	  /* Possible start of method "this" [sic] type.  */
	  saw_digit = p;
	  continue;
	}
    }

  if (method_type != NULL
      /* Ensure not something like "..foo".  */
      && (method_type > buf && method_type[-1] != '.'))
    {
      unpack_package_and_object (saw_digit + 2,
				 method_type_packagep, method_type_objectp);
      *method_type = '\0';
      *method_type_is_pointerp = saw_pointer;
    }

  unpack_package_and_object (buf, packagep, objectp);
  return buf;
}
Ejemplo n.º 23
0
Archivo: wmfs.c Proyecto: wavebeem/wmfs
/** main function
 * \param argc ?
 * \param argv ?
 * \return 0
*/
int
main(int argc, char **argv)
{
     int i;
     char *ol = "csgVS";
     extern char *optarg;
     extern int optind;
     struct sigaction sa;

     argv_global  = xstrdup(argv[0]);
     all_argv = argv;
     sprintf(conf.confpath, "%s/"DEF_CONF, getenv("HOME"));

     while((i = getopt(argc, argv, "hviSc:s:g:C:V:")) != -1)
     {

          /* For options who need WMFS running */
          if(strchr(ol, i) && !(dpy = XOpenDisplay(NULL)))
               errx(EXIT_FAILURE, "cannot open X server.");

          switch(i)
          {
          case 'h':
          default:
               printf("usage: %s [-ihvS] [-C <file>] [-c <uicb function> <cmd> ] [-g <argument>] [-s <screen_num> <string>] [-V <viwmfs cmd]\n"
                      "   -C <file>                 Load a configuration file\n"
                      "   -c <uicb_function> <cmd>  Execute an uicb function to control WMFS\n"
                      "   -g <argument>             Show information about wmfs status\n"
                      "   -s <screen_num> <string>  Set the bar(s) statustext\n"
                      "   -V <viwmfs cmd>           Manage WMFS with vi-like command\n"
                      "   -S                        Update status script\n"
                      "   -h                        Show this page\n"
                      "   -i                        Show informations\n"
                      "   -v                        Show WMFS version\n", argv[0]);
               exit(EXIT_SUCCESS);
               break;

          case 'i':
               printf("WMFS - Window Manager From Scratch By Martin Duquesnoy\n");
               exit(EXIT_SUCCESS);
               break;

          case 'v':
               printf("WMFS "WMFS_VERSION"\n");
               exit(EXIT_SUCCESS);
               break;

          case 'S':
               update_status();
               XCloseDisplay(dpy);
               exit(EXIT_SUCCESS);
               break;

          case 'C':
               strncpy(conf.confpath, optarg, sizeof(conf.confpath));
               break;

          case 'c':
               exec_uicb_function(optarg, argv[optind]);
               XCloseDisplay(dpy);
               exit(EXIT_SUCCESS);
               break;

          case 's':
               if(argc > 3)
                    set_statustext(atoi(optarg), argv[3]);
               else
                    set_statustext(-1, optarg);
               XCloseDisplay(dpy);
               exit(EXIT_SUCCESS);
               break;

          case 'g':
               getinfo(optarg);
               XCloseDisplay(dpy);
               exit(EXIT_SUCCESS);
               break;
          case 'V':
               viwmfs(argc, argv);
               XCloseDisplay(dpy);
               exit(EXIT_SUCCESS);
               break;
          }
     }

     /* Check if WMFS can open X server */
     if(!(dpy = XOpenDisplay(NULL)))
          errx(EXIT_FAILURE, "cannot open X server.");

     /* Set signal handler */
     memset(&sa, 0, sizeof(sa));
     sa.sa_handler = signal_handle;
     sigemptyset(&sa.sa_mask);
     sigaction(SIGQUIT, &sa, NULL);
     sigaction(SIGTERM, &sa, NULL);
     sigaction(SIGCHLD, &sa, NULL);

     /* Check if an other WM is already running; set the error handler */
     XSetErrorHandler(errorhandler);

     /* Let's Go ! */
     init();
     scan();
     mainloop();
     quit();

     return 0;
}
Ejemplo n.º 24
0
bool add_edge_h(meshlink_handle_t *mesh, connection_t *c, const char *request) {
	edge_t *e;
	node_t *from, *to;
	char from_name[MAX_STRING_SIZE];
	int from_devclass;
	char to_name[MAX_STRING_SIZE];
	char to_address[MAX_STRING_SIZE];
	char to_port[MAX_STRING_SIZE];
	int to_devclass;
	sockaddr_t address;
	uint32_t options;
	int weight;

	if(sscanf(request, "%*d %*x "MAX_STRING" %d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %x %d",
			  from_name, &from_devclass, to_name, to_address, to_port, &to_devclass, &options, &weight) != 8) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name,
			   c->hostname);
		return false;
	}

	/* Check if names are valid */

	if(!check_id(from_name) || !check_id(to_name)) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
			   c->hostname, "invalid name");
		return false;
	}

	// Check if devclasses are valid

	if(from_devclass < 0 || from_devclass > _DEV_CLASS_MAX) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
			   c->hostname, "from devclass invalid");
		return false;
	}

	if(to_devclass < 0 || to_devclass > _DEV_CLASS_MAX) {
		logger(mesh, MESHLINK_ERROR, "Got bad %s from %s (%s): %s", "ADD_EDGE", c->name,
			   c->hostname, "to devclass invalid");
		return false;
	}

	if(seen_request(mesh, request))
		return true;

	/* Lookup nodes */

	from = lookup_node(mesh, from_name);
	to = lookup_node(mesh, to_name);

	if(!from) {
		from = new_node();
		from->status.blacklisted = mesh->default_blacklist;
		from->name = xstrdup(from_name);
		node_add(mesh, from);
	}

	from->devclass = from_devclass;
	node_write_devclass(mesh, from);

	if(!to) {
		to = new_node();
		to->status.blacklisted = mesh->default_blacklist;
		to->name = xstrdup(to_name);
		node_add(mesh, to);
	}

	to->devclass = to_devclass;
	node_write_devclass(mesh, to);

	/* Convert addresses */

	address = str2sockaddr(to_address, to_port);

	/* Check if edge already exists */

	e = lookup_edge(from, to);

	if(e) {
		if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) {
			if(from == mesh->self) {
				logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
						   "ADD_EDGE", c->name, c->hostname);
				send_add_edge(mesh, c, e);
				return true;
			} else {
				logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) which does not match existing entry",
						   "ADD_EDGE", c->name, c->hostname);
				edge_del(mesh, e);
				graph(mesh);
			}
		} else
			return true;
	} else if(from == mesh->self) {
		logger(mesh, MESHLINK_WARNING, "Got %s from %s (%s) for ourself which does not exist",
				   "ADD_EDGE", c->name, c->hostname);
		mesh->contradicting_add_edge++;
		e = new_edge();
		e->from = from;
		e->to = to;
		send_del_edge(mesh, c, e);
		free_edge(e);
		return true;
	}

	e = new_edge();
	e->from = from;
	e->to = to;
	e->address = address;
	e->options = options;
	e->weight = weight;
	edge_add(mesh, e);

	/* Tell the rest about the new edge */

	forward_request(mesh, c, request);

	/* Run MST before or after we tell the rest? */

	graph(mesh);

	return true;
}