Ejemplo n.º 1
0
void set_global_stop_on_not_reportable(bool enabled, int flags/*unused - persistent*/)
{
    assert_global_configuration_initialized();

    if (enabled)
        xsetenv(STOP_ON_NOT_REPORTABLE, "1");
    else
        xsetenv(STOP_ON_NOT_REPORTABLE, "0");
}
Ejemplo n.º 2
0
static void euidgid(char *user)
{
	struct bb_uidgid_t ugid;

	if (!get_uidgid(&ugid, user, 1)) {
		bb_error_msg_and_die("unknown user/group: %s", user);
	}
	xsetenv("GID", utoa(ugid.gid));
	xsetenv("UID", utoa(ugid.uid));
}
Ejemplo n.º 3
0
/* Setting munin specific vars */
static void setenvvars_system() {
	/* Some locales use "," as decimal separator.
	 * This can mess up a lot of plugins. */
	xsetenv("LC_ALL", "C", yes);

	/* LC_ALL should be enough, but some plugins don't
	 * follow specs (#1014) */
	xsetenv("LANG", "C", yes);

	/* PATH should be *very* sane by default. Can be
	 * overrided via config file if needed
	 * (Closes #863 and #1128).  */
	xsetenv("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", yes);
}
Ejemplo n.º 4
0
static void change_user(const struct passwd *pas)
{
	xsetenv("USER", pas->pw_name);
	xsetenv("HOME", pas->pw_dir);
	xsetenv("SHELL", DEFAULT_SHELL);

	/* initgroups, setgid, setuid */
	change_identity(pas);

	if (chdir(pas->pw_dir) < 0) {
		bb_perror_msg("chdir(%s) by %s failed",
				pas->pw_dir, pas->pw_name);
		xchdir("/tmp");
	}
}
Ejemplo n.º 5
0
// main takes care of OS-specific startup and dispatches to xmain.
void
main(int argc, char **argv)
{
	Buf b;

	setvbuf(stdout, nil, _IOLBF, BUFSIZ);
	setvbuf(stderr, nil, _IOLBF, BUFSIZ);

	binit(&b);

	rfork(RFENVG);

	slash = "/";
	gohostos = "plan9";

	xgetenv(&b, "objtype");
	if(b.len == 0)
		fatal("$objtype is unset");
	gohostarch = btake(&b);

	xgetenv(&b, "GOBIN");
	if(b.len == 0){
		bpathf(&b, "/%s/bin", gohostarch);
		xsetenv("GOBIN", bstr(&b));
	}

	srand(time(0)+getpid());
	init();
	xmain(argc, argv);

	bfree(&b);
	exits(nil);
}
Ejemplo n.º 6
0
Archivo: zcip.c Proyecto: sdg7/wl500g
/**
 * Run a script.
 * argv[0]:intf argv[1]:script_name argv[2]:junk argv[3]:NULL
 */
