Esempio n. 1
0
static bool interface_tests_i(const char* pszHost)
{
	output("\n");

	for (const char** pszDlls = get_dlls(); *pszDlls; ++pszDlls)
	{
		bool bSkipped;
		bool res = do_library_test(make_absolute(*pszDlls),pszHost,bSkipped);

		unregister_library("/Local User");

		if (res && !bSkipped)
			output("[Ok]\n");
	}

	output("  %-46s","Result");

	for (const char** pszExes = get_exes(); *pszExes; ++pszExes)
	{
		bool bSkipped;
		bool res = do_process_test(make_absolute(*pszExes),pszHost,bSkipped);

		unregister_process("/Local User");

		if (res && !bSkipped)
			output("[Ok]\n");
	}

	output("  %-46s","Result");
	return true;
}
bool file_specification::make_absolute(const std::string& root)
{
  if (absolute()) return true;
  file_specification rootspec;
  rootspec.initialise_folder(root);
  return make_absolute(rootspec);
}
Esempio n. 3
0
/* assumes that tree->name and tree->path are already filled in */
void
dirtree_fill_from_dir (dirtree_t * tree)
{
	struct direntry **list;
	int           i, n;
	
	ASSERT_TREE(tree);
	n = my_scandir (tree->path, &list, no_dots_except_include, NULL);
	for (i = 0; i < n; i++)
	{
		dirtree_t    *t = dirtree_new ();

		t->name = mystrdup (list[i]->d_name);
		t->path = make_absolute (tree->path, t->name);
		if (S_ISDIR (list[i]->d_mode))
			t->flags |= DIRTREE_DIR;
		t->mtime = list[i]->d_mtime;

		dirtree_fill_from_dir (t);
		t->parent = tree;
		t->next = tree->child;
		tree->child = t;

		free (list[i]);
	}
	if (n > 0)
	{
		tree->flags |= DIRTREE_DIR;
		free (list);
	}
}
Esempio n. 4
0
/* try to parse the file and line number where the error occurred described in string
 * and when something useful is found, it stores the line number in *line and the
 * relevant file with the error in *filename.
 * *line will be -1 if no error was found in string.
 * *filename must be freed unless it is NULL. */
void msgwin_parse_compiler_error_line(const gchar *string, const gchar *dir,
		gchar **filename, gint *line)
{
	GeanyFiletype *ft;
	gchar *trimmed_string, *utf8_dir;

	*filename = NULL;
	*line = -1;

	if (G_UNLIKELY(string == NULL))
		return;

	if (dir == NULL)
		utf8_dir = utils_get_utf8_from_locale(build_info.dir);
	else
		utf8_dir = g_strdup(dir);
	g_return_if_fail(utf8_dir != NULL);

	trimmed_string = g_strdup(string);
	g_strchug(trimmed_string); /* remove possible leading whitespace */

	ft = filetypes[build_info.file_type_id];

	/* try parsing with a custom regex */
	if (!filetypes_parse_error_message(ft, trimmed_string, filename, line))
	{
		/* fallback to default old-style parsing */
		parse_compiler_error_line(trimmed_string, filename, line);
	}
	make_absolute(filename, utf8_dir);
	g_free(trimmed_string);
	g_free(utf8_dir);
}
Esempio n. 5
0
EntityRef SplashState::loadEntity(const Path& path, EntityRef parent, const Path& cd) {
	Path localPath = make_absolute(cd, path);
	log().info("Load entity \"", localPath, "\"");

	Json::Value json;
	Path realPath = game()->dataPath() / localPath;
	if(!parseJson(json, realPath, localPath, log())) {
		return EntityRef();
	}

	return _entities.createEntityFromJson(parent, json, localPath.dir());
}
Esempio n. 6
0
bool interface_dll_tests()
{
	output("\n");

	for (const char** pszDlls = get_dlls(); *pszDlls; ++pszDlls)
	{
		// Register the library
		Omega::string_t strLibName = make_absolute(*pszDlls);
		output("  %-45s",strLibName.c_str());

		// Register the library
		bool bSkipped;
		bool res = register_library("/Local User",strLibName,bSkipped);
		if (bSkipped)
			continue;

		if (res)
		{
			output("\n");

			res = do_local_library_test("/Local User");

			unregister_library("/Local User");

			if (res)
				output("[Ok]");
		}

		res = register_library("/All Users",strLibName,bSkipped);
		if (res && !bSkipped)
		{
			output("\n");

			res = do_local_library_test("/All Users");

			unregister_library("/All Users");

			if (res)
				output("[Ok]\n");
		}
	}

	output("  %-46s","Result");
	return true;
}
Esempio n. 7
0
bool interface_process_tests()
{
	output("\n");

	for (const char** pszExes = get_exes(); *pszExes; ++pszExes)
	{
		// Register the exe
		Omega::string_t strModulePath = make_absolute(*pszExes);
		output("  %-45s ",strModulePath.c_str());

		bool bSkipped;
		bool res = register_process("/Local User",strModulePath,bSkipped);
		if (bSkipped)
			continue;

		if (res)
		{
			output("\n");

			res = do_local_process_test("/Local User");

			unregister_process("/Local User");

			if (res)
				output("[Ok]");
		}

		res = register_process("/All Users",strModulePath,bSkipped);
		if (res && !bSkipped)
		{
			output("\n");

			res = do_local_process_test("/All Users");

			unregister_process("/All Users");

			if (res)
				output("[Ok]\n");
		}
	}

	output("  %-46s","Result");

	return true;
}
Esempio n. 8
0
void BitmapFontLoader::loadSyncImpl(Logger& log) {
	Json::Value json;
	if(!parseJson(json, realPath(), asset()->logicPath(), log)) {
		return;
	}

	Json::Value imgPathValue = json.get("image", Json::nullValue);
	Path imgPath = imgPathValue.isString()? imgPathValue.asString():
	                                        asset()->logicPath().withExtension("png");
	imgPath = make_absolute(asset()->logicPath().dir(), imgPath);

	AssetSP imgAsset = _manager->loadSync<ImageLoader>(imgPath);

	BitmapFontAspectSP aspect = std::static_pointer_cast<BitmapFontAspect>(_aspect);
	aspect->_set(std::make_shared<BitmapFont>(json, imgAsset));

	_success();
}
Esempio n. 9
0
/**
  * This method is to post-process options once we know all of them
  */
void unionfs_post_opts(void) {
	// chdir to the given chroot, we
	if (uopt.chroot) {
		int res = chdir(uopt.chroot);
		if (res) {
			fprintf(stderr, "Chdir to %s failed: %s ! Aborting!\n",
				  uopt.chroot, strerror(errno));
			exit(1);
		}
	}

	// Make the pathes absolute and add trailing slashes
	int i;
	for (i = 0; i<uopt.nbranches; i++) {
		// if -ochroot= is specified, the path has to be given absolute
		// or relative to the chroot, so no need to make it absolute
		// also won't work, since we are not yet in the chroot here
		if (!uopt.chroot) {
			uopt.branches[i].path = make_absolute(uopt.branches[i].path);
		}
		uopt.branches[i].path = add_trailing_slash(uopt.branches[i].path);

		// Prevent accidental umounts. Especially system shutdown scripts tend
		// to umount everything they can. If we don't have an open file descriptor,
		// this might cause unexpected behaviour.
		char path[PATHLEN_MAX];

		if (!uopt.chroot) {
			BUILD_PATH(path, uopt.branches[i].path);
		} else {
			BUILD_PATH(path, uopt.chroot, uopt.branches[i].path);
		}

		int fd = open(path, O_RDONLY);
		if (fd == -1) {
			fprintf(stderr, "\nFailed to open %s: %s. Aborting!\n\n",
				path, strerror(errno));
			exit(1);
		}
		uopt.branches[i].fd = fd;
		uopt.branches[i].path_len = strlen(path);
	}
}
Esempio n. 10
0
/* Tries to parse strings of the file:line style, allowing line field to be missing
 * * filename is filled with the filename, should be freed
 * * line is filled with the line number or -1 */
