示例#1
0
int builtin_catenate(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {

	if (tokens.size() == 1) {
		int rv = cat_helper(stdin, stdout);
		if (rv) fdputs("### Catenate - I/O Error\n", stderr);
		return rv;
	}

	for (const auto &s : make_offset_range(tokens, 1)) {

		std::string path = ToolBox::MacToUnix(s);
		int fd = open(path.c_str(), O_RDONLY);
		if (fd < 0) {
			fdprintf(stderr, "### Catenate - Unable to open \"%s\".\n", path.c_str());
			return 1;
		}

		int rv = cat_helper(fd, stdout);
		close(fd);
		if (rv) {
			fdputs("### Catenate - I/O Error\n", stderr);
			return rv;
		}
	}
	return 0;
}
示例#2
0
int builtin_set(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {
	// set var name  -- set
	// set var -- just print the value

	// 3.5 supports -e to also export it.

	//io_helper io(fds);


	if (tokens.size() == 1) {

		for (const auto &kv : env) {
			std::string name = quote(kv.first);
			std::string value = quote(kv.second);

			fdprintf(stdout, "Set %s%s %s\n",
				bool(kv.second) ? "-e " : "", 
				name.c_str(), value.c_str());
		}
		return 0;
	}

	if (tokens.size() == 2) {
		std::string name = tokens[1];
		auto iter = env.find(name);
		if 	(iter == env.end()) {
			fdprintf(stderr, "### Set - No variable definition exists for %s.\n", name.c_str());
			return 2;
		}

		name = quote(name);
		std::string value = quote(iter->second);
		fdprintf(stdout, "Set %s%s %s\n", 
			bool(iter->second) ? "-e " : "", 
			name.c_str(), value.c_str());
		return 0;
	}

	bool exported = false;


	if (tokens.size() == 4 && tokens[1] == "-e") {
		exported = true;
	}

	if (tokens.size() > 3 && !exported) {
		fdputs("### Set - Too many parameters were specified.\n", stderr);
		fdputs("# Usage - set [name [value]]\n", stderr);
		return 1;
	}

	std::string name = tokens[1+exported];
	std::string value = tokens[2+exported];

	env.set(name, value, exported);
	return 0;
}
示例#3
0
static int
outspkr(const char *s)
{
	int err = -1, fd = open("/dev/speaker", O_WRONLY);
	if (fd >= 0) {
		fdputs(initcmd, fd, 0);
		err = fdputs(s, fd, verbose);
		close(fd);
	}
	return err;
}/* outspkr */
示例#4
0
bool help_helper(const mapped_file &f, const fdmask &fds, const std::string &cmd) {

	/*
	 * format is:
	 * -\n
	 * name whitespace
	 * ....
	 * -\n
	 */

	if (f.size() < 2) return false;
	auto iter = f.begin();
	auto end = f.end();

	if (iter[0] != '-' && iter[1] != '\n') {
		iter = find_entry(iter, end);
	}

	if (cmd.empty()) {
		// print first entry
		write(stdout, f.begin(), std::distance(f.begin(), iter));
		fdputs("\n", stdout);
		return true;
	}

	for(;;) {

		if (iter == end) return false;

		iter += 2;
		auto next = find_entry(iter, end);

 		auto l = std::distance(iter, end);
 		if (help_name_match(cmd.begin(), cmd.end(), iter, next)) {

			write(stdout, iter, std::distance(iter, next));
			fdputs("\n", stdout);

 			return true;
 		}

		iter = next;
	}
}
示例#5
0
int builtin_echo(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {

	//io_helper io(fds);

	bool space = false;
	bool n = false;

	for (const auto &s : make_offset_range(tokens, 1)) {
		if (s == "-n" || s == "-N") {
			n = true;
			continue;
		}
		if (space) {
			fdputs(" ", stdout);
		}
		fdputs(s.c_str(), stdout);
		space = true;
	}
	if (!n) fdputs("\n", stdout);
	return 0;
}
示例#6
0
inline int fdprintf(int fd, const char *format, ...) {
	char *cp = nullptr;
	va_list ap;

	va_start(ap, format);
	int len = vasprintf(&cp, format, ap);
	va_end(ap);

	fdputs(cp, fd);
	free(cp);
	return len;
}
示例#7
0
int builtin_version(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {


	bool _v = false;
	bool error = false;

	auto argv = getopt(tokens, [&](char c){
		switch(tolower(c))
		{
			case 'v': _v = true; break;
			default:
				fdprintf(stderr, "### Version - \"-%c\" is not an option.\n", c);
				error = true;
				break;
		}
	});

	if (argv.size() != 0) {
		fdprintf(stderr, "### Version - Too many parameters were specified.\n");
		error = true;
	}

	if (error) {
		fdprintf(stderr, "# Usage - Version [-v]\n");
		return 1;
	}

	//fdputs("MPW Shell 3.5, Copyright Apple Computer, Inc. 1985-99. All rights reserved.\n", stdout);
	fdputs("MPW Shell " VERSION ", Copyright Kelvin W Sherlock 2016. All rights reserved.\n", stdout);
	fdputs("based on MPW Shell 3.5, Copyright Apple Computer, Inc. 1985-99. All rights reserved.\n", stdout);

	if (_v) {
		fdputs("This version built on " __DATE__ " at " __TIME__ ".\n", stdout);
	}

	return 0;
}
示例#8
0
int builtin_shift(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {

	int n = 1;

	if (tokens.size() > 3) {
		fdputs("### Shift - Too many parameters were specified.\n", stderr);
		fdputs("# Usage - Shift [number]\n", stderr);
		return 1;
	}

	if (tokens.size() == 2) {

		value v(tokens[1]);
		if (v.is_number() && v.number >= 0) n = v.number;
		else {
			fdputs("### Shift - The parameter must be a positive number.\n", stderr);
			fdputs("# Usage - Shift [number]\n", stderr);
			return 1;
		}
	}

	if (n == 0) return 0;

	auto argv = load_argv(env);
	if (argv.empty()) return 0;

	std::move(argv.begin() + n , argv.end(), argv.begin());
	do {
		env.unset(std::to_string(argv.size()));
		argv.pop_back();
	} while (--n);

	env.set_argv(argv);

	return 0;
}
示例#9
0
int builtin_aboutbox(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {
	// the most important command of all!

	if (tokens.size() == 2 && tokens[1] == "--moof") {

		fdputs(
		"\n"
		"              ##                                            \n"
		"            ##  ##  ####                                    \n"
		"            ##  ####  ##                                    \n"
		"          ##          ##                                    \n"
		"        ##    ##    ##                              ##      \n"
		"      ##            ##                              ####    \n"
		"    ##                ##                          ##  ##    \n"
		"      ########          ####                    ##    ##    \n"
		"              ##            ####################      ##    \n"
		"              ##            ##############          ##      \n"
		"                ####          ############        ##        \n"
		"                ######            ######          ##        \n"
		"                ######                          ##          \n"
		"                ####                            ##          \n"
		"                ##                              ##          \n"
		"                ##      ################        ##          \n"
		"                ##    ##                ##        ##        \n"
		"                ##    ##                  ##      ##        \n"
		"                ##    ##                    ##    ##        \n"
		"                ##    ##                    ##    ##        \n"
		"              ##    ##                    ##    ##          \n"
		"              ######                      ######            \n"
		"\n"
		,stdout);

		return 0;
	}


	fdprintf(stdout,
"+--------------------------------------+\n"
"| MPW Shell %-4s                       |\n"
"|                                      |\n"
"|                                      |\n"
"| (c) 2016 Kelvin W Sherlock           |\n"
"+--------------------------------------+\n"
	, VERSION);
	return 0;
}
示例#10
0
void cmd_index(int clientsock) {
	send_200_ok(clientsock);
	send_header_textplain(clientsock);
	fdputs(clientsock, "\nHi from mptsd.\n");
}
示例#11
0
文件: error.c 项目: ipeet/ubw32
//! Print the current error
void err_print(int fd, err_desc_t* err) {
    char pbuf[32];
    fdputs(fd,"Error Description:\n");

    /* Print internal error into */
    if( err->status ) {
        fdputs(fd,"Internal Error: ");
        sprintf(pbuf,"%d ",err->status);
        fdputs(fd,pbuf);
        sprintf(pbuf,"(%dx)\n",_err_counts[err->status]);
        fdputs(fd,pbuf);
        if(_err_msgs[err->status]) {
                   fdputs(fd,_err_msgs[err->status]);
            fdputs(fd,"\n");
        }
        if(err->details) {
            fdputs(fd,err->details);
            fdputs(fd,"\n");
        }
    }

    /* Print errno */
    if( err->errno ) {
        // If errno is recorded:
        fdputs(fd,"Errno: ");
        sprintf(pbuf,"%d\n",err->errno);
        fdputs(fd,pbuf);
        fdputs(fd,strerror(err->errno));
        fdputs(fd,"\n");
    }
}
示例#12
0
int builtin_evaluate(Environment &env, std::vector<token> &&tokens, const fdmask &fds) {
	// evaluate expression
	// evaluate variable = expression
	// evaluate variable += expression
	// evaluate variable -= expression

	// flags -- -h -o -b -- print in hex, octal, or binary

	// convert the arguments to a stack.


	int output = 'd';

	//io_helper io(fds);

	std::reverse(tokens.begin(), tokens.end());

	// remove 'Evaluate'
	tokens.pop_back();

	// check for -h -x -o
	if (tokens.size() >= 2 && tokens.back().type == '-') {

		const token &t = tokens[tokens.size() - 2];
		if (t.type == token::text && t.string.length() == 1) {
			int flag = tolower(t.string[0]);
			switch(flag) {
				case 'o':
				case 'h':
				case 'b':
					output = flag;
					tokens.pop_back();
					tokens.pop_back();
			}
		}

	}

	if (tokens.size() >= 2 && tokens.back().type == token::text)
	{
		int type = tokens[tokens.size() -2].type;

		if (is_assignment(type)) {

			std::string name = tokens.back().string;

			tokens.pop_back();
			tokens.pop_back();

			int32_t i = evaluate_expression("Evaluate", std::move(tokens));

			switch(type) {
				case '=':
					env.set(name, i);
					break;
				case '+=':
				case '-=':
					{
						value old;
						auto iter = env.find(name);
						if (iter != env.end()) old = (const std::string &)iter->second;

						switch(type) {
							case '+=':
								i = old.to_number() + i;
								break;
							case '-=':
								i = old.to_number() - i;
								break;
						}

						env.set(name, i);
					}
					break;
			}
			return 0;
		}
	}

	int32_t i = evaluate_expression("Evaluate", std::move(tokens));

	if (output == 'h') {
		fdprintf(stdout, "0x%08x\n", i);
		return 0;
	}

	if (output == 'b') {
		std::string tmp("0b");

		for (int j = 0; j < 32; ++j) {
			tmp.push_back(i & 0x80000000 ? '1' : '0');
			i <<= 1;
		}
		tmp.push_back('\n');
		fdputs(tmp.c_str(), stdout);
		return 0;
	}

	if (output == 'o') {
		// octal.
		fdprintf(stdout, "0%o\n", i);
		return 0;
	}

	fdprintf(stdout, "%d\n", i);
	return 0;
}
示例#13
0
int builtin_exists(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {

	bool _a = false; // print if alias/symlink
	bool _d = false; // print if directory
	bool _f = false; // print if normal file
	bool _n = false; // don't follow alias
	bool _w = false; // print if normal file + writable
	bool _q = false; // don't quote names
	bool error = false;

	std::vector<std::string> argv = getopt(tokens, [&](char c){
		switch(tolower(c))
		{
			case 'a': _a = true; break;
			case 'd': _d = true; break;
			case 'f': _f = true; break;
			case 'n': _n = true; break;
			case 'q': _q = true; break;
			case 'w': _w = true; break;
			default:
				fdprintf(stderr, "### Exists - \"-%c\" is not an option.\n", c);
				error = true;
				break;
		}
	});	

	if (_w) _f = false;

	if (_a + _d + _f + _w > 1) {
		fdputs("### Exists - Conflicting options were specified.\n", stderr);
		error = true;
	}

	if (argv.size() < 1) {
		fdputs("### Exists - Not enough parameters were specified.\n", stderr);
		error = true;
	}



	if (error) {
		fdputs("# Usage - Exists [-a | -d | -f | -w] [-n] [-q] name...\n", stderr);
		return 1;
	}

	for (auto &s : argv) {
		std::string path = ToolBox::MacToUnix(s);
		std::error_code ec;
		fs::file_status st = _n ? fs::symlink_status(path, ec) : fs::status(path, ec);
		if (ec) continue;

		if (_d && !fs::is_directory(st)) continue;
		if (_a && !fs::is_symlink(st)) continue;
		if (_f && !fs::is_regular_file(st)) continue;
		if (_w && !fs::is_regular_file(st)) continue;
		if (_w && (access(path.c_str(), W_OK | F_OK) < 0)) continue; 

		if (!_q) s = quote(std::move(s));
		fdprintf(stdout, "%s\n", s.c_str());

	}


	return 0;
}
示例#14
0
int builtin_directory(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {
	// directory [-q]
	// directory path

	// for relative names, uses {DirectoryPath} (if set) rather than .
	// set DirectoryPath ":,{MPW},{MPW}Projects:"

	/*
	 * Parameters:
	 * ----------
	 * directory
	 * Sets the default directory to directory. If you specify directory
	 * as a leafname (that is, the final portion of a full pathname), the
	 * MPW Shell searches for the directory in the current directory path
	 * (for example, searching "{MPW}Examples:" for CExamples). However, if
	 * the MPW Shell fails to find the directory in the current directory
	 * path, it searches the directories listed in the {DirectoryPath} MPW
	 * Shell variable, which contains a list of directories to be searched
	 * in order of precedence. The last example illustrates how to do this.
	 *
	 * Options:
	 * -------
	 * -q
	 * Inhibits quoting the directory pathname written to standard
	 * output. This option applies only if you omit the directory
	 * parameter Normally the MPW Shell quotes the current default
	 * directory name if it contains spaces or other special characters
	 *
	 * Status:
	 * ------
	 * Directory can return the following status codes:
	 *
	 * 0 no errors
	 * 1 directory not found; command aborted; or parameter error
	 *
	 */



	//io_helper io(fds);

	bool q = false;
	bool error = false;

	std::vector<std::string> argv = getopt(tokens, [&](char c){
		switch(tolower(c))
		{
			case 'q': q = true; break;
			default:
				fdprintf(stderr, "### Directory - \"-%c\" is not an option.\n", c);
				error = true;
				break;
		}
	});

	if (error) {
		fdputs("# Usage - Directory [-q | directory]\n", stderr);
		return 1;
	}

	if (argv.size() > 1) {
		fdputs("### Directory - Too many parameters were specified.\n", stderr);
		fdputs("# Usage - Directory [-q | directory]\n", stderr);
		return 1;	
	}


	if (argv.size() == 1) {
		//cd
		if (q) {
			fdputs("### Directory - Conflicting options or parameters were specified.\n", stderr);
			return 1;
		}

		// todo -- if relative path does not exist, check {DirectoryPath}
		fs::path path = ToolBox::MacToUnix(argv.front());
		std::error_code ec;
		current_path(path, ec);
		if (ec) {
			fdputs("### Directory - Unable to set current directory.\n", stderr);
			fdprintf(stderr, "# %s\n", ec.message().c_str());
			return 1;
		}
	}
	else {
		// pwd
		std::error_code ec;
		fs::path path = fs::current_path(ec);
		if (ec) {

			fdputs("### Directory - Unable to get current directory.\n", stderr);
			fdprintf(stderr, "# %s\n", ec.message().c_str());
			return 1;

		}
		// todo -- pathname translation?

		std::string s = path;
		if (!q) s = quote(std::move(s));
		fdprintf(stdout, "%s\n", s.c_str());
	}
	return 0;
}
示例#15
0
int builtin_help(Environment &env, const std::vector<std::string> &tokens, const fdmask &fds) {

	bool error = false;
	filesystem::path _f;

	// todo -- -f to specify help file.
	auto argv = getopt(tokens, [&](char c){
		switch(tolower(c))
		{

			default:
				fdprintf(stderr, "### Help - \"-%c\" is not an option.\n", c);
				error = true;
				break;
		}
	});

	if (error) {
		fdputs("# Usage - Help [-f helpfile] command...\n", stderr);
		return 1;
	}


	const filesystem::path sd(ToolBox::MacToUnix(env.get("shelldirectory")));
	const filesystem::path hd = sd / "Help";

	filesystem::path mono;
	mapped_file mono_file;
	std::error_code ec;

	if (_f.empty()) {
		mono = sd / "MPW.Help";
		mono_file = mapped_file(mono, mapped_file::priv, ec);
	} else {

		mono = _f;
		mono_file = mapped_file(mono, mapped_file::priv, ec);
		if (!mono_file && !_f.is_absolute()) {
			mono = sd / _f;
			mono_file = mapped_file(mono, mapped_file::priv, ec);
		}

		if (!mono_file) {
			fdprintf(stderr, "### Help: Unable to open %s\n", _f.c_str());
			fdprintf(stderr, "# %s\n", ec.message().c_str());
			return 3;
		}

	}

	if (mono_file) {
		std::replace(mono_file.begin(), mono_file.end(), '\r', '\n');
	}

	if (argv.empty()) {
		help_helper(mono_file, fds, "");
		return 0;
	}

	int rv = 0;
	for (const auto &cmd : argv) {


		// 1. check for $MPW:Help:command
		filesystem::path p(hd);
		p /= cmd;

		mapped_file f(p, mapped_file::priv, ec);
		if (!ec) {
			std::replace(f.begin(), f.end(), '\r', '\n');
			write(stdout, f.data(), f.size());
			fdputs("\n", stdout);
			continue;
		}


		if (mono_file) {
			bool ok = help_helper(mono_file, fds, cmd);
			if (ok) break;
		}

		fdprintf(stderr, "### Help - \"%s\" was not found.\n", cmd.c_str());
		rv = 2;
	}

	return rv;
}