static int run(char *argv[3], const char *param, struct in_addr *ip)
{
	int status;
	char *addr = addr; /* for gcc */
	const char *fmt = "%s %s %s" + 3;

	argv[2] = (char*)param;

	VDBG("%s run %s %s\n", argv[0], argv[1], argv[2]);

	if (ip) {
		addr = inet_ntoa(*ip);
		xsetenv("ip", addr);
		fmt -= 3;
	}
	if (verbose)
		bb_info_msg(fmt, argv[2], argv[0], addr);

	status = spawn_and_wait(argv + 1);
	if (status < 0) {
		bb_perror_msg("%s %s %s" + 3, argv[2], argv[0]);
		return -errno;
	}
	if (status != 0)
		bb_error_msg("script %s %s failed, exitcode=%d", argv[1], argv[2], status & 0xff);
	return status;
}
Ejemplo n.º 7
0
/* TODO: use recursive_action? */
static NOINLINE void edir(const char *directory_name)
{
	int wdir;
	DIR *dir;
	struct dirent *d;
	int fd;

	wdir = xopen(".", O_RDONLY | O_NDELAY);
	xchdir(directory_name);
	dir = xopendir(".");
	for (;;) {
		char buf[256];
		char *tail;
		int size;

		errno = 0;
		d = readdir(dir);
		if (!d) {
			if (errno)
				bb_perror_msg_and_die("readdir %s",
						directory_name);
			break;
		}
		if (d->d_name[0] == '.')
			continue;
		fd = open(d->d_name, O_RDONLY | O_NDELAY);
		if (fd < 0) {
			if ((errno == EISDIR) && directory_name) {
				if (option_mask32 & OPT_v)
					bb_perror_msg("warning: %s/%s is a directory",
						directory_name, d->d_name);
				continue;
			}
			bb_perror_msg_and_die("open %s/%s",
						directory_name, d->d_name);
		}
		size = full_read(fd, buf, sizeof(buf)-1);
		close(fd);
		if (size < 0)
			bb_perror_msg_and_die("read %s/%s",
					directory_name, d->d_name);
		if (size == 0) {
			unsetenv(d->d_name);
			continue;
		}
		buf[size] = '\n';
		tail = strchr(buf, '\n');
		/* skip trailing whitespace */
		while (1) {
			*tail = '\0';
			tail--;
			if (tail < buf || !isspace(*tail))
				break;
		}
		xsetenv(d->d_name, buf);
	}
	closedir(dir);
	xfchdir(wdir);
	close(wdir);
}
Ejemplo n.º 8
0
static void set_env_vars(struct passwd *pas, const char *shell)
{
	/* POSIX requires crond to set up at least HOME, LOGNAME, PATH, SHELL.
	 * We assume crond inherited suitable PATH.
	 */
#if SETENV_LEAKS
	safe_setenv(&G.env_var_logname, "LOGNAME", pas->pw_name);
	safe_setenv(&G.env_var_user, "USER", pas->pw_name);
	safe_setenv(&G.env_var_home, "HOME", pas->pw_dir);
	safe_setenv(&G.env_var_shell, "SHELL", shell);
#else
	xsetenv("LOGNAME", pas->pw_name);
	xsetenv("USER", pas->pw_name);
	xsetenv("HOME", pas->pw_dir);
	xsetenv("SHELL", shell);
#endif
}
Ejemplo n.º 9
0
/* Setting munin specific vars */
static void setenvvars_munin() {
	/* munin-node will override this with the IP of the
	 * connecting master */
	if (client_ip != NULL && client_ip[0] != '\0') {
		xsetenv("MUNIN_MASTER_IP", client_ip, no);
	}

	/* Tell plugins about supported capabilities */
	xsetenv("MUNIN_CAP_MULTIGRAPH", "1", no);

	/* We only have one user, so using a fixed path */
	xsetenv("MUNIN_PLUGSTATE", "/var/tmp", no);
	xsetenv("MUNIN_STATEFILE", "/dev/null", no);

	/* That's where plugins should live */
	xsetenv("MUNIN_LIBDIR", "/usr/share/munin", no);
}
Ejemplo n.º 10
0
void set_global_create_private_ticket(bool enabled, int flags/*unused - persistent*/)
{
    assert_global_configuration_initialized();

    if (enabled)
        xsetenv(CREATE_PRIVATE_TICKET, "1");
    else
        safe_unsetenv(CREATE_PRIVATE_TICKET);
}
Ejemplo n.º 11
0
void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw )
{
	if ( loginshell ) {
		const char *term;

		/* Change the current working directory to be the home directory
		 * of the user.  It is a fatal error for this process to be unable
		 * to change to that directory.  There is no "default" home
		 * directory.
		 * Some systems default to HOME=/
		 */
		if ( chdir ( pw-> pw_dir )) {
			if ( chdir ( "/" )) {
				syslog ( LOG_WARNING, "unable to cd to %s' for user %s'\n", pw-> pw_dir, pw-> pw_name );
				bb_error_msg_and_die ( "cannot cd to home directory or /" );
			}
			fputs ( "warning: cannot change to home directory\n", stderr );
		}

		/* Leave TERM unchanged.  Set HOME, SHELL, USER, LOGNAME, PATH.
		   Unset all other environment variables.  */
		term = getenv ("TERM");
		clearenv ( );
		if ( term )
			xsetenv ( "TERM", term );
		xsetenv ( "HOME",    pw-> pw_dir );
		xsetenv ( "SHELL",   shell );
		xsetenv ( "USER",    pw-> pw_name );
		xsetenv ( "LOGNAME", pw-> pw_name );
		xsetenv ( "PATH",    ( pw-> pw_uid ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH ));
	}
	else if ( changeenv ) {
		/* Set HOME, SHELL, and if not becoming a super-user,
		   USER and LOGNAME.  */
		xsetenv ( "HOME",  pw-> pw_dir );
		xsetenv ( "SHELL", shell );
		if  ( pw-> pw_uid ) {
			xsetenv ( "USER",    pw-> pw_name );
			xsetenv ( "LOGNAME", pw-> pw_name );
		}
	}
}
Ejemplo n.º 12
0
/* Restore CLASSPATH to its previous value.  */
void
reset_classpath (char *old_classpath)
{
  if (old_classpath != NULL)
    {
      xsetenv (CLASSPATHVAR, old_classpath, 1);
      free (old_classpath);
    }
  else
    unsetenv (CLASSPATHVAR);
}
Ejemplo n.º 13
0
static void run_login_script(struct passwd *pw, char *full_tty)
{
    char *t_argv[2];

    t_argv[0] = getenv("LOGIN_PRE_SUID_SCRIPT");
    if (t_argv[0]) {
        t_argv[1] = NULL;
        xsetenv("LOGIN_TTY", full_tty);
        xsetenv("LOGIN_USER", pw->pw_name);
        xsetenv("LOGIN_UID", utoa(pw->pw_uid));
        xsetenv("LOGIN_GID", utoa(pw->pw_gid));
        xsetenv("LOGIN_SHELL", pw->pw_shell);
        spawn_and_wait(t_argv);	/* NOMMU-friendly */
        unsetenv("LOGIN_TTY");
        unsetenv("LOGIN_USER");
        unsetenv("LOGIN_UID");
        unsetenv("LOGIN_GID");
        unsetenv("LOGIN_SHELL");
    }
}
Ejemplo n.º 14
0
int
main (int argc, char *argv[])
{
  char *s;
  int result = 0;

  /* Clean up environment.  */
  unsetenv ("LANGUAGE");
  unsetenv ("LC_ALL");
  unsetenv ("LC_MESSAGES");
  unsetenv ("LC_CTYPE");
  unsetenv ("LANG");
  unsetenv ("OUTPUT_CHARSET");

  xsetenv ("LC_ALL", argv[1], 1);
  setlocale (LC_ALL, "");
  textdomain ("codeset");
  bindtextdomain ("codeset", "gt-4");

  /* Here we expect output in ISO-8859-1.
     Except on Darwin 7 or newer and on BeOS, for which locale_charset ()
     always returns "UTF-8" (see config.charset).  */
#if !((defined __APPLE__ && defined __MACH__) || defined __BEOS__)
  s = gettext ("cheese");
  if (strcmp (s, "K\344se"))
    {
      fprintf (stderr, "call 1 returned: %s\n", s);
      result = 1;
    }
#endif

  bind_textdomain_codeset ("codeset", "UTF-8");

  /* Here we expect output in UTF-8.  */
  s = gettext ("cheese");
  if (strcmp (s, "K\303\244se"))
    {
      fprintf (stderr, "call 2 returned: %s\n", s);
      result = 1;
    }

  bind_textdomain_codeset ("codeset", "ISO-8859-1");

  /* Here we expect output in ISO-8859-1.  */
  s = gettext ("cheese");
  if (strcmp (s, "K\344se"))
    {
      fprintf (stderr, "call 3 returned: %s\n", s);
      result = 1;
    }

  return result;
}
Ejemplo n.º 15
0
static void
modify_environment (const struct passwd *pw, const char *shell)
{
  if (simulate_login)
    {
      /* Leave TERM unchanged.  Set HOME, SHELL, USER, LOGNAME, PATH.
         Unset all other environment variables.  */
      char *term = getenv ("TERM");
      if (term)
	term = xstrdup (term);
      environ = xmalloc ((6 + !!term) * sizeof (char *));
      environ[0] = NULL;
      if (term) {
	xsetenv ("TERM", term, 1);
	free(term);
      }
      xsetenv ("HOME", pw->pw_dir, 1);
      if (shell)
	xsetenv ("SHELL", shell, 1);
      xsetenv ("USER", pw->pw_name, 1);
      xsetenv ("LOGNAME", pw->pw_name, 1);
      set_path(pw);
    }
  else
    {
      /* Set HOME, SHELL, and (if not becoming a superuser)
	 USER and LOGNAME.  */
      if (change_environment)
        {
          xsetenv ("HOME", pw->pw_dir, 1);
	  if (shell)
            xsetenv ("SHELL", shell, 1);
	  if (getlogindefs_bool ("ALWAYS_SET_PATH", 0))
	    set_path(pw);

          if (pw->pw_uid)
            {
              xsetenv ("USER", pw->pw_name, 1);
              xsetenv ("LOGNAME", pw->pw_name, 1);
            }
        }
    }

  export_pamenv ();
}
Ejemplo n.º 16
0
Archivo: build.c Proyecto: hfeeki/go
// The bootstrap command runs a build from scratch,
// stopping at having installed the go_bootstrap command.
void
cmdbootstrap(int argc, char **argv)
{
	int i;
	Buf b;
	char *oldgoos, *oldgoarch, *oldgochar;

	binit(&b);

	ARGBEGIN{
	case 'a':
		rebuildall = 1;
		break;
	case 'v':
		vflag++;
		break;
	default:
		usage();
	}ARGEND

	if(argc > 0)
		usage();

	if(rebuildall)
		clean();
	goversion = findgoversion();
	setup();

	xsetenv("GOROOT", goroot);
	xsetenv("GOROOT_FINAL", goroot_final);

	// For the main bootstrap, building for host os/arch.
	oldgoos = goos;
	oldgoarch = goarch;
	oldgochar = gochar;
	goos = gohostos;
	goarch = gohostarch;
	gochar = gohostchar;
	xsetenv("GOARCH", goarch);
	xsetenv("GOOS", goos);

	for(i=0; i<nelem(buildorder); i++) {
		install(bprintf(&b, buildorder[i], gohostchar));
		if(!streq(oldgochar, gohostchar) && xstrstr(buildorder[i], "%s"))
			install(bprintf(&b, buildorder[i], oldgochar));
	}

	goos = oldgoos;
	goarch = oldgoarch;
	gochar = oldgochar;
	xsetenv("GOARCH", goarch);
	xsetenv("GOOS", goos);

	// Build pkg/runtime for actual goos/goarch too.
	if(!streq(goos, gohostos) || !streq(goarch, gohostarch))
		install("pkg/runtime");

	bfree(&b);
}
Ejemplo n.º 17
0
int
main (int argc, char *argv[])
{
  int n = atoi (argv[2]);

  xsetenv ("LC_ALL", argv[1], 1);
  if (setlocale (LC_ALL, "") == NULL)
    return 1;

  textdomain ("cake");
  bindtextdomain ("cake", "plural-1-dir");
  printf (ngettext ("a piece of cake", "%d pieces of cake", n), n);
  printf ("\n");
  return 0;
}
Ejemplo n.º 18
0
void make_run_event_state_forwarding(struct run_event_state *state)
{
    /* reset callbacks, just to be sure */
    state->alert_callback = run_event_stdio_alert;
    state->ask_callback = run_event_stdio_ask;
    state->ask_yes_no_callback = run_event_stdio_ask_yes_no;
    state->ask_yes_no_yesforever_callback= run_event_stdio_ask_yes_no_yesforever;
    state->ask_password_callback = run_event_stdio_ask_password;

    /*
     * Not sure if we should reset even logging_callback and error_callback?
     */

    xsetenv("REPORT_CLIENT_SLAVE", "1");
}
Ejemplo n.º 19
0
int
main (int argc, char *argv[])
{
  int n = 5;
  const char *en;
  const char *s;
  const char *expected_translation;
  const char *expected_result;
  char buf[100];

  xsetenv ("LC_ALL", argv[1], 1);
  if (setlocale (LC_ALL, "") == NULL)
    {
      fprintf (stderr, "Couldn't set locale.\n");
      exit (1);
    }

  textdomain ("fc5");
  bindtextdomain ("fc5", ".");

  s = gettext ("father of %d children");
  en = "father of %d children";
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
  expected_translation = "Vater von %Id Kindern";
  expected_result = "Vater von \xdb\xb5 Kindern";
#else
  expected_translation = "Vater von %d Kindern";
  expected_result = "Vater von 5 Kindern";
#endif

  if (strcmp (s, en) == 0)
    {
      fprintf (stderr, "String untranslated.\n");
      exit (1);
    }
  if (strcmp (s, expected_translation) != 0)
    {
      fprintf (stderr, "String incorrectly translated.\n");
      exit (1);
    }
  sprintf (buf, s, n);
  if (strcmp (buf, expected_result) != 0)
    {
      fprintf (stderr, "printf of translation wrong.\n");
      exit (1);
    }
  return 0;
}
Ejemplo n.º 20
0
/* Set CLASSPATH and returns a safe copy of its old value.  */
char *
set_classpath (const char * const *classpaths, unsigned int classpaths_count,
	       bool use_minimal_classpath, bool verbose)
{
  const char *old_CLASSPATH = getenv (CLASSPATHVAR);
  char *result = (old_CLASSPATH != NULL ? xstrdup (old_CLASSPATH) : NULL);
  char *new_CLASSPATH =
    new_classpath (classpaths, classpaths_count, use_minimal_classpath);

  if (verbose)
    printf (CLASSPATHVAR "=%s ", new_CLASSPATH);

  xsetenv (CLASSPATHVAR, new_CLASSPATH, 1);

  free (new_CLASSPATH);

  return result;
}
Ejemplo n.º 21
0
int
main (int argc, char *argv[])
{
  unsigned char n = 5;
  const char *s;
  const char *c1;
  const char *c2;
  char buf[100];

  xsetenv ("LC_ALL", argv[1], 1);
  if (setlocale (LC_ALL, "") == NULL)
    {
      fprintf (stderr, "Couldn't set locale.\n");
      exit (1);
    }

  textdomain ("fc4");
  bindtextdomain ("fc4", ".");

  s = ngettext ("father of %"PRId8" child", "father of %"PRId8" children", n);
  c1 = "Vater von %"; c2 = " Kindern";

  if (!(strlen (s) > strlen (c1) + strlen (c2)
	&& memcmp (s, c1, strlen (c1)) == 0
	&& memcmp (s + strlen (s) - strlen (c2), c2, strlen (c2)) == 0))
    {
      fprintf (stderr, "String not translated.\n");
      exit (1);
    }
  if (strchr (s, '<') != NULL || strchr (s, '>') != NULL)
    {
      fprintf (stderr, "Translation contains <...> markers.\n");
      exit (1);
    }
  sprintf (buf, s, n);
  if (strcmp (buf, "Vater von 5 Kindern") != 0)
    {
      fprintf (stderr, "printf of translation wrong.\n");
      exit (1);
    }
  return 0;
}
Ejemplo n.º 22
0
/*
 * Initialize $TERM, $HOME, ...
 */