static void msgwin_parse_generic_line(const gchar *string, gchar **filename, gint *line)
{
	gchar **fields;
	gboolean incertain = TRUE; /* whether we're reasonably certain of the result */

	*filename = NULL;
	*line = -1;

	fields = g_strsplit(string, ":", 2);
	/* extract the filename */
	if (fields[0] != NULL)
	{
		*filename = utils_get_locale_from_utf8(fields[0]);
		if (msgwindow.messages_dir != NULL)
			make_absolute(filename, msgwindow.messages_dir);

		/* now the line */
		if (fields[1] != NULL)
		{
			gchar *end;

			*line = strtol(fields[1], &end, 10);
			if (end == fields[1])
				*line = -1;
			else if (*end == ':' || g_ascii_isspace(*end))
			{	/* if we have a blank or a separator right after the number, assume we really got a
				 * filename (it's a grep-like syntax) */
				incertain = FALSE;
			}
		}

		/* if we aren't sure we got a supposedly correct filename, check it */
		if (incertain && ! g_file_test(*filename, G_FILE_TEST_EXISTS))
		{
			SETPTR(*filename, NULL);
			*line = -1;
		}
	}
	g_strfreev(fields);
}
Esempio n. 11
0
BitmapTextComponent* BitmapTextComponentManager::addComponentFromJson(
        EntityRef entity, const Json::Value& json, const Path& cd) {
	BitmapTextComponent* comp = addComponent(entity);
	if(json.isMember("font")) {
		comp->setFont(make_absolute(cd, json["font"].asString()));
	}
	if(json.isMember("text")) {
		comp->setText(json["text"].asString());
	}
	if(json.isMember("color")) {
		Json::Value color = json["color"];
		if(color.isArray() || color.size() == 4) {
			comp->setColor(Vector4(color[0].asFloat(), color[1].asFloat(),
			               color[2].asFloat(), color[3].asFloat()));
		} /*else {
			log().warning("Invalid anchor field while loading entity \"", entity.name(), "\".");
		}*/
	}
	if(json.isMember("size")) {
		Json::Value size = json["size"];
		if(size.isArray() || size.size() == 2) {
			comp->setSize(Vector2i(size[0].asInt(), size[1].asInt()));
		} /*else {
			log().warning("Invalid anchor field while loading entity \"", entity.name(), "\".");
		}*/
	}
	if(json.isMember("anchor")) {
		Json::Value anchor = json["anchor"];
		if(anchor.isArray() || anchor.size() == 2) {
			comp->setAnchor(Vector2(anchor[0].asFloat(), anchor[1].asFloat()));
		} /*else {
			log().warning("Invalid anchor field while loading entity \"", entity.name(), "\".");
		}*/
	}
	return comp;
}
Esempio n. 12
0
int
main (int argc, char ** argv)
{
  int rc;
  int need_shell;
  char * cmdline;
  char * progname;
  int envsize;
  char **pass_through_args;
  int num_pass_through_args;
  char modname[MAX_PATH];
  char path[MAX_PATH];
  char dir[MAX_PATH];
  int status;

  interactive = TRUE;

  SetConsoleCtrlHandler ((PHANDLER_ROUTINE) console_event_handler, TRUE);

  if (!GetCurrentDirectory (sizeof (dir), dir))
    fail ("error: GetCurrentDirectory failed\n");

  /* We serve double duty: we can be called either as a proxy for the
     real shell (that is, because we are defined to be the user shell),
     or in our role as a helper application for running DOS programs.
     In the former case, we interpret the command line options as if we
     were a Unix shell, but in the latter case we simply pass our
     command line to CreateProcess.  We know which case we are dealing
     with by whether argv[0] refers to ourself or to some other program.
     (This relies on an arcane feature of CreateProcess, where we can
     specify cmdproxy as the module to run, but specify a different
     program in the command line - the MSVC startup code sets argv[0]
     from the command line.)  */

  if (!GetModuleFileName (NULL, modname, sizeof (modname)))
    fail ("error: GetModuleFileName failed\n");

  /* Change directory to location of .exe so startup directory can be
     deleted.  */
  progname = strrchr (modname, '\\');
  *progname = '\0';
  SetCurrentDirectory (modname);
  *progname = '\\';

  /* Due to problems with interaction between API functions that use "OEM"
     codepage vs API functions that use the "ANSI" codepage, we need to
     make things consistent by choosing one and sticking with it.  */
  SetConsoleCP (GetACP ());
  SetConsoleOutputCP (GetACP ());

  /* Although Emacs always sets argv[0] to an absolute pathname, we
     might get run in other ways as well, so convert argv[0] to an
     absolute name before comparing to the module name.  */
  path[0] = '\0';
  /* The call to SearchPath will find argv[0] in the current
     directory, append ".exe" to it if needed, and also canonicalize
     it, to resolve references to ".", "..", etc.  */
  status = SearchPath (NULL, argv[0], ".exe", sizeof (path), path,
				  &progname);
  if (!(status > 0 && stricmp (modname, path) == 0))
    {
      if (status <= 0)
	{
	  char *s;

	  /* Make sure we have argv[0] in path[], as the failed
	     SearchPath might not have copied it there.  */
	  strcpy (path, argv[0]);
	  /* argv[0] could include forward slashes; convert them all
	     to backslashes, for strrchr calls below to DTRT.  */
	  for (s = path; *s; s++)
	    if (*s == '/')
	      *s = '\\';
	}
      /* Perhaps MODNAME and PATH use mixed short and long file names.  */
      if (!(GetShortPathName (modname, modname, sizeof (modname))
	    && GetShortPathName (path, path, sizeof (path))
	    && stricmp (modname, path) == 0))
	{
	  /* Sometimes GetShortPathName fails because one or more
	     directories leading to argv[0] have issues with access
	     rights.  In that case, at least we can compare the
	     basenames.  Note: this disregards the improbable case of
	     invoking a program of the same name from another
	     directory, since the chances of that other executable to
	     be both our namesake and a 16-bit DOS application are nil.  */
	  char *p = strrchr (path, '\\');
	  char *q = strrchr (modname, '\\');
	  char *pdot, *qdot;

	  if (!p)
	    p = strchr (path, ':');
	  if (!p)
	    p = path;
	  else
	    p++;
	  if (!q)
	    q = strchr (modname, ':');
	  if (!q)
	    q = modname;
	  else
	    q++;

	  pdot = strrchr (p, '.');
	  if (!pdot || stricmp (pdot, ".exe") != 0)
	    pdot = p + strlen (p);
	  qdot = strrchr (q, '.');
	  if (!qdot || stricmp (qdot, ".exe") != 0)
	    qdot = q + strlen (q);
	  if (pdot - p != qdot - q || strnicmp (p, q, pdot - p) != 0)
	    {
	      /* We are being used as a helper to run a DOS app; just
		 pass command line to DOS app without change.  */
	      /* TODO: fill in progname.  */
	      if (spawn (NULL, GetCommandLine (), dir, &rc))
		return rc;
	      fail ("Could not run %s\n", GetCommandLine ());
	    }
	}
    }

  /* Process command line.  If running interactively (-c or /c not
     specified) then spawn a real command shell, passing it the command
     line arguments.

     If not running interactively, then attempt to execute the specified
     command directly.  If necessary, spawn a real shell to execute the
     command.

  */

  progname = NULL;
  cmdline = NULL;
  /* If no args, spawn real shell for interactive use.  */
  need_shell = TRUE;
  interactive = TRUE;
  /* Ask command.com to create an environment block with a reasonable
     amount of free space.  */
  envsize = get_env_size () + 300;
  pass_through_args = (char **) alloca (argc * sizeof (char *));
  num_pass_through_args = 0;

  while (--argc > 0)
    {
      ++argv;
      /* Act on switches we recognize (mostly single letter switches,
	 except for -e); all unrecognized switches and extra args are
	 passed on to real shell if used (only really of benefit for
	 interactive use, but allow for batch use as well).  Accept / as
	 switch char for compatibility with cmd.exe.  */
      if (((*argv)[0] == '-' || (*argv)[0] == '/') && (*argv)[1] != '\0')
	{
	  if (((*argv)[1] == 'c' || (*argv)[1] == 'C') && ((*argv)[2] == '\0'))
	    {
	      if (--argc == 0)
		fail ("error: expecting arg for %s\n", *argv);
	      cmdline = *(++argv);
	      interactive = FALSE;
	    }
	  else if (((*argv)[1] == 'i' || (*argv)[1] == 'I') && ((*argv)[2] == '\0'))
	    {
	      if (cmdline)
		warn ("warning: %s ignored because of -c\n", *argv);
	    }
	  else if (((*argv)[1] == 'e' || (*argv)[1] == 'E') && ((*argv)[2] == ':'))
	    {
	      int requested_envsize = atoi (*argv + 3);
	      /* Enforce a reasonable minimum size, as above.  */
	      if (requested_envsize > envsize)
		envsize = requested_envsize;
	      /* For sanity, enforce a reasonable maximum.  */
	      if (envsize > 32768)
		envsize = 32768;
	    }
	  else
	    {
	      /* warn ("warning: unknown option %s ignored", *argv); */
	      pass_through_args[num_pass_through_args++] = *argv;
	    }
	}
      else
	break;
    }

#if 0
  /* I think this is probably not useful - cmd.exe ignores extra
     (non-switch) args in interactive mode, and they cannot be passed on
     when -c was given.  */

  /* Collect any remaining args after (initial) switches.  */
  while (argc-- > 0)
    {
      pass_through_args[num_pass_through_args++] = *argv++;
    }
#else
  /* Probably a mistake for there to be extra args; not fatal.  */
  if (argc > 0)
    warn ("warning: extra args ignored after '%s'\n", argv[-1]);
#endif

  pass_through_args[num_pass_through_args] = NULL;

  /* If -c option, determine if we must spawn a real shell, or if we can
     execute the command directly ourself.  */
  if (cmdline)
    {
      const char *args;

      /* The program name is the first token of cmdline.  Since
         filenames cannot legally contain embedded quotes, the value
         of escape_char doesn't matter.  */
      args = cmdline;
      if (!get_next_token (path, &args))
        fail ("error: no program name specified.\n");

      canon_filename (path);
      progname = make_absolute (path);

      /* If we found the program and the rest of the command line does
         not contain unquoted shell metacharacters, run the program
         directly (if not found it might be an internal shell command,
         so don't fail).  */
      if (progname != NULL && try_dequote_cmdline (cmdline))
        need_shell = FALSE;
      else
        progname = NULL;
    }

 pass_to_shell:
  if (need_shell)
    {
      char * p;
      int    extra_arg_space = 0;
      int    maxlen, remlen;
      int    run_command_dot_com;

      progname = getenv ("COMSPEC");
      if (!progname)
	fail ("error: COMSPEC is not set\n");

      canon_filename (progname);
      progname = make_absolute (progname);

      if (progname == NULL || strchr (progname, '\\') == NULL)
	fail ("error: the program %s could not be found.\n", getenv ("COMSPEC"));

      /* Need to set environment size when running command.com.  */
      run_command_dot_com =
	(stricmp (strrchr (progname, '\\'), "command.com") == 0);

      /* Work out how much extra space is required for
         pass_through_args.  */
      for (argv = pass_through_args; *argv != NULL; ++argv)
	/* We don't expect to have to quote switches.  */
	extra_arg_space += strlen (*argv) + 2;

      if (cmdline)
	{
	  char * buf;

	  /* Convert to syntax expected by cmd.exe/command.com for
	     running non-interactively.  Always quote program name in
	     case path contains spaces (fortunately it can't contain
	     quotes, since they are illegal in path names).  */

	  remlen = maxlen =
	    strlen (progname) + extra_arg_space + strlen (cmdline) + 16 + 2;
	  buf = p = alloca (maxlen + 1);

	  /* Quote progname in case it contains spaces.  */
	  p += _snprintf (p, remlen, "\"%s\"", progname);
	  remlen = maxlen - (p - buf);

	  /* Include pass_through_args verbatim; these are just switches
             so should not need quoting.  */
	  for (argv = pass_through_args; *argv != NULL; ++argv)
	    {
	      p += _snprintf (p, remlen, " %s", *argv);
	      remlen = maxlen - (p - buf);
	    }

	  /* Now that we know we will be invoking the shell, quote the
	     command line after the "/c" switch as the shell expects:
	     a single pair of quotes enclosing the entire command
	     tail, no matter whether quotes are used in the command
	     line, and how many of them are there.  See the output of
	     "cmd /?" for how cmd.exe treats quotes.  */
	  if (run_command_dot_com)
	    _snprintf (p, remlen, " /e:%d /c \"%s\"", envsize, cmdline);
	  else
	    _snprintf (p, remlen, " /c \"%s\"", cmdline);
	  cmdline = buf;
	}
      else
	{
	  if (run_command_dot_com)
	    {
	      /* Provide dir arg expected by command.com when first
		 started interactively (the "command search path").  To
		 avoid potential problems with spaces in command dir
		 (which cannot be quoted - command.com doesn't like it),
		 we always use the 8.3 form.  */
	      GetShortPathName (progname, path, sizeof (path));
	      p = strrchr (path, '\\');
	      /* Trailing slash is acceptable, so always leave it.  */
	      *(++p) = '\0';
	    }
	  else
	    path[0] = '\0';

	  remlen = maxlen =
	    strlen (progname) + extra_arg_space + strlen (path) + 13;
	  cmdline = p = alloca (maxlen + 1);

	  /* Quote progname in case it contains spaces.  */
	  p += _snprintf (p, remlen, "\"%s\" %s", progname, path);
	  remlen = maxlen - (p - cmdline);

	  /* Include pass_through_args verbatim; these are just switches
             so should not need quoting.  */
	  for (argv = pass_through_args; *argv != NULL; ++argv)
	    {
	      p += _snprintf (p, remlen, " %s", *argv);
	      remlen = maxlen - (p - cmdline);
	    }

	  if (run_command_dot_com)
	    _snprintf (p, remlen, " /e:%d", envsize);
	}
    }

  if (!progname)
    fail ("Internal error: program name not defined\n");

  if (!cmdline)
    cmdline = progname;

  if (spawn (progname, cmdline, dir, &rc))
    return rc;

  if (!need_shell)
    {
      need_shell = TRUE;
      goto pass_to_shell;
    }

  fail ("Could not run %s\n", progname);

  return 0;
}
Esempio n. 13
0
int
interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
{
	char *pwd;
	char *dir = NULL;
	char cmd[2048];
	struct sftp_conn *conn;
	int err, interactive;
	EditLine *el = NULL;
#ifdef USE_LIBEDIT
	History *hl = NULL;
	HistEvent hev;
	extern char *__progname;

	if (!batchmode && isatty(STDIN_FILENO)) {
		if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL)
			fatal("Couldn't initialise editline");
		if ((hl = history_init()) == NULL)
			fatal("Couldn't initialise editline history");
		history(hl, &hev, H_SETSIZE, 100);
		el_set(el, EL_HIST, history, hl);

		el_set(el, EL_PROMPT, prompt);
		el_set(el, EL_EDITOR, "emacs");
		el_set(el, EL_TERMINAL, NULL);
		el_set(el, EL_SIGNAL, 1);
		el_source(el, NULL);
	}
