Exemple #1
0
void
decode_ss(const char *arg)
{
	struct sockaddr_storage *ssp;
	size_t len = strlen(arg);
	
	if (len > sizeof(*ssp) * 4 + 1 || len < sizeof(*ssp))
		errx(EXIT_FAILURE, "Bad argument");

	if ((ssp = malloc(len)) == NULL)
		err(EXIT_FAILURE, NULL);

	if (strunvis((char *)ssp, arg) != sizeof(*ssp))
		errx(EXIT_FAILURE, "Decoding error");

	(void)memcpy(&ss, ssp, sizeof(ss));
	free(ssp);
	have_ss = 1;
}
Exemple #2
0
ATF_TC_BODY(strunvis_hex, tc)
{
	static const struct {
		const char *e;
		const char *d;
		int error;
	} ed[] = {
		{ "\\xff", "\xff", 1 },
		{ "\\x1", "\x1", 1 },
		{ "\\x1\\x02", "\x1\x2", 2 },
		{ "\\x1x", "\x1x", 2 },
		{ "\\xx", "", -1 },
	};
	char uv[10];

	for (size_t i = 0; i < __arraycount(ed); i++) {
		ATF_REQUIRE(strunvis(uv, ed[i].e) == ed[i].error);
		if (ed[i].error > 0)
			ATF_REQUIRE(memcmp(ed[i].d, uv, ed[i].error) == 0);
	}
}
Exemple #3
0
NODE *
spec(FILE *fp)
{
	NODE *centry, *last, *pathparent, *cur;
	char *p, *e, *next;
	NODE ginfo, *root;
	char *buf, *tname, *ntname;
	size_t tnamelen, plen;

	root = NULL;
	centry = last = NULL;
	tname = NULL;
	tnamelen = 0;
	memset(&ginfo, 0, sizeof(ginfo));
	for (mtree_lineno = 0;
	    (buf = fparseln(fp, NULL, &mtree_lineno, NULL,
		FPARSELN_UNESCCOMM));
	    free(buf)) {
		/* Skip leading whitespace. */
		for (p = buf; *p && isspace((unsigned char)*p); ++p)
			continue;

		/* If nothing but whitespace, continue. */
		if (!*p)
			continue;

#ifdef DEBUG
		fprintf(stderr, "line %lu: {%s}\n",
		    (u_long)mtree_lineno, p);
#endif
		/* Grab file name, "$", "set", or "unset". */
		next = buf;
		while ((p = strsep(&next, " \t")) != NULL && *p == '\0')
			continue;
		if (p == NULL)
			mtree_err("missing field");

		if (p[0] == '/') {
			if (strcmp(p + 1, "set") == 0)
				set(next, &ginfo);
			else if (strcmp(p + 1, "unset") == 0)
				unset(next, &ginfo);
			else
				mtree_err("invalid specification `%s'", p);
			continue;
		}

		if (strcmp(p, "..") == 0) {
			/* Don't go up, if haven't gone down. */
			if (root == NULL)
				goto noparent;
			if (last->type != F_DIR || last->flags & F_DONE) {
				if (last == root)
					goto noparent;
				last = last->parent;
			}
			last->flags |= F_DONE;
			continue;

noparent:		mtree_err("no parent node");
		}

		plen = strlen(p) + 1;
		if (plen > tnamelen) {
			if ((ntname = realloc(tname, plen)) == NULL)
				mtree_err("realloc: %s", strerror(errno));
			tname = ntname;
			tnamelen = plen;
		}
		if (strunvis(tname, p) == -1)
			mtree_err("strunvis failed on `%s'", p);
		p = tname;

		pathparent = NULL;
		if (strchr(p, '/') != NULL) {
			cur = root;
			for (; (e = strchr(p, '/')) != NULL; p = e+1) {
				if (p == e)
					continue;	/* handle // */
				*e = '\0';
				if (strcmp(p, ".") != 0) {
					while (cur &&
					    strcmp(cur->name, p) != 0) {
						cur = cur->next;
					}
				}
				if (cur == NULL || cur->type != F_DIR) {
					mtree_err("%s: %s", tname,
					"missing directory in specification");
				}
				*e = '/';
				pathparent = cur;
				cur = cur->child;
			}
			if (*p == '\0')
				mtree_err("%s: empty leaf element", tname);
		}

		if ((centry = calloc(1, sizeof(NODE) + strlen(p))) == NULL)
			mtree_err("%s", strerror(errno));
		*centry = ginfo;
		centry->lineno = mtree_lineno;
		strcpy(centry->name, p);
#define	MAGIC	"?*["
		if (strpbrk(p, MAGIC))
			centry->flags |= F_MAGIC;
		set(next, centry);

		if (root == NULL) {
				/*
				 * empty tree
				 */
			if (strcmp(centry->name, ".") != 0 ||
			    centry->type != F_DIR)
				mtree_err(
				    "root node must be the directory `.'");
			last = root = centry;
			root->parent = root;
		} else if (pathparent != NULL) {
				/*
				 * full path entry; add or replace
				 */
			centry->parent = pathparent;
			addchild(pathparent, centry);
			last = centry;
		} else if (strcmp(centry->name, ".") == 0) {
				/*
				 * duplicate "." entry; always replace
				 */
			replacenode(root, centry);
		} else if (last->type == F_DIR && !(last->flags & F_DONE)) {
				/*
				 * new relative child in current dir;
				 * add or replace
				 */
			centry->parent = last;
			addchild(last, centry);
			last = centry;
		} else {
				/*
				 * new relative child in parent dir
				 * (after encountering ".." entry);
				 * add or replace
				 */
			centry->parent = last->parent;
			addchild(last->parent, centry);
			last = centry;
		}
	}
	return (root);
}
Exemple #4
0
NODE *
spec(void)
{
	NODE *centry, *last;
	char *p;
	NODE ginfo, *root;
	int c_cur, c_next;
	char buf[2048];

	centry = last = root = NULL;
	bzero(&ginfo, sizeof(ginfo));
	c_cur = c_next = 0;
	for (lineno = 1; fgets(buf, sizeof(buf), stdin);
	    ++lineno, c_cur = c_next, c_next = 0) {
		/* Skip empty lines. */
		if (buf[0] == '\n')
			continue;

		/* Find end of line. */
		if ((p = strchr(buf, '\n')) == NULL)
			errx(1, "line %d too long", lineno);

		/* See if next line is continuation line. */
		if (p[-1] == '\\') {
			--p;
			c_next = 1;
		}

		/* Null-terminate the line. */
		*p = '\0';

		/* Skip leading whitespace. */
		for (p = buf; *p && isspace(*p); ++p);

		/* If nothing but whitespace or comment char, continue. */
		if (!*p || *p == '#')
			continue;

#ifdef DEBUG
		fprintf(stderr, "line %d: {%s}\n", lineno, p);
#endif
		if (c_cur) {
			set(p, centry);
			continue;
		}

		/* Grab file name, "$", "set", or "unset". */
		if ((p = strtok(p, "\n\t ")) == NULL)
			errx(1, "line %d: missing field", lineno);

		if (p[0] == '/')
			switch(p[1]) {
			case 's':
				if (strcmp(p + 1, "set"))
					break;
				set(NULL, &ginfo);
				continue;
			case 'u':
				if (strcmp(p + 1, "unset"))
					break;
				unset(NULL, &ginfo);
				continue;
			}

		if (strchr(p, '/'))
			errx(1, "line %d: slash character in file name",
			lineno);

		if (!strcmp(p, "..")) {
			/* Don't go up, if haven't gone down. */
			if (!root)
				goto noparent;
			if (last->type != F_DIR || last->flags & F_DONE) {
				if (last == root)
					goto noparent;
				last = last->parent;
			}
			last->flags |= F_DONE;
			continue;

noparent:		errx(1, "line %d: no parent node", lineno);
		}

		if ((centry = calloc(1, sizeof(NODE) + strlen(p))) == NULL)
			errx(1, "calloc");
		*centry = ginfo;
#define	MAGIC	"?*["
		if (strpbrk(p, MAGIC))
			centry->flags |= F_MAGIC;
		if (strunvis(centry->name, p) == -1) {
			warnx("filename %s is ill-encoded and literally used",
			    p);
			strcpy(centry->name, p);
		}
		set(NULL, centry);

		if (!root) {
			last = root = centry;
			root->parent = root;
		} else if (last->type == F_DIR && !(last->flags & F_DONE)) {
			centry->parent = last;
			last = last->child = centry;
		} else {
			centry->parent = last->parent;
			centry->prev = last;
			last = last->next = centry;
		}
	}
	return (root);
}
Exemple #5
0
static int
fstabscan(void)
{
	char *cp, *p;
#define	MAXLINELENGTH	1024
	static char line[MAXLINELENGTH];
	char subline[MAXLINELENGTH];
	int typexx;

	for (;;) {

		if (!(p = fgets(line, sizeof(line), _fs_fp)))
			return (0);
/* OLD_STYLE_FSTAB */
		++LineNo;
		if (*line == '#' || *line == '\n')
			continue;
		if (!strpbrk(p, " \t")) {
			_fs_fstab.fs_spec = strsep(&p, ":\n");
			_fs_fstab.fs_file = strsep(&p, ":\n");
			fixfsfile();
			_fs_fstab.fs_type = strsep(&p, ":\n");
			if (_fs_fstab.fs_type) {
				if (!strcmp(_fs_fstab.fs_type, FSTAB_XX))
					continue;
				_fs_fstab.fs_mntops = _fs_fstab.fs_type;
				_fs_fstab.fs_vfstype =
				    strcmp(_fs_fstab.fs_type, FSTAB_SW) ?
				    "ufs" : "swap";
				if ((cp = strsep(&p, ":\n")) != NULL) {
					_fs_fstab.fs_freq = atoi(cp);
					if ((cp = strsep(&p, ":\n")) != NULL) {
						_fs_fstab.fs_passno = atoi(cp);
						return (1);
					}
				}
			}
			goto bad;
		}
/* OLD_STYLE_FSTAB */
		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
			;
		_fs_fstab.fs_spec = cp;
		if (_fs_fstab.fs_spec == NULL || *_fs_fstab.fs_spec == '#')
			continue;
		if (strunvis(_fs_fstab.fs_spec, _fs_fstab.fs_spec) < 0)
			goto bad;
		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
			;
		_fs_fstab.fs_file = cp;
		if (_fs_fstab.fs_file == NULL)
			goto bad;
		if (strunvis(_fs_fstab.fs_file, _fs_fstab.fs_file) < 0)
			goto bad;
		fixfsfile();
		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
			;
		_fs_fstab.fs_vfstype = cp;
		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
			;
		_fs_fstab.fs_mntops = cp;
		if (_fs_fstab.fs_mntops == NULL)
			goto bad;
		_fs_fstab.fs_freq = 0;
		_fs_fstab.fs_passno = 0;
		while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
			;
		if (cp != NULL) {
			_fs_fstab.fs_freq = atoi(cp);
			while ((cp = strsep(&p, " \t\n")) != NULL && *cp == '\0')
				;
			if (cp != NULL)
				_fs_fstab.fs_passno = atoi(cp);
		}
		(void)strlcpy(subline, _fs_fstab.fs_mntops, sizeof(subline));
		p = subline;
		for (typexx = 0, cp = strsep(&p, ","); cp;
		     cp = strsep(&p, ",")) {
			if (strlen(cp) != 2)
				continue;
			if (!strcmp(cp, FSTAB_RW)) {
				_fs_fstab.fs_type = FSTAB_RW;
				break;
			}
			if (!strcmp(cp, FSTAB_RQ)) {
				_fs_fstab.fs_type = FSTAB_RQ;
				break;
			}
			if (!strcmp(cp, FSTAB_RO)) {
				_fs_fstab.fs_type = FSTAB_RO;
				break;
			}
			if (!strcmp(cp, FSTAB_SW)) {
				_fs_fstab.fs_type = FSTAB_SW;
				break;
			}
			if (!strcmp(cp, FSTAB_XX)) {
				_fs_fstab.fs_type = FSTAB_XX;
				typexx++;
				break;
			}
		}
		if (typexx)
			continue;
		if (cp != NULL)
			return (1);

bad:		/* no way to distinguish between EOF and syntax error */
		error(EFTYPE);
	}
	/* NOTREACHED */
}
Exemple #6
0
NODE *
spec(void)
{
	NODE *centry, *last;
	char *p;
	NODE ginfo, *root;
	int c_cur, c_next;
	char *buf, *tbuf = NULL;
	size_t len;

	last = root = NULL;
	bzero(&ginfo, sizeof(ginfo));
	centry = &ginfo;
	c_cur = c_next = 0;
	for (lineno = 1; (buf = fgetln(stdin, &len));
	    ++lineno, c_cur = c_next, c_next = 0) {
		/* Null-terminate the line. */
		if (buf[len - 1] == '\n') {
			buf[--len] = '\0';
		} else {
			/* EOF with no newline. */
			tbuf = malloc(len + 1);
			memcpy(tbuf, buf, len);
			tbuf[len] = '\0';
			buf = tbuf;
		}

		/* Skip leading whitespace. */
		for (p = buf; isspace((unsigned char)*p); p++)
			;

		/* If nothing but whitespace or comment char, continue. */
		if (*p == '\0' || *p == '#')
			continue;

		/* See if next line is continuation line. */
		if (buf[len - 1] == '\\') {
			c_next = 1;
			if (--len == 0)
				continue;
			buf[len] = '\0';
		}

#ifdef DEBUG
		(void)fprintf(stderr, "line %d: {%s}\n", lineno, p);
#endif
		if (c_cur) {
			set(p, centry);
			continue;
		}
			
		/* Grab file name, "$", "set", or "unset". */
		if ((p = strtok(p, "\n\t ")) == NULL)
			error("missing field");

		if (p[0] == '/')
			switch(p[1]) {
			case 's':
				if (strcmp(p + 1, "set"))
					break;
				set(NULL, &ginfo);
				continue;
			case 'u':
				if (strcmp(p + 1, "unset"))
					break;
				unset(NULL, &ginfo);
				continue;
			}

		if (strchr(p, '/'))
			error("slash character in file name");

		if (!strcmp(p, "..")) {
			/* Don't go up, if haven't gone down. */
			if (!root)
				goto noparent;
			if (last->type != F_DIR || last->flags & F_DONE) {
				if (last == root)
					goto noparent;
				last = last->parent;
			}
			last->flags |= F_DONE;
			continue;

noparent:		error("no parent node");
		}

		len = strlen(p) + 1;	/* NUL in struct _node */
		if ((centry = calloc(1, sizeof(NODE) + len - 1)) == NULL)
			error("%s", strerror(errno));
		*centry = ginfo;
#define	MAGIC	"?*["
		if (strpbrk(p, MAGIC))
			centry->flags |= F_MAGIC;
		if (strunvis(centry->name, p) == -1) {
			fprintf(stderr,
			    "mtree: filename (%s) encoded incorrectly\n", p);
			strlcpy(centry->name, p, len);
		}
		set(NULL, centry);

		if (!root) {
			last = root = centry;
			root->parent = root;
		} else if (last->type == F_DIR && !(last->flags & F_DONE)) {
			centry->parent = last;
			last = last->child = centry;
		} else {
			centry->parent = last->parent;
			centry->prev = last;
			last = last->next = centry;
		}
	}
	free(tbuf);
	return (root);
}
Exemple #7
0
static void
set(char *t, NODE *ip)
{
	int type;
	char *kw, *val = NULL;
	struct group *gr;
	struct passwd *pw;
	void *m;
	int value;
	u_int32_t fset, fclr;
	char *ep;
	size_t len;

	for (; (kw = strtok(t, "= \t\n")); t = NULL) {
		ip->flags |= type = parsekey(kw, &value);
		if (value && (val = strtok(NULL, " \t\n")) == NULL)
			error("missing value");
		switch(type) {
		case F_CKSUM:
			ip->cksum = strtoul(val, &ep, 10);
			if (*ep)
				error("invalid checksum %s", val);
			break;
		case F_MD5:
			ip->md5digest = strdup(val);
			if (!ip->md5digest)
				error("%s", strerror(errno));
			break;
		case F_FLAGS:
			if (!strcmp(val, "none")) {
				ip->file_flags = 0;
				break;
			}
			if (strtofflags(&val, &fset, &fclr))
				error("%s", strerror(errno));
			ip->file_flags = fset;
			break; 
		case F_GID:
			ip->st_gid = strtoul(val, &ep, 10);
			if (*ep)
				error("invalid gid %s", val);
			break;
		case F_GNAME:
			if ((gr = getgrnam(val)) == NULL)
			    error("unknown group %s", val);
			ip->st_gid = gr->gr_gid;
			break;
		case F_IGN:
			/* just set flag bit */
			break;
		case F_MODE:
			if ((m = setmode(val)) == NULL)
				error("invalid file mode %s", val);
			ip->st_mode = getmode(m, 0);
			free(m);
			break;
		case F_NLINK:
			ip->st_nlink = strtoul(val, &ep, 10);
			if (*ep)
				error("invalid link count %s", val);
			break;
		case F_RMD160:
			ip->rmd160digest = strdup(val);
			if (!ip->rmd160digest)
				error("%s", strerror(errno));
			break;
		case F_SHA1:
			ip->sha1digest = strdup(val);
			if (!ip->sha1digest)
				error("%s", strerror(errno));
			break;
		case F_SIZE:
			ip->st_size = strtouq(val, &ep, 10);
			if (*ep)
				error("invalid size %s", val);
			break;
		case F_SLINK:
			len = strlen(val) + 1;
			if ((ip->slink = malloc(len)) == NULL)
				error("%s", strerror(errno));
			if (strunvis(ip->slink, val) == -1) {
				fprintf(stderr,
				    "mtree: filename (%s) encoded incorrectly\n", val);
				strlcpy(ip->slink, val, len);
			}
			break;
		case F_TIME:
			ip->st_mtimespec.tv_sec = strtoul(val, &ep, 10);
			if (*ep != '.')
				error("invalid time %s", val);
			val = ep + 1;
			ip->st_mtimespec.tv_nsec = strtoul(val, &ep, 10);
			if (*ep)
				error("invalid time %s", val);
			break;
		case F_TYPE:
			switch(*val) {
			case 'b':
				if (!strcmp(val, "block"))
					ip->type = F_BLOCK;
				break;
			case 'c':
				if (!strcmp(val, "char"))
					ip->type = F_CHAR;
				break;
			case 'd':
				if (!strcmp(val, "dir"))
					ip->type = F_DIR;
				break;
			case 'f':
				if (!strcmp(val, "file"))
					ip->type = F_FILE;
				if (!strcmp(val, "fifo"))
					ip->type = F_FIFO;
				break;
			case 'l':
				if (!strcmp(val, "link"))
					ip->type = F_LINK;
				break;
			case 's':
				if (!strcmp(val, "socket"))
					ip->type = F_SOCK;
				break;
			default:
				error("unknown file type %s", val);
			}
			break;
		case F_UID:
			ip->st_uid = strtoul(val, &ep, 10);
			if (*ep)
				error("invalid uid %s", val);
			break;
		case F_UNAME:
			if ((pw = getpwnam(val)) == NULL)
			    error("unknown user %s", val);
			ip->st_uid = pw->pw_uid;
			break;
		}
	}
}
Exemple #8
0
const char *
getfsspecname(char *buf, size_t bufsiz, const char *name)
{
	static const int mib[] = { CTL_HW, HW_DISKNAMES };
	static const unsigned int miblen = __arraycount(mib);
	char *drives, *dk;
	size_t len;
	int fd, savee;
	char *vname;

	drives = NULL;
	vname = NULL;
	if (strncasecmp(name, "NAME=", 5) != 0) {
#ifdef COMPAT_DKWEDGE
		/*
		 * We try to open the disk name, and if we fail with EBUSY
		 * we use the name as the label to find the wedge.
		 */
		char rbuf[MAXPATHLEN];
		if (name[0] == '/') {
			if (getdiskrawname(rbuf, sizeof(rbuf), name) != NULL) {
				if ((fd = open(rbuf, O_RDONLY)) == -1) {
					if (errno == EBUSY) {
						name = strrchr(name, '/') + 1;
						goto search;
					}
				} else
					close(fd);
			}
		}
#endif
		strlcpy(buf, name, bufsiz);
		return buf;
	} else
		name += 5;

#ifdef COMPAT_DKWEDGE
search:
#endif
	vname = malloc(strlen(name) * 4 + 1);
	if (vname == NULL) {
		savee = errno;
		strlcpy(buf, "malloc failed", bufsiz);
		goto out;
	}

	strunvis(vname, name);

	if (sysctl(mib, miblen, NULL, &len, NULL, 0) == -1) {
		savee = errno;
		strlcpy(buf, "sysctl hw.disknames failed", bufsiz);
		goto out;
	}

	drives = malloc(len);
	if (drives == NULL) {
		savee = errno;
		strlcpy(buf, "malloc failed", bufsiz);
		goto out;
	}
	if (sysctl(mib, miblen, drives, &len, NULL, 0) == -1) {
		savee = errno;
		strlcpy(buf, "sysctl hw.disknames failed", bufsiz);
		goto out;
	}

	for (dk = strtok(drives, " "); dk != NULL; dk = strtok(NULL, " ")) {
		struct dkwedge_info dkw;
		if (strncmp(dk, "dk", 2) != 0)
			continue;
		fd = opendisk(dk, O_RDONLY, buf, bufsiz, 0);
		if (fd == -1)
			continue;
		if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == -1) {
			savee = errno;
			snprintf(buf, bufsiz, "%s: getwedgeinfo", dk);
			(void)close(fd);
			goto out;
		}
		(void)close(fd);
		if (strcmp(vname, (char *)dkw.dkw_wname) == 0) {
			char *p = strstr(buf, "/rdk");
			if (p++ == NULL) 
				return buf;
			strcpy(p, p + 1);
			free(drives);
			free(vname);
			return buf;
		}
	}
	savee = ESRCH;
	snprintf(buf, bufsiz, "no match for `%s'", vname);
out:
	free(drives);
	free(vname);
	errno = savee;
	return NULL;
}