static void init_environ(struct login_context *cxt)
{
	struct passwd *pwd = cxt->pwd;
	char *termenv, **env;
	char tmp[PATH_MAX];
	int len, i;

	termenv = getenv("TERM");
	if (termenv)
		termenv = xstrdup(termenv);

	/* destroy environment unless user has requested preservation (-p) */
	if (!cxt->keep_env) {
		environ = xmalloc(sizeof(char *));
		memset(environ, 0, sizeof(char *));
	}

	xsetenv("HOME", pwd->pw_dir, 0);	/* legal to override */
	xsetenv("USER", pwd->pw_name, 1);
	xsetenv("SHELL", pwd->pw_shell, 1);
	xsetenv("TERM", termenv ? termenv : "dumb", 1);
	free(termenv);

	if (pwd->pw_uid) {
		if (logindefs_setenv("PATH", "ENV_PATH", _PATH_DEFPATH) != 0)
			err(EXIT_FAILURE, _("failed to set the %s environment variable"), "PATH");

	} else if (logindefs_setenv("PATH", "ENV_ROOTPATH", NULL) != 0 &&
		   logindefs_setenv("PATH", "ENV_SUPATH", _PATH_DEFPATH_ROOT) != 0) {
			err(EXIT_FAILURE, _("failed to set the %s environment variable"), "PATH");
	}

	/* mailx will give a funny error msg if you forget this one */
	len = snprintf(tmp, sizeof(tmp), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
	if (len > 0 && (size_t) len < sizeof(tmp))
		xsetenv("MAIL", tmp, 0);

	/* LOGNAME is not documented in login(1) but HP-UX 6.5 does it. We'll
	 * not allow modifying it.
	 */
	xsetenv("LOGNAME", pwd->pw_name, 1);

	env = pam_getenvlist(cxt->pamh);
	for (i = 0; env && env[i]; i++)
		putenv(env[i]);
}
Ejemplo n.º 23
0
void FAST_FUNC setup_environment(const char *shell, int flags, const struct passwd *pw)
{
	if (!shell || !shell[0])
		shell = DEFAULT_SHELL;

	/* Change the current working directory to be the home directory
	 * of the user */
	if (!(flags & SETUP_ENV_NO_CHDIR)) {
		if (chdir(pw->pw_dir) != 0) {
			bb_error_msg("can't change directory to '%s'", pw->pw_dir);
			xchdir((flags & SETUP_ENV_TO_TMP) ? "/tmp" : "/");
		}
	}

	if (flags & SETUP_ENV_CLEARENV) {
		const char *term;

		/* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
		 * Unset all other environment variables.  */
		term = getenv("TERM");
		clearenv();
		if (term)
			xsetenv("TERM", term);
		xsetenv("PATH", (pw->pw_uid ? bb_default_path : bb_default_root_path));
		goto shortcut;
		// No, gcc (4.2.1) is not clever enougn to do it itself.
		//xsetenv("USER",    pw->pw_name);
		//xsetenv("LOGNAME", pw->pw_name);
		//xsetenv("HOME",    pw->pw_dir);
		//xsetenv("SHELL",   shell);
	} else if (flags & SETUP_ENV_CHANGEENV) {
#if ENABLE_PLATFORM_MINGW32
#define xsetenv(k, v) xsetenv_if_unset(k, v)
#endif
		/* Set HOME, SHELL, and if not becoming a super-user,
		 * USER and LOGNAME.  */
		if (pw->pw_uid) {
 shortcut:
			xsetenv("USER",    pw->pw_name);
			xsetenv("LOGNAME", pw->pw_name);
		}
		xsetenv("HOME",    pw->pw_dir);
		xsetenv("SHELL",   shell);
	}
}
void FAST_FUNC setup_environment(const char *shell, int clear_env, int change_env, const struct passwd *pw)
{
	/* Change the current working directory to be the home directory
	 * of the user */
	if (chdir(pw->pw_dir)) {
		xchdir("/");
		bb_error_msg("can't chdir to home directory '%s'", pw->pw_dir);
	}

	if (clear_env) {
		const char *term;

		/* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
		   Unset all other environment variables.  */
		term = getenv("TERM");
		clearenv();
		if (term)
			xsetenv("TERM", term);
		xsetenv("PATH", (pw->pw_uid ? bb_default_path : bb_default_root_path));
		goto shortcut;
		// No, gcc (4.2.1) is not clever enougn to do it itself.
		//xsetenv("USER",    pw->pw_name);
		//xsetenv("LOGNAME", pw->pw_name);
		//xsetenv("HOME",    pw->pw_dir);
		//xsetenv("SHELL",   shell);
	}
	else if (change_env) {
		/* Set HOME, SHELL, and if not becoming a super-user,
		   USER and LOGNAME.  */
		if (pw->pw_uid) {
 shortcut:
			xsetenv("USER",    pw->pw_name);
			xsetenv("LOGNAME", pw->pw_name);
		}
		xsetenv("HOME",    pw->pw_dir);
		xsetenv("SHELL",   shell);
	}
}
Ejemplo n.º 25
0
Archivo: zcip.c Proyecto: sdg7/wl500g
int zcip_main(int argc UNUSED_PARAM, char **argv)
{
	int state;
	char *r_opt;
	unsigned opts;

	// ugly trick, but I want these zeroed in one go
	struct {
		const struct in_addr null_ip;
		const struct ether_addr null_addr;
		struct in_addr ip;
		struct ifreq ifr;
		int timeout_ms; /* must be signed */
		unsigned conflicts;
		unsigned nprobes;
		unsigned nclaims;
		int ready;
	} L;
#define null_ip    (L.null_ip   )
#define null_addr  (L.null_addr )
#define ip         (L.ip        )
#define ifr        (L.ifr       )
#define timeout_ms (L.timeout_ms)
#define conflicts  (L.conflicts )
#define nprobes    (L.nprobes   )
#define nclaims    (L.nclaims   )
#define ready      (L.ready     )

	memset(&L, 0, sizeof(L));
	INIT_G();

#define FOREGROUND (opts & 1)
#define QUIT       (opts & 2)
	// parse commandline: prog [options] ifname script
	// exactly 2 args; -v accumulates and implies -f
	opt_complementary = "=2:vv:vf";
	opts = getopt32(argv, "fqr:p:v", &r_opt, &pidfile, &verbose);
#if !BB_MMU
	// on NOMMU reexec early (or else we will rerun things twice)
	if (!FOREGROUND)
		bb_daemonize_or_rexec(0 /*was: DAEMON_CHDIR_ROOT*/, argv);
#endif
	// open an ARP socket
	// (need to do it before openlog to prevent openlog from taking
	// fd 3 (sock_fd==3))
	xmove_fd(xsocket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)), sock_fd);
	if (!FOREGROUND) {
		// do it before all bb_xx_msg calls
		openlog(applet_name, 0, LOG_DAEMON);
		logmode |= LOGMODE_SYSLOG;
	}
	if (opts & 4) { // -r n.n.n.n
		if (inet_aton(r_opt, &ip) == 0
		 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR
		) {
			bb_error_msg_and_die("invalid link address");
		}
	}
	argv += optind - 1;

	/* Now: argv[0]:junk argv[1]:intf argv[2]:script argv[3]:NULL */
	/* We need to make space for script argument: */
	argv[0] = argv[1];
	argv[1] = argv[2];
	/* Now: argv[0]:intf argv[1]:script argv[2]:junk argv[3]:NULL */