#endif /* USE_LIBEDIT */

	conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
	if (conn == NULL)
		fatal("Couldn't initialise connection to server");

	pwd = do_realpath(conn, ".");
	if (pwd == NULL)
		fatal("Need cwd");

	if (file1 != NULL) {
		dir = xstrdup(file1);
		dir = make_absolute(dir, pwd);

		if (remote_is_dir(conn, dir) && file2 == NULL) {
			printf("Changing to: %s\n", dir);
			snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
			if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0) {
				xfree(dir);
				xfree(pwd);
				return (-1);
			}
		} else {
			if (file2 == NULL)
				snprintf(cmd, sizeof cmd, "get %s", dir);
			else
				snprintf(cmd, sizeof cmd, "get %s %s", dir,
				    file2);

			err = parse_dispatch_command(conn, cmd, &pwd, 1);
			xfree(dir);
			xfree(pwd);
			return (err);
		}
		xfree(dir);
	}

#if defined(HAVE_SETVBUF) && !defined(BROKEN_SETVBUF)
	setvbuf(stdout, NULL, _IOLBF, 0);
	setvbuf(infile, NULL, _IOLBF, 0);
#else
	setlinebuf(stdout);
	setlinebuf(infile);
#endif

	interactive = !batchmode && isatty(STDIN_FILENO);
	err = 0;
	for (;;) {
		char *cp;

		signal(SIGINT, SIG_IGN);

		if (el == NULL) {
			if (interactive)
				printf("sftp> ");
			if (fgets(cmd, sizeof(cmd), infile) == NULL) {
				if (interactive)
					printf("\n");
				break;
			}
			if (!interactive) { /* Echo command */
				printf("sftp> %s", cmd);
				if (strlen(cmd) > 0 &&
				    cmd[strlen(cmd) - 1] != '\n')
					printf("\n");
			}
		} else {
#ifdef USE_LIBEDIT
			const char *line;
			int count = 0;

			if ((line = el_gets(el, &count)) == NULL || count <= 0) {
				printf("\n");
 				break;
			}
			history(hl, &hev, H_ENTER, line);
			if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {
				fprintf(stderr, "Error: input line too long\n");
				continue;
			}
#endif /* USE_LIBEDIT */
		}

		cp = strrchr(cmd, '\n');
		if (cp)
			*cp = '\0';

		/* Handle user interrupts gracefully during commands */
		interrupted = 0;
		signal(SIGINT, cmd_interrupt);

		err = parse_dispatch_command(conn, cmd, &pwd, batchmode);
		if (err != 0)
			break;
	}
	xfree(pwd);

