+/*-
+ * Copyright (c) 1991 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Kenneth Almquist.
+ *
+ * %sccs.include.redist.c%
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)miscbltin.c 5.1 (Berkeley) %G%";
+#endif /* not lint */
+
+/*
+ * Miscelaneous builtins.
+ */
+
+#include "shell.h"
+#include "options.h"
+#include "var.h"
+#include "output.h"
+#include "memalloc.h"
+#include "error.h"
+#include "mystring.h"
+
+#undef eflag
+
+extern char **argptr; /* argument list for builtin command */
+
+
+/*
+ * The read builtin. The -e option causes backslashes to escape the
+ * following character.
+ *
+ * This uses unbuffered input, which may be avoidable in some cases.
+ */
+
+readcmd(argc, argv) char **argv; {
+ char **ap;
+ int backslash;
+ char c;
+ int eflag;
+ char *prompt;
+ char *ifs;
+ char *p;
+ int startword;
+ int status;
+ int i;
+
+ eflag = 0;
+ prompt = NULL;
+ while ((i = nextopt("ep:")) >= 0) {
+ if (i == 'p')
+ prompt = optarg;
+ else
+ eflag = 1;
+ }
+ if (prompt && isatty(0)) {
+ out2str(prompt);
+ flushall();
+ }
+ if ((ap = argptr) == NULL)
+ error("arg count");
+ if ((ifs = bltinlookup("IFS", 1)) == NULL)
+ ifs = nullstr;
+ status = 0;
+ startword = 1;
+ backslash = 0;
+ STARTSTACKSTR(p);
+ for (;;) {
+ if (read(0, &c, 1) != 1) {
+ status = 1;
+ break;
+ }
+ if (c == '\0')
+ continue;
+ if (backslash) {
+ backslash = 0;
+ if (c != '\n')
+ STPUTC(c, p);
+ continue;
+ }
+ if (eflag && c == '\\') {
+ backslash++;
+ continue;
+ }
+ if (c == '\n')
+ break;
+ if (startword && *ifs == ' ' && strchr(ifs, c)) {
+ continue;
+ }
+ startword = 0;
+ if (backslash && c == '\\') {
+ if (read(0, &c, 1) != 1) {
+ status = 1;
+ break;
+ }
+ STPUTC(c, p);
+ } else if (ap[1] != NULL && strchr(ifs, c) != NULL) {
+ STACKSTRNUL(p);
+ setvar(*ap, stackblock(), 0);
+ ap++;
+ startword = 1;
+ STARTSTACKSTR(p);
+ } else {
+ STPUTC(c, p);
+ }
+ }
+ STACKSTRNUL(p);
+ setvar(*ap, stackblock(), 0);
+ while (*++ap != NULL)
+ setvar(*ap, nullstr, 0);
+ return status;
+}
+
+
+
+umaskcmd(argc, argv) char **argv; {
+ int mask;
+ char *p;
+ int i;
+
+ if ((p = argv[1]) == NULL) {
+ INTOFF;
+ mask = umask(0);
+ umask(mask);
+ INTON;
+ out1fmt("%.4o\n", mask); /* %#o might be better */
+ } else {
+ mask = 0;
+ do {
+ if ((unsigned)(i = *p - '0') >= 8)
+ error("Illegal number: %s", argv[1]);
+ mask = (mask << 3) + i;
+ } while (*++p != '\0');
+ umask(mask);
+ }
+ return 0;
+}