#define argv_intf (argv[0])

	xsetenv("interface", argv_intf);

	// initialize the interface (modprobe, ifup, etc)
	if (run(argv, "init", NULL))
		return EXIT_FAILURE;

	// initialize saddr
	// saddr is: { u16 sa_family; u8 sa_data[14]; }
	//memset(&saddr, 0, sizeof(saddr));
	//TODO: are we leaving sa_family == 0 (AF_UNSPEC)?!
	safe_strncpy(saddr.sa_data, argv_intf, sizeof(saddr.sa_data));

	// bind to the interface's ARP socket
	xbind(sock_fd, &saddr, sizeof(saddr));

	// get the interface's ethernet address
	//memset(&ifr, 0, sizeof(ifr));
	strncpy_IFNAMSIZ(ifr.ifr_name, argv_intf);
	xioctl(sock_fd, SIOCGIFHWADDR, &ifr);
	memcpy(&eth_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);

	// start with some stable ip address, either a function of
	// the hardware address or else the last address we used.
	// we are taking low-order four bytes, as top-order ones
	// aren't random enough.
	// NOTE: the sequence of addresses we try changes only
	// depending on when we detect conflicts.
	{
		uint32_t t;
		move_from_unaligned32(t, ((char *)&eth_addr + 2));
		srand(t);
	}
	if (ip.s_addr == 0)
		ip.s_addr = pick();

	// FIXME cases to handle:
	//  - zcip already running!
	//  - link already has local address... just defend/update

	// daemonize now; don't delay system startup
	if (!FOREGROUND) {
#if BB_MMU
		bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/);