#ifdef USE_LIBEDIT
	if (el != NULL)
		el_end(el);
#endif /* USE_LIBEDIT */

	/* err == 1 signifies normal "quit" exit */
	return (err >= 0 ? 0 : -1);
}
Esempio n. 14
0
/**
 * local implementation of pathfind.
 * @param[in] path  colon separated list of directories
 * @param[in] fname the name we are hunting for
 * @param[in] mode  the required file mode
 * @returns an allocated string with the full path, or NULL
 */
static char *
pathfind( char const * path,
          char const * fname,
          char const * mode )
{
    int    p_index   = 0;
    int    mode_bits = 0;
    char * res_path  = NULL;
    char   zPath[ AG_PATH_MAX + 1 ];

    if (strchr( mode, 'r' )) mode_bits |= R_OK;
    if (strchr( mode, 'w' )) mode_bits |= W_OK;
    if (strchr( mode, 'x' )) mode_bits |= X_OK;

    /*
     *  FOR each non-null entry in the colon-separated path, DO ...
     */
    for (;;) {
        DIR*  dirP;
        char* colon_unit = extract_colon_unit( zPath, path, &p_index );

        if (colon_unit == NULL)
            break;

        dirP = opendir( colon_unit );

        /*
         *  IF the directory is inaccessable, THEN next directory
         */
        if (dirP == NULL)
            continue;

        for (;;) {
            struct dirent *entP = readdir( dirP );

            if (entP == (struct dirent*)NULL)
                break;

            /*
             *  IF the file name matches the one we are looking for, ...
             */
            if (strcmp(entP->d_name, fname) == 0) {
                char * abs_name = make_absolute(fname, colon_unit);

                /*
                 *  Make sure we can access it in the way we want
                 */
                if (access(abs_name, mode_bits) >= 0) {
                    /*
                     *  We can, so normalize the name and return it below
                     */
                    res_path = canonicalize_pathname(abs_name);
                }

                free(abs_name);
                break;
            }
        }

        closedir( dirP );

        if (res_path != NULL)
            break;
    }

    return res_path;
}
Esempio n. 15
0
static gboolean
git_extract_submodule (const char     *repo_location,
                       GFile          *checkout_dir,
                       BuilderContext *context,
                       GError        **error)
{
  g_autofree char *submodule_status = NULL;

  if (!git (checkout_dir, &submodule_status, error,
            "submodule", "status", NULL))
    return FALSE;

  if (submodule_status)
    {
      int i;
      g_auto(GStrv) lines = g_strsplit (submodule_status, "\n", -1);
      for (i = 0; lines[i] != NULL; i++)
        {
          g_autoptr(GFile) mirror_dir = NULL;
          g_autoptr(GFile) child_dir = NULL;
          g_autofree char *child_url = NULL;
          g_autofree char *option = NULL;
          g_autofree char *update_method = NULL;
          g_autofree char *child_relative_url = NULL;
          g_autofree char *mirror_dir_as_url = NULL;
          g_auto(GStrv) words = NULL;
          if (*lines[i] == 0)
            continue;
          words = g_strsplit (lines[i] + 1, " ", 3);

          /* Skip any submodules that are disabled (have the update method set to "none")
             Only check if the command succeeds. If it fails, the update method is not set. */
          option = g_strdup_printf ("submodule.%s.update", words[1]);
          if (git (checkout_dir, &update_method, NULL,
                   "config", "-f", ".gitmodules", option, NULL))
            {
              /* Trim trailing whitespace */
              g_strchomp (update_method);

              if (g_strcmp0 (update_method, "none") == 0)
                continue;
            }

          option = g_strdup_printf ("submodule.%s.url", words[1]);
          if (!git (checkout_dir, &child_relative_url, error,
                    "config", "-f", ".gitmodules", option, NULL))
            return FALSE;

          /* Trim trailing whitespace */
          g_strchomp (child_relative_url);

          g_print ("processing submodule %s\n", words[1]);

          child_url = make_absolute (repo_location, child_relative_url, error);
          if (child_url == NULL)
            return FALSE;

          mirror_dir = git_get_mirror_dir (child_url, context);

          mirror_dir_as_url = g_file_get_uri (mirror_dir);

          if (!git (checkout_dir, NULL, error,
                    "config", option, mirror_dir_as_url, NULL))
            return FALSE;

          if (!git (checkout_dir, NULL, error,
                    "submodule", "update", "--init", words[1], NULL))
            return FALSE;

          child_dir = g_file_resolve_relative_path (checkout_dir, words[1]);

          if (!git_extract_submodule (child_url, child_dir, context, error))
            return FALSE;
        }
    }

  return TRUE;
}
Esempio n. 16
0
static gboolean
git_mirror_submodules (const char     *repo_location,
                       gboolean        update,
                       GFile          *mirror_dir,
                       const char     *revision,
                       BuilderContext *context,
                       GError        **error)
{
  g_autofree char *mirror_dir_path = NULL;

  g_autoptr(GFile) checkout_dir_template = NULL;
  g_autoptr(GFile) checkout_dir = NULL;
  g_autofree char *checkout_dir_path = NULL;
  g_autofree char *submodule_status = NULL;

  mirror_dir_path = g_file_get_path (mirror_dir);

  checkout_dir_template = g_file_get_child (builder_context_get_state_dir (context),
                                            "tmp-checkout-XXXXXX");
  checkout_dir_path = g_file_get_path (checkout_dir_template);

  if (g_mkdtemp (checkout_dir_path) == NULL)
    {
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Can't create temporary checkout directory");
      return FALSE;
    }

  checkout_dir = g_file_new_for_path (checkout_dir_path);

  if (!git (NULL, NULL, error,
            "clone", "-q", "--no-checkout", mirror_dir_path, checkout_dir_path, NULL))
    return FALSE;

  if (!git (checkout_dir, NULL, error, "checkout", "-q", "-f", revision, NULL))
    return FALSE;

  if (!git (checkout_dir, &submodule_status, error,
            "submodule", "status", NULL))
    return FALSE;

  if (submodule_status)
    {
      int i;
      g_auto(GStrv) lines = g_strsplit (submodule_status, "\n", -1);
      for (i = 0; lines[i] != NULL; i++)
        {
          g_autofree char *url = NULL;
          g_autofree char *option = NULL;
          g_autofree char *old = NULL;
          g_auto(GStrv) words = NULL;
          if (*lines[i] == 0)
            continue;
          words = g_strsplit (lines[i] + 1, " ", 3);

          option = g_strdup_printf ("submodule.%s.url", words[1]);
          if (!git (checkout_dir, &url, error,
                    "config", "-f", ".gitmodules", option, NULL))
            return FALSE;
          /* Trim trailing whitespace */
          g_strchomp (url);

          old = url;
          url = make_absolute (repo_location, old, error);
          if (url == NULL)
            return FALSE;

          if (!git_mirror_repo (url, update, words[0], context, error))
            return FALSE;
        }
    }

  if (!gs_shutil_rm_rf (checkout_dir, NULL, error))
    return FALSE;

  return TRUE;
}
Esempio n. 17
0
static ejsval
_ejs_path_relative (ejsval env, ejsval _this, uint32_t argc, ejsval* args)
{
    ejsval from = _ejs_undefined;
    ejsval to   = _ejs_undefined;

    if (argc > 0) from = args[0];
    if (argc > 1) to   = args[1];

    if (!EJSVAL_IS_STRING(from) || !EJSVAL_IS_STRING(to))
        _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Arguments to path.relative must be strings");

    char *from_utf8 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(from));
    char *to_utf8   = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(to));

    if (from_utf8[0] != '/') from_utf8 = make_absolute(from_utf8);
    if (to_utf8[0]   != '/') to_utf8   = make_absolute(to_utf8);

    char* p = to_utf8 + strlen(to_utf8) - 1;
    int up = 0;
    EJSBool seen_slash = EJS_FALSE;

    while (p != to_utf8) {
        if (*p == '/') {
            if (seen_slash) continue; // skip adjacent slashes
            seen_slash = EJS_TRUE;
            char* prefix = strndup(to_utf8, p - to_utf8);
            if (!strcmp(from_utf8, prefix)) {
                up = -1;
                free (prefix);
                goto done;
            }
            if (strstr(from_utf8, prefix) == from_utf8) {
                free (prefix);
                goto done;
            }
            free (prefix);
            up ++;
        }
        else {
            seen_slash = EJS_FALSE;
        }
        p--;
    }
    // we made it all the way to the end, fall through to building up our string

 done:
    {
        ejsval dotdotslash = _ejs_string_new_utf8("../");
        ejsval rv = _ejs_string_new_utf8(p+1);
        while (up >= 0) {
            rv = _ejs_string_concat(dotdotslash, rv);
            up--;
        }

        free (from_utf8);
        free (to_utf8);

        return rv;
    }
}
Esempio n. 18
0
int
dirtree_parse (dirtree_t * tree, const char *file)
{
	FILE         *fp;
	char         *str;
	ASHashTable  *exclusions = NULL; 

	ASSERT_TREE_INT(tree,1);
	
	if( file == NULL ) 
		return 1 ;
	
	if ((fp = fopen (file, "r")) == NULL)
		return 1;
	
	
	str = safemalloc (8192);
	while (fgets (str, 8192, fp) != NULL)
	{
		char         *ptr;
		Bool 	      do_include = False ; 
		int 		  include_order = 0 ;

		ptr = strip_whitespace (str);
		/* ignore comments and blank lines */
		if (*ptr == '#' || *ptr == '\0')
			continue;
		if( !mystrncasecmp (ptr, "exclude", 7) )
		{
			char *excl_name ; 
			if( exclusions == NULL ) 
				exclusions = create_ashash( 0, casestring_hash_value, casestring_compare, string_destroy );
			if( exclusions ) 
			{	
				excl_name = stripcpy2 (ptr +7, 0);
				add_hash_item( exclusions, AS_HASHABLE(excl_name), NULL );
			}
			continue;
		}		
		
		if( !mystrncasecmp (ptr, "category", 8) )
		{
			char *cat_name;
			Bool include_children = False;
			ptr+= 8 ;
			if( *ptr == '_' ) ++ptr ;
			if( !mystrncasecmp (ptr, "tree", 4))
			{
				include_children = True ;
				ptr += 4 ;	  
			}
			cat_name = stripcpy2 (ptr, 0);
			dirtree_add_category_by_name (tree, cat_name, include_children, exclusions);
			free( cat_name );
			continue;
		}
		   
		if( !mystrncasecmp (ptr, "include", 7) )
		{
			do_include = True ;
			ptr += 7 ; 
			if( *ptr == '_' ) ++ptr ;
			if( !mystrncasecmp (ptr, "ordered", 7) ) 	  
			{
				for (ptr += 7; isspace (*ptr); ptr++);				
				if ( isdigit(*ptr) )
				{
					include_order = atoi( ptr );	
					while( isdigit( *ptr ) ) ++ptr;
				}	 
			}	 
		}
			
		if( do_include )   
		{
			char         *path;
			dirtree_t    *t;

			while(isspace (*ptr))	ptr++;
			if (*ptr != '"')
				continue;
			path = ++ptr;
			for (; *ptr != '\0' && *ptr != '"'; ptr++);
			if (*ptr == '"')
				for (*ptr++ = '\0'; isspace (*ptr); ptr++);
			path = make_absolute (tree->path, path);
			t = dirtree_new_from_dir (path);
			free (path);
			if (t != NULL)
			{
				if (*ptr != '\0')
				{
					txt2func (ptr, &t->command, False);
					dirtree_set_command (t, &t->command, 1);
				}

				/* included dir might have a .include */
				dirtree_parse_include (t);
				if( include_order != 0 ) 
					dirtree_set_base_order ( t, include_order);

				dirtree_move_children (tree, t);
				dirtree_delete (t);
			}
		} else if (!mystrncasecmp (ptr, "keepname", 8))
			tree->flags |= DIRTREE_KEEPNAME;
		else   if (!mystrncasecmp (ptr, "ShowUnavailable", 15))
			tree->flags |= DIRTREE_SHOW_UNAVAILABLE;
		   else if (!mystrncasecmp (ptr, "extension", 9))
		{
			char         *tmp;

			for (ptr += 9; isspace (*ptr); ptr++);
			for (tmp = ptr + strlen (ptr); tmp > ptr && isspace (*(tmp - 1)); tmp--);
			if (tmp != ptr)
			{
				if( tree->extension ) free( tree->extension );
				tree->extension = mystrndup (ptr, tmp - ptr);
			}
		}else if (!mystrncasecmp (ptr, "miniextension", 13))
		{
			char         *tmp;

			for (ptr += 13; isspace (*ptr); ptr++);
			for (tmp = ptr + strlen (ptr); tmp > ptr && isspace (*(tmp - 1)); tmp--);
			if (tmp != ptr)
				tree->minipixmap_extension = mystrndup (ptr, tmp - ptr);
		} else if (!mystrncasecmp (ptr, "minipixmap", 10) || !mystrncasecmp (ptr, "smallminipixmap", 15))
		{
			if( ptr[0] == 's' || ptr[0] == 'S' )
			{	
				set_flags(tree->flags, DIRTREE_ICON_IS_SMALL);
				ptr += 5 ;
			}else
				clear_flags(tree->flags, DIRTREE_ICON_IS_SMALL);
			set_string(&(tree->icon), stripcpy2(ptr+10,False));

		} else if (!mystrncasecmp (ptr, "command", 7))
		{
			for (ptr += 7; isspace (*ptr); ptr++);
			txt2func (ptr, &tree->command, False);
			dirtree_set_command (tree, &tree->command, 0);
		} else if (!mystrncasecmp (ptr, "order", 5))
		{	
			tree->order = strtol (ptr + 5, NULL, 10);
		} else if (!mystrncasecmp (ptr, "RecentSubmenuItems", 18))
		{	
			tree->recent_items = strtol (ptr + 18, NULL, 10);
			tree->flags |= DIRTREE_RECENT_ITEMS_SET;
		} else if (!mystrncasecmp (ptr, "name", 4))
		{
			set_string(&(tree->name), stripcpy2(ptr+4,False));
			clear_flags( tree->flags, DIRTREE_NAME_IS_UTF8 );
		}else if (!mystrncasecmp (ptr, "Comment", 7))
		{
			set_string(&(tree->Comment), stripcpy2(ptr+7,False));
			clear_flags( tree->flags, DIRTREE_COMMENT_IS_UTF8 );
		}else if (!mystrncasecmp (ptr, "FolderReference", 15))
		{
			set_string(&(tree->FolderReference), stripcpy2(ptr+15,False));
			dirtree_fill_from_reference( tree, tree->FolderReference );
		}
	}
	free (str);
	fclose (fp);
	return 0;
}
Esempio n. 19
0
static int
process_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
{
	char *abs_src = NULL;
	char *abs_dst = NULL;
	char *tmp;
	glob_t g;
	int err = 0;
	int i;

	abs_src = xstrdup(src);
	abs_src = make_absolute(abs_src, pwd);

	memset(&g, 0, sizeof(g));
	debug3("Looking up %s", abs_src);
	if (remote_glob(conn, abs_src, 0, NULL, &g)) {
		error("File \"%s\" not found.", abs_src);
		err = -1;
		goto out;
	}

	/* If multiple matches, dst must be a directory or unspecified */
	if (g.gl_matchc > 1 && dst && !is_dir(dst)) {
		error("Multiple files match, but \"%s\" is not a directory",
		    dst);
		err = -1;
		goto out;
	}

	for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
		if (infer_path(g.gl_pathv[i], &tmp)) {
			err = -1;
			goto out;
		}

		if (g.gl_matchc == 1 && dst) {
			/* If directory specified, append filename */
			if (is_dir(dst)) {
				if (infer_path(g.gl_pathv[0], &tmp)) {
					err = 1;
					goto out;
				}
				abs_dst = path_append(dst, tmp);
				xfree(tmp);
			} else
				abs_dst = xstrdup(dst);
		} else if (dst) {
			abs_dst = path_append(dst, tmp);
			xfree(tmp);
		} else
			abs_dst = tmp;

		printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
		if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
			err = -1;
		xfree(abs_dst);
		abs_dst = NULL;
	}

out:
	xfree(abs_src);
	if (abs_dst)
		xfree(abs_dst);
	globfree(&g);
	return(err);
}
Esempio n. 20
0
static int
parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
    int err_abort)
{
	char *path1, *path2, *tmp;
	int pflag, lflag, iflag, cmdnum, i;
	unsigned long n_arg;
	Attrib a, *aa;
	char path_buf[MAXPATHLEN];
	int err = 0;
	glob_t g;

	path1 = path2 = NULL;
	cmdnum = parse_args(&cmd, &pflag, &lflag, &iflag, &n_arg,
	    &path1, &path2);

	if (iflag != 0)
		err_abort = 0;

	memset(&g, 0, sizeof(g));

	/* Perform command */
	switch (cmdnum) {
	case 0:
		/* Blank line */
		break;
	case -1:
		/* Unrecognized command */
		err = -1;
		break;
	case I_GET:
		err = process_get(conn, path1, path2, *pwd, pflag);
		break;
	case I_PUT:
		err = process_put(conn, path1, path2, *pwd, pflag);
		break;
	case I_RENAME:
		path1 = make_absolute(path1, *pwd);
		path2 = make_absolute(path2, *pwd);
		err = do_rename(conn, path1, path2);
		break;
	case I_SYMLINK:
		path2 = make_absolute(path2, *pwd);
		err = do_symlink(conn, path1, path2);
		break;
	case I_RM:
		path1 = make_absolute(path1, *pwd);
		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
			printf("Removing %s\n", g.gl_pathv[i]);
			err = do_rm(conn, g.gl_pathv[i]);
			if (err != 0 && err_abort)
				break;
		}
		break;
	case I_MKDIR:
		path1 = make_absolute(path1, *pwd);
		attrib_clear(&a);
		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
		a.perm = 0777;
		err = do_mkdir(conn, path1, &a);
		break;
	case I_RMDIR:
		path1 = make_absolute(path1, *pwd);
		err = do_rmdir(conn, path1);
		break;
	case I_CHDIR:
		path1 = make_absolute(path1, *pwd);
		if ((tmp = do_realpath(conn, path1)) == NULL) {
			err = 1;
			break;
		}
		if ((aa = do_stat(conn, tmp, 0)) == NULL) {
			xfree(tmp);
			err = 1;
			break;
		}
		if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
			error("Can't change directory: Can't check target");
			xfree(tmp);
			err = 1;
			break;
		}
		if (!S_ISDIR(aa->perm)) {
			error("Can't change directory: \"%s\" is not "
			    "a directory", tmp);
			xfree(tmp);
			err = 1;
			break;
		}
		xfree(*pwd);
		*pwd = tmp;
		break;
	case I_LS:
		if (!path1) {
			do_globbed_ls(conn, *pwd, *pwd, lflag);
			break;
		}

		/* Strip pwd off beginning of non-absolute paths */
		tmp = NULL;
		if (*path1 != '/')
			tmp = *pwd;

		path1 = make_absolute(path1, *pwd);
		err = do_globbed_ls(conn, path1, tmp, lflag);
		break;
	case I_LCHDIR:
		if (chdir(path1) == -1) {
			error("Couldn't change local directory to "
			    "\"%s\": %s", path1, strerror(errno));
			err = 1;
		}
		break;
	case I_LMKDIR:
		if (mkdir(path1, 0777) == -1) {
			error("Couldn't create local directory "
			    "\"%s\": %s", path1, strerror(errno));
			err = 1;
		}
		break;
	case I_LLS:
		local_do_ls(cmd);
		break;
	case I_SHELL:
		local_do_shell(cmd);
		break;
	case I_LUMASK:
		umask(n_arg);
		printf("Local umask: %03lo\n", n_arg);
		break;
	case I_CHMOD:
		path1 = make_absolute(path1, *pwd);
		attrib_clear(&a);
		a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;
		a.perm = n_arg;
		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
			printf("Changing mode on %s\n", g.gl_pathv[i]);
			err = do_setstat(conn, g.gl_pathv[i], &a);
			if (err != 0 && err_abort)
				break;
		}
		break;
	case I_CHOWN:
	case I_CHGRP:
		path1 = make_absolute(path1, *pwd);
		remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);
		for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
			if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
				if (err != 0 && err_abort)
					break;
				else
					continue;
			}
			if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
				error("Can't get current ownership of "
				    "remote file \"%s\"", g.gl_pathv[i]);
				if (err != 0 && err_abort)
					break;
				else
					continue;
			}
			aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;
			if (cmdnum == I_CHOWN) {
				printf("Changing owner on %s\n", g.gl_pathv[i]);
				aa->uid = n_arg;
			} else {
				printf("Changing group on %s\n", g.gl_pathv[i]);
				aa->gid = n_arg;
			}
			err = do_setstat(conn, g.gl_pathv[i], aa);
			if (err != 0 && err_abort)
				break;
		}
		break;
	case I_PWD:
		printf("Remote working directory: %s\n", *pwd);
		break;
	case I_LPWD:
		if (!getcwd(path_buf, sizeof(path_buf))) {
			error("Couldn't get local cwd: %s", strerror(errno));
			err = -1;
			break;
		}
		printf("Local working directory: %s\n", path_buf);
		break;
	case I_QUIT:
		/* Processed below */
		break;
	case I_HELP:
		help();
		break;
	case I_VERSION:
		printf("SFTP protocol version %u\n", sftp_proto_version(conn));
		break;
	case I_PROGRESS:
		showprogress = !showprogress;
		if (showprogress)
			printf("Progress meter enabled\n");
		else
			printf("Progress meter disabled\n");
		break;
	default:
		fatal("%d is not implemented", cmdnum);
	}

	if (g.gl_pathc)
		globfree(&g);
	if (path1)
		xfree(path1);
	if (path2)
		xfree(path2);

	/* If an unignored error occurs in batch mode we should abort. */
	if (err_abort && err != 0)
		return (-1);
	else if (cmdnum == I_QUIT)
		return (1);

	return (0);
}
Esempio n. 21
0
static int
process_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag)
{
	char *tmp_dst = NULL;
	char *abs_dst = NULL;
	char *tmp;
	glob_t g;
	int err = 0;
	int i;

	if (dst) {
		tmp_dst = xstrdup(dst);
		tmp_dst = make_absolute(tmp_dst, pwd);
	}

	memset(&g, 0, sizeof(g));
	debug3("Looking up %s", src);
	if (glob(src, 0, NULL, &g)) {
		error("File \"%s\" not found.", src);
		err = -1;
		goto out;
	}

	/* If multiple matches, dst may be directory or unspecified */
	if (g.gl_matchc > 1 && tmp_dst && !remote_is_dir(conn, tmp_dst)) {
		error("Multiple files match, but \"%s\" is not a directory",
		    tmp_dst);
		err = -1;
		goto out;
	}

	for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
		if (!is_reg(g.gl_pathv[i])) {
			error("skipping non-regular file %s",
			    g.gl_pathv[i]);
			continue;
		}
		if (infer_path(g.gl_pathv[i], &tmp)) {
			err = -1;
			goto out;
		}

		if (g.gl_matchc == 1 && tmp_dst) {
			/* If directory specified, append filename */
			if (remote_is_dir(conn, tmp_dst)) {
				if (infer_path(g.gl_pathv[0], &tmp)) {
					err = 1;
					goto out;
				}
				abs_dst = path_append(tmp_dst, tmp);
				xfree(tmp);
			} else
				abs_dst = xstrdup(tmp_dst);

		} else if (tmp_dst) {
			abs_dst = path_append(tmp_dst, tmp);
			xfree(tmp);
		} else
			abs_dst = make_absolute(tmp, pwd);

		printf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
		if (do_upload(conn, g.gl_pathv[i], abs_dst, pflag) == -1)
			err = -1;
	}