#endif
		if (verbose)
			bb_info_msg("start, interface %s", argv_intf);
	}

	write_pidfile(pidfile);
	bb_signals(BB_FATAL_SIGS, cleanup);

	// run the dynamic address negotiation protocol,
	// restarting after address conflicts:
	//  - start with some address we want to try
	//  - short random delay
	//  - arp probes to see if another host uses it
	//  - arp announcements that we're claiming it
	//  - use it
	//  - defend it, within limits
	// exit if:
	// - address is successfully obtained and -q was given:
	//   run "<script> config", then exit with exitcode 0
	// - poll error (when does this happen?)
	// - read error (when does this happen?)
	// - sendto error (in arp()) (when does this happen?)
	// - revents & POLLERR (link down). run "<script> deconfig" first
	state = PROBE;
	while (1) {
		struct pollfd fds[1];
		unsigned deadline_us;
		struct arp_packet p;
		int source_ip_conflict;
		int target_ip_conflict;

		fds[0].fd = sock_fd;
		fds[0].events = POLLIN;
		fds[0].revents = 0;

		// poll, being ready to adjust current timeout
		if (!timeout_ms) {
			timeout_ms = random_delay_ms(PROBE_WAIT);
			// FIXME setsockopt(sock_fd, SO_ATTACH_FILTER, ...) to
			// make the kernel filter out all packets except
			// ones we'd care about.
		}
		// set deadline_us to the point in time when we timeout
		deadline_us = MONOTONIC_US() + timeout_ms * 1000;

		VDBG("...wait %d %s nprobes=%u, nclaims=%u\n",
				timeout_ms, argv_intf, nprobes, nclaims);

		switch (safe_poll(fds, 1, timeout_ms)) {

		default:
			//bb_perror_msg("poll"); - done in safe_poll
			cleanup(EXIT_FAILURE);

		// timeout
		case 0:
			VDBG("state = %d\n", state);
			switch (state) {
			case PROBE:
				// timeouts in the PROBE state mean no conflicting ARP packets
				// have been received, so we can progress through the states
				if (nprobes < PROBE_NUM) {
					nprobes++;
					VDBG("probe/%u %s@%s\n",
							nprobes, argv_intf, inet_ntoa(ip));
					arp(/* ARPOP_REQUEST, */
							/* &eth_addr, */ null_ip,
							&null_addr, ip);
					timeout_ms = PROBE_MIN * 1000;
					timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN);
				}
				else {
					// Switch to announce state.
					state = ANNOUNCE;
					nclaims = 0;
					VDBG("announce/%u %s@%s\n",
							nclaims, argv_intf, inet_ntoa(ip));
					arp(/* ARPOP_REQUEST, */
							/* &eth_addr, */ ip,
							&eth_addr, ip);
					timeout_ms = ANNOUNCE_INTERVAL * 1000;
				}
				break;
			case RATE_LIMIT_PROBE:
				// timeouts in the RATE_LIMIT_PROBE state mean no conflicting ARP packets
				// have been received, so we can move immediately to the announce state
				state = ANNOUNCE;
				nclaims = 0;
				VDBG("announce/%u %s@%s\n",
						nclaims, argv_intf, inet_ntoa(ip));
				arp(/* ARPOP_REQUEST, */
						/* &eth_addr, */ ip,
						&eth_addr, ip);
				timeout_ms = ANNOUNCE_INTERVAL * 1000;
				break;
			case ANNOUNCE:
				// timeouts in the ANNOUNCE state mean no conflicting ARP packets
				// have been received, so we can progress through the states
				if (nclaims < ANNOUNCE_NUM) {
					nclaims++;
					VDBG("announce/%u %s@%s\n",
							nclaims, argv_intf, inet_ntoa(ip));
					arp(/* ARPOP_REQUEST, */
							/* &eth_addr, */ ip,
							&eth_addr, ip);
					timeout_ms = ANNOUNCE_INTERVAL * 1000;
				}
				else {
					// Switch to monitor state.
					state = MONITOR;
					// link is ok to use earlier
					// FIXME update filters
					run(argv, "config", &ip);
					ready = 1;
					conflicts = 0;
					timeout_ms = -1; // Never timeout in the monitor state.

					// NOTE: all other exit paths
					// should deconfig ...
					if (QUIT)
						cleanup(EXIT_SUCCESS);
				}
				break;
			case DEFEND:
				// We won!  No ARP replies, so just go back to monitor.
				state = MONITOR;
				timeout_ms = -1;
				conflicts = 0;
				break;
			default:
				// Invalid, should never happen.  Restart the whole protocol.
				state = PROBE;
				ip.s_addr = pick();
				timeout_ms = 0;
				nprobes = 0;
				nclaims = 0;
				break;
			} // switch (state)
			break; // case 0 (timeout)

		// packets arriving, or link went down
		case 1:
			// We need to adjust the timeout in case we didn't receive
			// a conflicting packet.
			if (timeout_ms > 0) {
				unsigned diff = deadline_us - MONOTONIC_US();
				if ((int)(diff) < 0) {
					// Current time is greater than the expected timeout time.
					// Should never happen.
					VDBG("missed an expected timeout\n");
					timeout_ms = 0;
				} else {
					VDBG("adjusting timeout\n");
					timeout_ms = (diff / 1000) | 1; /* never 0 */
				}
			}

			if ((fds[0].revents & POLLIN) == 0) {
				if (fds[0].revents & POLLERR) {
					// FIXME: links routinely go down;
					// this shouldn't necessarily exit.
					bb_error_msg("iface %s is down", argv_intf);
					if (ready) {
						run(argv, "deconfig", &ip);
					}
					cleanup(EXIT_FAILURE);
				}
				continue;
			}

			// read ARP packet
			if (safe_read(sock_fd, &p, sizeof(p)) < 0) {
				bb_perror_msg(bb_msg_read_error);
				cleanup(EXIT_FAILURE);
			}
			if (p.eth.ether_type != htons(ETHERTYPE_ARP))
				continue;
#ifdef DEBUG
			{
				struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha;
				struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha;
				struct in_addr *spa = (struct in_addr *) p.arp.arp_spa;
				struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa;
				VDBG("%s recv arp type=%d, op=%d,\n",
					argv_intf, ntohs(p.eth.ether_type),
					ntohs(p.arp.arp_op));
				VDBG("\tsource=%s %s\n",
					ether_ntoa(sha),
					inet_ntoa(*spa));
				VDBG("\ttarget=%s %s\n",
					ether_ntoa(tha),
					inet_ntoa(*tpa));
			}
#endif
			if (p.arp.arp_op != htons(ARPOP_REQUEST)
			 && p.arp.arp_op != htons(ARPOP_REPLY))
				continue;

			source_ip_conflict = 0;
			target_ip_conflict = 0;

			if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0
			 && memcmp(&p.arp.arp_sha, &eth_addr, ETH_ALEN) != 0
			) {
				source_ip_conflict = 1;
			}
			if (p.arp.arp_op == htons(ARPOP_REQUEST)
			 && memcmp(p.arp.arp_tpa, &ip.s_addr, sizeof(struct in_addr)) == 0
			 && memcmp(&p.arp.arp_tha, &eth_addr, ETH_ALEN) != 0
			) {
				target_ip_conflict = 1;
			}

			VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n",
				state, source_ip_conflict, target_ip_conflict);
			switch (state) {
			case PROBE:
			case ANNOUNCE:
				// When probing or announcing, check for source IP conflicts
				// and other hosts doing ARP probes (target IP conflicts).
				if (source_ip_conflict || target_ip_conflict) {
					conflicts++;
					if (conflicts >= MAX_CONFLICTS) {
						VDBG("%s ratelimit\n", argv_intf);
						timeout_ms = RATE_LIMIT_INTERVAL * 1000;
						state = RATE_LIMIT_PROBE;
					}

					// restart the whole protocol
					ip.s_addr = pick();
					timeout_ms = 0;
					nprobes = 0;
					nclaims = 0;
				}
				break;
			case MONITOR:
				// If a conflict, we try to defend with a single ARP probe.
				if (source_ip_conflict) {
					VDBG("monitor conflict -- defending\n");
					state = DEFEND;
					timeout_ms = DEFEND_INTERVAL * 1000;
					arp(/* ARPOP_REQUEST, */
						/* &eth_addr, */ ip,
						&eth_addr, ip);
				}
				break;
			case DEFEND:
				// Well, we tried.  Start over (on conflict).
				if (source_ip_conflict) {
					state = PROBE;
					VDBG("defend conflict -- starting over\n");
					ready = 0;
					run(argv, "deconfig", &ip);

					// restart the whole protocol
					ip.s_addr = pick();
					timeout_ms = 0;
					nprobes = 0;
					nclaims = 0;
				}
				break;
			default:
				// Invalid, should never happen.  Restart the whole protocol.
				VDBG("invalid state -- starting over\n");
				state = PROBE;
				ip.s_addr = pick();
				timeout_ms = 0;
				nprobes = 0;
				nclaims = 0;
				break;
			} // switch state
			break; // case 1 (packets arriving)
		} // switch poll
	} // while (1)