out:
	if (abs_dst)
		xfree(abs_dst);
	if (tmp_dst)
		xfree(tmp_dst);
	globfree(&g);
	return(err);
}
Esempio n. 22
0
int
main (int argc, char ** argv)
{
  int rc;
  int need_shell;
  char * cmdline;
  char * progname;
  int envsize;
  char **pass_through_args;
  int num_pass_through_args;
  char modname[MAX_PATH];
  char path[MAX_PATH];
  char dir[MAX_PATH];


  interactive = TRUE;

  SetConsoleCtrlHandler ((PHANDLER_ROUTINE) console_event_handler, TRUE);

  if (!GetCurrentDirectory (sizeof (dir), dir))
    fail ("error: GetCurrentDirectory failed\n");

  /* We serve double duty: we can be called either as a proxy for the
     real shell (that is, because we are defined to be the user shell),
     or in our role as a helper application for running DOS programs.
     In the former case, we interpret the command line options as if we
     were a Unix shell, but in the latter case we simply pass our
     command line to CreateProcess.  We know which case we are dealing
     with by whether argv[0] refers to ourself or to some other program.
     (This relies on an arcane feature of CreateProcess, where we can
     specify cmdproxy as the module to run, but specify a different
     program in the command line - the MSVC startup code sets argv[0]
     from the command line.)  */

  if (!GetModuleFileName (NULL, modname, sizeof (modname)))
    fail ("error: GetModuleFileName failed\n");

  /* Change directory to location of .exe so startup directory can be
     deleted.  */
  progname = strrchr (modname, '\\');
  *progname = '\0';
  SetCurrentDirectory (modname);
  *progname = '\\';

  /* Although Emacs always sets argv[0] to an absolute pathname, we
     might get run in other ways as well, so convert argv[0] to an
     absolute name before comparing to the module name.  Don't get
     caught out by mixed short and long names.  */
  GetShortPathName (modname, modname, sizeof (modname));
  path[0] = '\0';
  if (!SearchPath (NULL, argv[0], ".exe", sizeof (path), path, &progname)
      || !GetShortPathName (path, path, sizeof (path))
      || stricmp (modname, path) != 0)
    {
      /* We are being used as a helper to run a DOS app; just pass
	 command line to DOS app without change.  */
      /* TODO: fill in progname.  */
      if (spawn (NULL, GetCommandLine (), dir, &rc))
	return rc;
      fail ("Could not run %s\n", GetCommandLine ());
    }

  /* Process command line.  If running interactively (-c or /c not
     specified) then spawn a real command shell, passing it the command
     line arguments.

     If not running interactively, then attempt to execute the specified
     command directly.  If necessary, spawn a real shell to execute the
     command.

  */

  progname = NULL;
  cmdline = NULL;
  /* If no args, spawn real shell for interactive use.  */
  need_shell = TRUE;
  interactive = TRUE;
  /* Ask command.com to create an environment block with a reasonable
     amount of free space.  */
  envsize = get_env_size () + 300;
  pass_through_args = (char **) alloca (argc * sizeof(char *));
  num_pass_through_args = 0;

  while (--argc > 0)
    {
      ++argv;
      /* Act on switches we recognize (mostly single letter switches,
	 except for -e); all unrecognised switches and extra args are
	 passed on to real shell if used (only really of benefit for
	 interactive use, but allow for batch use as well).  Accept / as
	 switch char for compatability with cmd.exe.  */
      if (((*argv)[0] == '-' || (*argv)[0] == '/') && (*argv)[1] != '\0')
	{
	  if (((*argv)[1] == 'c' || (*argv)[1] == 'C') && ((*argv)[2] == '\0'))
	    {
	      if (--argc == 0)
		fail ("error: expecting arg for %s\n", *argv);
	      cmdline = *(++argv);
	      interactive = FALSE;
	    }
	  else if (((*argv)[1] == 'i' || (*argv)[1] == 'I') && ((*argv)[2] == '\0'))
	    {
	      if (cmdline)
		warn ("warning: %s ignored because of -c\n", *argv);
	    }
	  else if (((*argv)[1] == 'e' || (*argv)[1] == 'E') && ((*argv)[2] == ':'))
	    {
	      int requested_envsize = atoi (*argv + 3);
	      /* Enforce a reasonable minimum size, as above.  */
	      if (requested_envsize > envsize)
		envsize = requested_envsize;
	      /* For sanity, enforce a reasonable maximum.  */
	      if (envsize > 32768)
		envsize = 32768;
	    }
	  else
	    {
	      /* warn ("warning: unknown option %s ignored", *argv); */
	      pass_through_args[num_pass_through_args++] = *argv;
	    }
	}
      else
	break;
    }

#if 0
  /* I think this is probably not useful - cmd.exe ignores extra
     (non-switch) args in interactive mode, and they cannot be passed on
     when -c was given.  */

  /* Collect any remaining args after (initial) switches.  */
  while (argc-- > 0)
    {
      pass_through_args[num_pass_through_args++] = *argv++;
    }
#else
  /* Probably a mistake for there to be extra args; not fatal.  */
  if (argc > 0)
    warn ("warning: extra args ignored after '%s'\n", argv[-1]);
#endif

  pass_through_args[num_pass_through_args] = NULL;

  /* If -c option, determine if we must spawn a real shell, or if we can
     execute the command directly ourself.  */
  if (cmdline)
    {
      /* If no redirection or piping, and if program can be found, then
	 run program directly.  Otherwise invoke a real shell. */

      static char copout_chars[] = "|<>&";

      if (strpbrk (cmdline, copout_chars) == NULL)
	{
 	  char *args;

	  /* The program name is the first token of cmdline.  Since
	     filenames cannot legally contain embedded quotes, the value
	     of escape_char doesn't matter.  */
	  args = cmdline;
	  if (!get_next_token (path, &args))
	    fail ("error: no program name specified.\n");

	  canon_filename (path);
	  progname = make_absolute (path);

	  /* If we found the program, run it directly (if not found it
             might be an internal shell command, so don't fail).  */
	  if (progname != NULL)
	    need_shell = FALSE;
	}
    }

 pass_to_shell:
  if (need_shell)
    {
      char * p;
      int    extra_arg_space = 0;
      int    run_command_dot_com;

      progname = getenv ("COMSPEC");
      if (!progname)
	fail ("error: COMSPEC is not set\n");

      canon_filename (progname);
      progname = make_absolute (progname);

      if (progname == NULL || strchr (progname, '\\') == NULL)
	fail ("error: the program %s could not be found.\n", getenv ("COMSPEC"));

      /* Need to set environment size when running command.com.  */
      run_command_dot_com =
	(stricmp (strrchr (progname, '\\'), "command.com") == 0);

      /* Work out how much extra space is required for
         pass_through_args.  */
      for (argv = pass_through_args; *argv != NULL; ++argv)
	/* We don't expect to have to quote switches.  */
	extra_arg_space += strlen (*argv) + 2;

      if (cmdline)
	{
	  char * buf;

	  /* Convert to syntax expected by cmd.exe/command.com for
	     running non-interactively.  Always quote program name in
	     case path contains spaces (fortunately it can't contain
	     quotes, since they are illegal in path names).  */

	  buf = p = alloca (strlen (progname) + extra_arg_space +
			    strlen (cmdline) + 16);

	  /* Quote progname in case it contains spaces.  */
	  p += wsprintf (p, "\"%s\"", progname);

	  /* Include pass_through_args verbatim; these are just switches
             so should not need quoting.  */
	  for (argv = pass_through_args; *argv != NULL; ++argv)
	    p += wsprintf (p, " %s", *argv);

	  if (run_command_dot_com)
	    wsprintf(p, " /e:%d /c %s", envsize, cmdline);
	  else
	    wsprintf(p, " /c %s", cmdline);
	  cmdline = buf;
	}
      else
	{
	  if (run_command_dot_com)
	    {
	      /* Provide dir arg expected by command.com when first
		 started interactively (the "command search path").  To
		 avoid potential problems with spaces in command dir
		 (which cannot be quoted - command.com doesn't like it),
		 we always use the 8.3 form.  */
	      GetShortPathName (progname, path, sizeof (path));
	      p = strrchr (path, '\\');
	      /* Trailing slash is acceptable, so always leave it.  */
	      *(++p) = '\0';
	    }
	  else
	    path[0] = '\0';

	  cmdline = p = alloca (strlen (progname) + extra_arg_space +
				strlen (path) + 13);

	  /* Quote progname in case it contains spaces.  */
	  p += wsprintf (p, "\"%s\" %s", progname, path);

	  /* Include pass_through_args verbatim; these are just switches
             so should not need quoting.  */
	  for (argv = pass_through_args; *argv != NULL; ++argv)
	    p += wsprintf (p, " %s", *argv);

	  if (run_command_dot_com)
	    wsprintf (p, " /e:%d", envsize);
	}
    }

  if (!progname)
    fail ("Internal error: program name not defined\n");

  if (!cmdline)
    cmdline = progname;

  if (spawn (progname, cmdline, dir, &rc))
    return rc;

  if (!need_shell)
    {
      need_shell = TRUE;
      goto pass_to_shell;
    }

  fail ("Could not run %s\n", progname);

  return 0;
}
Esempio n. 23
0
int
interactive_loop(int fd_in, int fd_out, char *file1, char *file2)
{
	char *pwd;
	char *dir = NULL;
	char cmd[2048];
	struct sftp_conn *conn;
	int err, interactive;
	void *il = NULL;

#ifdef USE_LIBEDIT
        EditLine *el = NULL;
	History *hl = NULL;
	HistEvent hev;

	if (!batchmode && isatty(STDIN_FILENO)) {
		if ((il = el = el_init(__progname, stdin, stdout, stderr)) == NULL)
			fatal("Couldn't initialise editline");
		if ((hl = history_init()) == NULL)
			fatal("Couldn't initialise editline history");
		history(hl, &hev, H_SETSIZE, 100);
		el_set(el, EL_HIST, history, hl);

		el_set(el, EL_PROMPT, prompt);
		el_set(el, EL_EDITOR, "emacs");
		el_set(el, EL_TERMINAL, NULL);
		el_set(el, EL_SIGNAL, 1);
		el_source(el, NULL);
	}
#else
#ifdef USE_LIBTECLA
	GetLine *gl = NULL;

	if (!batchmode && isatty(STDIN_FILENO)) {
		if ((il = gl = new_GetLine(MAX_LINE_LEN, MAX_CMD_HIST)) == NULL)
			fatal("Couldn't initialize GetLine");
		if (gl_customize_completion(gl, NULL, nomatch) != 0) {
			(void) del_GetLine(gl);
			fatal("Couldn't register completion function");
		}
	}
#endif /* USE_LIBTECLA */
#endif /* USE_LIBEDIT */

	conn = do_init(fd_in, fd_out, copy_buffer_len, num_requests);
	if (conn == NULL)
		fatal("Couldn't initialise connection to server");

	pwd = do_realpath(conn, ".");
	if (pwd == NULL)
		fatal("Need cwd");

	if (file1 != NULL) {
		dir = xstrdup(file1);
		dir = make_absolute(dir, pwd);

		if (remote_is_dir(conn, dir) && file2 == NULL) {
			printf(gettext("Changing to: %s\n"), dir);
			snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);
			if (parse_dispatch_command(conn, cmd, &pwd, 1) != 0) {
				xfree(dir);
				xfree(pwd);
				xfree(conn);
				return (-1);
			}
		} else {
			if (file2 == NULL)
				snprintf(cmd, sizeof cmd, "get %s", dir);
			else
				snprintf(cmd, sizeof cmd, "get %s %s", dir,
				    file2);

			err = parse_dispatch_command(conn, cmd, &pwd, 1);
			xfree(dir);
			xfree(pwd);
			xfree(conn);
			return (err);
		}
		xfree(dir);
	}