#undef argv_intf
}
Ejemplo n.º 26
0
bool
execute_java_class (const char *class_name,
		    const char * const *classpaths,
		    unsigned int classpaths_count,
		    bool use_minimal_classpath,
		    const char *exe_dir,
		    const char * const *args,
		    bool verbose, bool quiet,
		    execute_fn *executer, void *private_data)
{
  bool err = false;
  unsigned int nargs;
  char *old_JAVA_HOME;

  /* Count args.  */
  {
    const char * const *arg;

    for (nargs = 0, arg = args; *arg != NULL; nargs++, arg++)
     ;
  }

  /* First, try a class compiled to a native code executable.  */
  if (exe_dir != NULL)
    {
      char *exe_pathname = concatenated_filename (exe_dir, class_name, EXEEXT);
      char *old_classpath;
      char **argv = (char **) xmalloca ((1 + nargs + 1) * sizeof (char *));
      unsigned int i;

      /* Set CLASSPATH.  */
      old_classpath =
	set_classpath (classpaths, classpaths_count, use_minimal_classpath,
		       verbose);

      argv[0] = exe_pathname;
      for (i = 0; i <= nargs; i++)
	argv[1 + i] = (char *) args[i];

      if (verbose)
	{
	  char *command = shell_quote_argv (argv);
	  printf ("%s\n", command);
	  free (command);
	}

      err = executer (class_name, exe_pathname, argv, private_data);

      /* Reset CLASSPATH.  */
      reset_classpath (old_classpath);

      freea (argv);

      goto done1;
    }

  {
    const char *java = getenv ("JAVA");
    if (java != NULL && java[0] != '\0')
      {
	/* Because $JAVA may consist of a command and options, we use the
	   shell.  Because $JAVA has been set by the user, we leave all
	   all environment variables in place, including JAVA_HOME, and
	   we don't erase the user's CLASSPATH.  */
	char *old_classpath;
	unsigned int command_length;
	char *command;
	char *argv[4];
	const char * const *arg;
	char *p;

	/* Set CLASSPATH.  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, false,
			 verbose);

	command_length = strlen (java);
	command_length += 1 + shell_quote_length (class_name);
	for (arg = args; *arg != NULL; arg++)
	  command_length += 1 + shell_quote_length (*arg);
	command_length += 1;

	command = (char *) xmalloca (command_length);
	p = command;
	/* Don't shell_quote $JAVA, because it may consist of a command
	   and options.  */
	memcpy (p, java, strlen (java));
	p += strlen (java);
	*p++ = ' ';
	p = shell_quote_copy (p, class_name);
	for (arg = args; *arg != NULL; arg++)
	  {
	    *p++ = ' ';
	    p = shell_quote_copy (p, *arg);
	  }
	*p++ = '\0';
	/* Ensure command_length was correctly calculated.  */
	if (p - command > command_length)
	  abort ();

	if (verbose)
	  printf ("%s\n", command);

	argv[0] = "/bin/sh";
	argv[1] = "-c";
	argv[2] = command;
	argv[3] = NULL;
	err = executer (java, "/bin/sh", argv, private_data);

	freea (command);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	goto done1;
      }
  }

  /* Unset the JAVA_HOME environment variable.  */
  old_JAVA_HOME = getenv ("JAVA_HOME");
  if (old_JAVA_HOME != NULL)
    {
      old_JAVA_HOME = xstrdup (old_JAVA_HOME);
      unsetenv ("JAVA_HOME");
    }

  {
    static bool gij_tested;
    static bool gij_present;

    if (!gij_tested)
      {
	/* Test for presence of gij: "gij --version > /dev/null"  */
	char *argv[3];
	int exitstatus;

	argv[0] = "gij";
	argv[1] = "--version";
	argv[2] = NULL;
	exitstatus = execute ("gij", "gij", argv, false, false, true, true,
			      true, false);
	gij_present = (exitstatus == 0);
	gij_tested = true;
      }

    if (gij_present)
      {
	char *old_classpath;
	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
	unsigned int i;

	/* Set CLASSPATH.  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
			 verbose);

	argv[0] = "gij";
	argv[1] = (char *) class_name;
	for (i = 0; i <= nargs; i++)
	  argv[2 + i] = (char *) args[i];

	if (verbose)
	  {
	    char *command = shell_quote_argv (argv);
	    printf ("%s\n", command);
	    free (command);
	  }

	err = executer ("gij", "gij", argv, private_data);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	freea (argv);

	goto done2;
      }
  }

  {
    static bool java_tested;
    static bool java_present;

    if (!java_tested)
      {
	/* Test for presence of java: "java -version 2> /dev/null"  */
	char *argv[3];
	int exitstatus;

	argv[0] = "java";
	argv[1] = "-version";
	argv[2] = NULL;
	exitstatus = execute ("java", "java", argv, false, false, true, true,
			      true, false);
	java_present = (exitstatus == 0);
	java_tested = true;
      }

    if (java_present)
      {
	char *old_classpath;
	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
	unsigned int i;

	/* Set CLASSPATH.  We don't use the "-classpath ..." option because
	   in JDK 1.1.x its argument should also contain the JDK's classes.zip,
	   but we don't know its location.  (In JDK 1.3.0 it would work.)  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
			 verbose);

	argv[0] = "java";
	argv[1] = (char *) class_name;
	for (i = 0; i <= nargs; i++)
	  argv[2 + i] = (char *) args[i];

	if (verbose)
	  {
	    char *command = shell_quote_argv (argv);
	    printf ("%s\n", command);
	    free (command);
	  }

	err = executer ("java", "java", argv, private_data);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	freea (argv);

	goto done2;
      }
  }

  {
    static bool jre_tested;
    static bool jre_present;

    if (!jre_tested)
      {
	/* Test for presence of jre: "jre 2> /dev/null ; test $? = 1"  */
	char *argv[2];
	int exitstatus;

	argv[0] = "jre";
	argv[1] = NULL;
	exitstatus = execute ("jre", "jre", argv, false, false, true, true,
			      true, false);
	jre_present = (exitstatus == 0 || exitstatus == 1);
	jre_tested = true;
      }

    if (jre_present)
      {
	char *old_classpath;
	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
	unsigned int i;

	/* Set CLASSPATH.  We don't use the "-classpath ..." option because
	   in JDK 1.1.x its argument should also contain the JDK's classes.zip,
	   but we don't know its location.  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
			 verbose);

	argv[0] = "jre";
	argv[1] = (char *) class_name;
	for (i = 0; i <= nargs; i++)
	  argv[2 + i] = (char *) args[i];

	if (verbose)
	  {
	    char *command = shell_quote_argv (argv);
	    printf ("%s\n", command);
	    free (command);
	  }

	err = executer ("jre", "jre", argv, private_data);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	freea (argv);

	goto done2;
      }
  }

#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__
  /* Win32, Cygwin */
  {
    static bool jview_tested;
    static bool jview_present;

    if (!jview_tested)
      {
	/* Test for presence of jview: "jview -? >nul ; test $? = 1"  */
	char *argv[3];
	int exitstatus;

	argv[0] = "jview";
	argv[1] = "-?";
	argv[2] = NULL;
	exitstatus = execute ("jview", "jview", argv, false, false, true, true,
			      true, false);
	jview_present = (exitstatus == 0 || exitstatus == 1);
	jview_tested = true;
      }

    if (jview_present)
      {
	char *old_classpath;
	char **argv = (char **) xmalloca ((2 + nargs + 1) * sizeof (char *));
	unsigned int i;

	/* Set CLASSPATH.  */
	old_classpath =
	  set_classpath (classpaths, classpaths_count, use_minimal_classpath,
			 verbose);

	argv[0] = "jview";
	argv[1] = (char *) class_name;
	for (i = 0; i <= nargs; i++)
	  argv[2 + i] = (char *) args[i];

	if (verbose)
	  {
	    char *command = shell_quote_argv (argv);
	    printf ("%s\n", command);
	    free (command);
	  }

	err = executer ("jview", "jview", argv, private_data);

	/* Reset CLASSPATH.  */
	reset_classpath (old_classpath);

	freea (argv);

	goto done2;
      }
  }
#endif

  if (!quiet)
    error (0, 0, _("Java virtual machine not found, try installing gij or set $JAVA"));
  err = true;

 done2:
  if (old_JAVA_HOME != NULL)
    {
      xsetenv ("JAVA_HOME", old_JAVA_HOME, 1);
      free (old_JAVA_HOME);
    }

 done1:
  return err;
}
Ejemplo n.º 27
0
// init handles initialization of the various global state, like goroot and goarch.
void
init(void)
{
	char *p;
	int i;
	Buf b;

	binit(&b);

	xgetenv(&b, "GOROOT");
	if(b.len > 0) {
		// if not "/", then strip trailing path separator
		if(b.len >= 2 && b.p[b.len - 1] == slash[0])
			b.len--;
		goroot = btake(&b);
	}

	xgetenv(&b, "GOBIN");
	if(b.len == 0)
		bprintf(&b, "%s%sbin", goroot, slash);
	gobin = btake(&b);

	xgetenv(&b, "GOOS");
	if(b.len == 0)
		bwritestr(&b, gohostos);
	goos = btake(&b);
	if(find(goos, okgoos, nelem(okgoos)) < 0)
		fatal("unknown $GOOS %s", goos);

	xgetenv(&b, "GOARM");
	if(b.len == 0)
		bwritestr(&b, xgetgoarm());
	goarm = btake(&b);

	xgetenv(&b, "GO386");
	if(b.len == 0) {
		if(cansse2())
			bwritestr(&b, "sse2");
		else
			bwritestr(&b, "387");
	}
	go386 = btake(&b);

	p = bpathf(&b, "%s/include/u.h", goroot);
	if(!isfile(p)) {
		fatal("$GOROOT is not set correctly or not exported\n"
			"\tGOROOT=%s\n"
			"\t%s does not exist", goroot, p);
	}

	xgetenv(&b, "GOHOSTARCH");
	if(b.len > 0)
		gohostarch = btake(&b);

	i = find(gohostarch, okgoarch, nelem(okgoarch));
	if(i < 0)
		fatal("unknown $GOHOSTARCH %s", gohostarch);
	bprintf(&b, "%c", gochars[i]);
	gohostchar = btake(&b);

	xgetenv(&b, "GOARCH");
	if(b.len == 0)
		bwritestr(&b, gohostarch);
	goarch = btake(&b);
	i = find(goarch, okgoarch, nelem(okgoarch));
	if(i < 0)
		fatal("unknown $GOARCH %s", goarch);
	bprintf(&b, "%c", gochars[i]);
	gochar = btake(&b);

	xgetenv(&b, "GO_EXTLINK_ENABLED");
	if(b.len > 0) {
		goextlinkenabled = btake(&b);
		if(!streq(goextlinkenabled, "0") && !streq(goextlinkenabled, "1"))
			fatal("unknown $GO_EXTLINK_ENABLED %s", goextlinkenabled);
	}
	
	xgetenv(&b, "CC");
	if(b.len == 0) {
		// Use clang on OS X, because gcc is deprecated there.
		// Xcode for OS X 10.9 Mavericks will ship a fake "gcc" binary that
		// actually runs clang. We prepare different command
		// lines for the two binaries, so it matters what we call it.
		// See golang.org/issue/5822.
		if(defaultclang)
			bprintf(&b, "clang");
		else
			bprintf(&b, "gcc");
	}
	defaultcc = btake(&b);

	xgetenv(&b, "CFLAGS");
	defaultcflags = btake(&b);

	xgetenv(&b, "LDFLAGS");
	defaultldflags = btake(&b);

	xgetenv(&b, "CC_FOR_TARGET");
	if(b.len == 0) {
		bprintf(&b, defaultcc);
	}
	defaultcctarget = btake(&b);

	xgetenv(&b, "CXX_FOR_TARGET");
	if(b.len == 0) {
		xgetenv(&b, "CXX");
		if(b.len == 0) {
			if(defaultclang)
				bprintf(&b, "clang++");
			else
				bprintf(&b, "g++");
		}
	}
	defaultcxxtarget = btake(&b);

	xsetenv("GOROOT", goroot);
	xsetenv("GOARCH", goarch);
	xsetenv("GOOS", goos);
	xsetenv("GOARM", goarm);
	xsetenv("GO386", go386);

	// Make the environment more predictable.
	xsetenv("LANG", "C");
	xsetenv("LANGUAGE", "en_US.UTF8");

	goversion = findgoversion();

	workdir = xworkdir();
	xatexit(rmworkdir);

	bpathf(&b, "%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch);
	tooldir = btake(&b);

	bfree(&b);
}
Ejemplo n.º 28
0
Archivo: build.c Proyecto: hfeeki/go
// init handles initialization of the various global state, like goroot and goarch.
void
init(void)
{
	char *p;
	int i;
	Buf b;

	binit(&b);

	xgetenv(&b, "GOROOT");
	if(b.len > 0) {
		// if not "/", then strip trailing path separator
		if(b.len >= 2 && b.p[b.len - 1] == slash[0])
			b.len--;
		goroot = btake(&b);
	}

	xgetenv(&b, "GOBIN");
	if(b.len == 0)
		bprintf(&b, "%s%sbin", goroot, slash);
	gobin = btake(&b);

	xgetenv(&b, "GOOS");
	if(b.len == 0)
		bwritestr(&b, gohostos);
	goos = btake(&b);
	if(find(goos, okgoos, nelem(okgoos)) < 0)
		fatal("unknown $GOOS %s", goos);

	p = bpathf(&b, "%s/include/u.h", goroot);
	if(!isfile(p)) {
		fatal("$GOROOT is not set correctly or not exported\n"
			"\tGOROOT=%s\n"
			"\t%s does not exist", goroot, p);
	}

	xgetenv(&b, "GOHOSTARCH");
	if(b.len > 0)
		gohostarch = btake(&b);

	i = find(gohostarch, okgoarch, nelem(okgoarch));
	if(i < 0)
		fatal("unknown $GOHOSTARCH %s", gohostarch);
	bprintf(&b, "%c", gochars[i]);
	gohostchar = btake(&b);

	xgetenv(&b, "GOARCH");
	if(b.len == 0)
		bwritestr(&b, gohostarch);
	goarch = btake(&b);
	i = find(goarch, okgoarch, nelem(okgoarch));
	if(i < 0)
		fatal("unknown $GOARCH %s", goarch);
	bprintf(&b, "%c", gochars[i]);
	gochar = btake(&b);

	xsetenv("GOROOT", goroot);
	xsetenv("GOARCH", goarch);
	xsetenv("GOOS", goos);

	// Make the environment more predictable.
	xsetenv("LANG", "C");
	xsetenv("LANGUAGE", "en_US.UTF8");

	goversion = findgoversion();

	workdir = xworkdir();
	xatexit(rmworkdir);

	bpathf(&b, "%s/pkg/tool/%s_%s", goroot, gohostos, gohostarch);
	tooldir = btake(&b);

	bfree(&b);
}
Ejemplo n.º 29
0
static void xsetenv_if_unset(const char *key, const char *value)
{
	if (!getenv(key))
		xsetenv(key, value);
}
Ejemplo n.º 30
0
static int parse(const char *boundary, char **argv)
{
	char *line, *s, *p;
	const char *type;
	int boundary_len = strlen(boundary);
	const char *delims = " ;\"\t\r\n";
	const char *uniq;
	int ntokens;
	const char *tokens[32]; // 32 is enough

	// prepare unique string pattern
	uniq = xasprintf("%%llu.%u.%s", (unsigned)getpid(), safe_gethostname());

//bb_info_msg("PARSE[%s]", terminator);

	while ((line = xmalloc_fgets_str(stdin, "\r\n\r\n")) != NULL) {

		// seek to start of MIME section
		// N.B. to avoid false positives let us seek to the _last_ occurance
		p = NULL;
		s = line;
		while ((s=strcasestr(s, "Content-Type:")) != NULL)
			p = s++;
		if (!p)
			goto next;
//bb_info_msg("L[%s]", p);

		// split to tokens
		// TODO: strip of comments which are of form: (comment-text)
		ntokens = 0;
		tokens[ntokens] = NULL;
		for (s = strtok(p, delims); s; s = strtok(NULL, delims)) {
			tokens[ntokens] = s;
			if (ntokens < ARRAY_SIZE(tokens) - 1)
				ntokens++;
//bb_info_msg("L[%d][%s]", ntokens, s);
		}
		tokens[ntokens] = NULL;
//bb_info_msg("N[%d]", ntokens);

		// analyse tokens
		type = find_token(tokens, "Content-Type:", "text/plain");
//bb_info_msg("T[%s]", type);
		if (0 == strncasecmp(type, "multipart/", 10)) {
			if (0 == strcasecmp(type+10, "mixed")) {
				parse(xfind_token(tokens, "boundary="), argv);
			} else
				bb_error_msg_and_die("no support of content type '%s'", type);
		} else {
			pid_t pid = pid;
			int rc;
			FILE *fp;
			// fetch charset
			const char *charset = find_token(tokens, "charset=", CONFIG_FEATURE_MIME_CHARSET);
			// fetch encoding
			const char *encoding = find_token(tokens, "Content-Transfer-Encoding:", "7bit");
			// compose target filename
			char *filename = (char *)find_token(tokens, "filename=", NULL);
			if (!filename)
				filename = xasprintf(uniq, monotonic_us());
			else
				filename = bb_get_last_path_component_strip(xstrdup(filename));

			// start external helper, if any
			if (opts & OPT_X) {
				int fd[2];
				xpipe(fd);
				pid = vfork();
				if (0 == pid) {
					// child reads from fd[0]
					xdup2(fd[0], STDIN_FILENO);
					close(fd[0]); close(fd[1]);
					xsetenv("CONTENT_TYPE", type);
					xsetenv("CHARSET", charset);
					xsetenv("ENCODING", encoding);
					xsetenv("FILENAME", filename);
					BB_EXECVP(*argv, argv);
					_exit(EXIT_FAILURE);
				}
				// parent dumps to fd[1]
				close(fd[0]);
				fp = fdopen(fd[1], "w");
				signal(SIGPIPE, SIG_IGN); // ignore EPIPE
			// or create a file for dump
			} else {
				char *fname = xasprintf("%s%s", *argv, filename);
				fp = xfopen_for_write(fname);
				free(fname);
			}

			// housekeeping
			free(filename);

			// dump to fp
			if (0 == strcasecmp(encoding, "base64")) {
				decode_base64(stdin, fp);
			} else if (0 != strcasecmp(encoding, "7bit")
				&& 0 != strcasecmp(encoding, "8bit")) {
				// quoted-printable, binary, user-defined are unsupported so far
				bb_error_msg_and_die("no support of encoding '%s'", encoding);
			} else {
				// N.B. we have written redundant \n. so truncate the file
				// The following weird 2-tacts reading technique is due to
				// we have to not write extra \n at the end of the file
				// In case of -x option we could truncate the resulting file as
				// fseek(fp, -1, SEEK_END);
				// if (ftruncate(fileno(fp), ftell(fp)))
				//	bb_perror_msg("ftruncate");
				// But in case of -X we have to be much more careful. There is
				// no means to truncate what we already have sent to the helper.
				p = xmalloc_fgets_str(stdin, "\r\n");
				while (p) {
					if ((s = xmalloc_fgets_str(stdin, "\r\n")) == NULL)
						break;
					if ('-' == s[0] && '-' == s[1]
						&& 0 == strncmp(s+2, boundary, boundary_len))
						break;
					fputs(p, fp);
					p = s;
				}

/*
				while ((s = xmalloc_fgetline_str(stdin, "\r\n")) != NULL) {
					if ('-' == s[0] && '-' == s[1]
						&& 0 == strncmp(s+2, boundary, boundary_len))
						break;
					fprintf(fp, "%s\n", s);
				}
				// N.B. we have written redundant \n. so truncate the file
				fseek(fp, -1, SEEK_END);
				if (ftruncate(fileno(fp), ftell(fp)))
					bb_perror_msg("ftruncate");
*/
			}
			fclose(fp);

			// finalize helper
			if (opts & OPT_X) {
				signal(SIGPIPE, SIG_DFL);
				// exit if helper exited >0
				rc = wait4pid(pid);
				if (rc)
					return rc+20;
			}

			// check multipart finalized
			if (s && '-' == s[2+boundary_len] && '-' == s[2+boundary_len+1]) {
				free(line);
				break;
			}
		}
 next:
 		free(line);
	}

//bb_info_msg("ENDPARSE[%s]", boundary);

	return EXIT_SUCCESS;
}