#if defined(HAVE_SETVBUF) && !defined(BROKEN_SETVBUF)
	setvbuf(stdout, NULL, _IOLBF, 0);
	setvbuf(infile, NULL, _IOLBF, 0);
#else
	setlinebuf(stdout);
	setlinebuf(infile);
#endif

	interactive = !batchmode && isatty(STDIN_FILENO);
	err = 0;
	for (;;) {
		char *cp;

		signal(SIGINT, SIG_IGN);

		if (il == NULL) {
			if (interactive)
				printf("sftp> ");
			if (fgets(cmd, sizeof(cmd), infile) == NULL) {
				if (interactive)
					printf("\n");
				break;
			}
			if (!interactive) { /* Echo command */
				printf("sftp> %s", cmd);
				if (strlen(cmd) > 0 &&
				    cmd[strlen(cmd) - 1] != '\n')
					printf("\n");
			}
		}
#ifdef USE_LIBEDIT
		else {
			const char *line;
			int count = 0;

			if ((line = el_gets(el, &count)) == NULL || count <= 0) {
				printf("\n");
 				break;
			}
			history(hl, &hev, H_ENTER, line);
			if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {
				fprintf(stderr, gettext("Error: input line too long\n"));
				continue;
			}
		}
#else
#ifdef USE_LIBTECLA
		else {
			const char *line;

			line = gl_get_line(gl, "sftp> ", NULL, -1);
			if (line != NULL) {
				if (strlcpy(cmd, line, sizeof(cmd)) >=
				    sizeof(cmd)) {
					fprintf(stderr, gettext(
					    "Error: input line too long\n"));
					continue;
				}
			} else {
				GlReturnStatus rtn;

				rtn = gl_return_status(gl);
				if (rtn == GLR_SIGNAL) {
					gl_abandon_line(gl);
					continue;
				} else if (rtn == GLR_ERROR) {
					fprintf(stderr, gettext(
					    "Error reading terminal: %s/\n"),
					    gl_error_message(gl, NULL, 0));
				}
				break;
			}
		}
#endif /* USE_LIBTECLA */
#endif /* USE_LIBEDIT */

		cp = strrchr(cmd, '\n');
		if (cp)
			*cp = '\0';

		/* Handle user interrupts gracefully during commands */
		interrupted = 0;
		signal(SIGINT, cmd_interrupt);

		err = parse_dispatch_command(conn, cmd, &pwd, batchmode);
		if (err != 0)
			break;
	}