Esempio n. 1
0
int
main(int argc, char **argv, char **envp)
{
	FILE *config;
	char *line, *cp, *from, *to, *ap;
	const char *progname;
	size_t len, lineno = 0;
	int i;
	struct arglist al;

	/* change progname to mailwrapper so we get sensible error messages */
	progname = getprogname();
	setprogname("mailwrapper");

	if ((config = fopen(_PATH_MAILERCONF, "r")) == NULL) {
		openlog("mailwrapper", LOG_PID, LOG_MAIL);
		syslog(LOG_INFO, "can't open %s, using %s as default MTA",
		    _PATH_MAILERCONF, _PATH_DEFAULTMTA);
		closelog();
		execve(_PATH_DEFAULTMTA, argv, envp);
		err(1, "cannot exec %s", _PATH_DEFAULTMTA);
		/*NOTREACHED*/
	}

	initarg(&al);
	addarg(&al, argv[0], 0);

	for (;;) {
		if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) {
			if (feof(config))
				errx(1, "no mapping in %s", _PATH_MAILERCONF);
			err(1, NULL);
		}

#define	WS	" \t\n"
		cp = line;

		cp += strspn(cp, WS);
		if (cp[0] == '\0') {
			/* empty line */
			free(line);
			continue;
		}

		if ((from = strsep(&cp, WS)) == NULL)
			goto parse_error;

		cp += strspn(cp, WS);

		if ((to = strsep(&cp, WS)) == NULL)
			goto parse_error;

		if (strcmp(from, progname) == 0) {
			for (ap = strsep(&cp, WS); ap != NULL;
			    ap = strsep(&cp, WS))
			    if (*ap)
				    addarg(&al, ap, 0);
			break;
		}

		free(line);
	}

	fclose(config);

	for (i = 1; i < argc; i++)
		addarg(&al, argv[i], 0);
	addarg(&al, NULL, 0);

	execve(to, al.argv, envp);
	err(1, "cannot exec %s", to);
	/*NOTREACHED*/
parse_error:
	errx(1, "parse error in %s at line %lu",
	    _PATH_MAILERCONF, (u_long)lineno);
	/*NOTREACHED*/
}
Esempio n. 2
0
int
main(int argc, char *argv[])
{
	int c, tout, flags, flush, restore;
	const char *spath, **blsock;
	size_t nblsock, maxblsock;

	setprogname(argv[0]);

	spath = NULL;
	blsock = NULL;
	maxblsock = nblsock = 0;
	flush = 0;
	restore = 0;
	tout = 0;
	flags = O_RDWR|O_EXCL|O_CLOEXEC;
	while ((c = getopt(argc, argv, "C:c:D:dfP:rR:s:t:v")) != -1) {
		switch (c) {
		case 'C':
			controlprog = optarg;
			break;
		case 'c':
			configfile = optarg;
			break;
		case 'D':
			dbfile = optarg;
			break;
		case 'd':
			debug++;
			break;
		case 'f':
			flush++;
			break;
		case 'P':
			spath = optarg;
			break;
		case 'R':
			rulename = optarg;
			break;
		case 'r':
			restore++;
			break;
		case 's':
			if (nblsock >= maxblsock) {
				maxblsock += 10;
				void *p = realloc(blsock,
				    sizeof(*blsock) * maxblsock);
				if (p == NULL)
				    err(EXIT_FAILURE,
					"Can't allocate memory for %zu sockets",
					maxblsock);
				blsock = p;
			}
			blsock[nblsock++] = optarg;
			break;
		case 't':
			tout = atoi(optarg) * 1000;
			break;
		case 'v':
			vflag++;
			break;
		default:
			usage(c);
		}
	}

	argc -= optind;
	if (argc)
		usage(0);

	signal(SIGHUP, sighup);
	signal(SIGINT, sigdone);
	signal(SIGQUIT, sigdone);
	signal(SIGTERM, sigdone);
	signal(SIGUSR1, sigusr1);
	signal(SIGUSR2, sigusr2);

	openlog(getprogname(), LOG_PID, LOG_DAEMON);

	if (debug) {
		lfun = dlog;
		if (tout == 0)
			tout = 5000;
	} else {
		if (tout == 0)
			tout = 15000;
	}

	update_interfaces();
	conf_parse(configfile);
	if (flush) {
		rules_flush();
		flags |= O_TRUNC;
	}

	struct pollfd *pfd = NULL;
	bl_t *bl = NULL;
	size_t nfd = 0;
	size_t maxfd = 0;

	for (size_t i = 0; i < nblsock; i++)
		addfd(&pfd, &bl, &nfd, &maxfd, blsock[i]);
	free(blsock);

	if (spath) {
		FILE *fp = fopen(spath, "r");
		char *line;
		if (fp == NULL)
			err(EXIT_FAILURE, "Can't open `%s'", spath);
		for (; (line = fparseln(fp, NULL, NULL, NULL, 0)) != NULL;
		    free(line))
			addfd(&pfd, &bl, &nfd, &maxfd, line);
		fclose(fp);
	}
	if (nfd == 0)
		addfd(&pfd, &bl, &nfd, &maxfd, _PATH_BLSOCK);

	state = state_open(dbfile, flags, 0600);
	if (state == NULL)
		state = state_open(dbfile,  flags | O_CREAT, 0600);
	if (state == NULL)
		return EXIT_FAILURE;

	if (restore)
		rules_restore();

	if (!debug) {
		if (daemon(0, 0) == -1)
			err(EXIT_FAILURE, "daemon failed");
		if (pidfile(NULL) == -1)
			err(EXIT_FAILURE, "Can't create pidfile");
	}

	for (size_t t = 0; !done; t++) {
		if (readconf) {
			readconf = 0;
			conf_parse(configfile);
		}
		switch (poll(pfd, (nfds_t)nfd, tout)) {
		case -1:
			if (errno == EINTR)
				continue;
			(*lfun)(LOG_ERR, "poll (%m)");
			return EXIT_FAILURE;
		case 0:
			state_sync(state);
			break;
		default:
			for (size_t i = 0; i < nfd; i++)
				if (pfd[i].revents & POLLIN)
					process(bl[i]);
		}
		if (t % 100 == 0)
			state_sync(state);
		if (t % 10000 == 0)
			update_interfaces();
		update();
	}
	state_close(state);
	return 0;
}
Esempio n. 3
0
struct tm *
getdate(const char *str)
{
	char *datemsk, *line, *rp;
	FILE *fp;
	struct stat sb;
	static struct tm rtm, tmnow;
	struct tm *tmp, *rtmp = &rtm;
	size_t lineno = 0;
	time_t now;

	if (((datemsk = getenv("DATEMSK")) == NULL) || *datemsk == '\0') {
		getdate_err = 1;
		return (NULL);
	}

	if (stat(datemsk, &sb) < 0) {
		getdate_err = 3;
		return (NULL);
	}

	if ((sb.st_mode & S_IFMT) != S_IFREG) {
		getdate_err = 4;
		return (NULL);
	}

	if ((fp = fopen(datemsk, "r")) == NULL) {
		getdate_err = 2;
		return (NULL);
	}

	/* loop through datemsk file */
	errno = 0;
	rp = NULL;
	while ((line = fparseln(fp, NULL, &lineno, NULL, 0)) != NULL) {
		/* initialize tmp with sentinels */
		rtm.tm_sec = rtm.tm_min = rtm.tm_hour = TMSENTINEL;
		rtm.tm_mday = rtm.tm_mon = rtm.tm_year = TMSENTINEL;
		rtm.tm_wday = rtm.tm_yday = rtm.tm_isdst = TMSENTINEL;
		rtm.tm_gmtoff = 0;
		rtm.tm_zone = NULL;
		rp = strptime(str, line, rtmp);
		free(line);
		if (rp != NULL) 
			break;
		errno = 0;
	}
	if (errno != 0 || ferror(fp)) {
		if (errno == ENOMEM)
			getdate_err = 6;
		else
			getdate_err = 5;
		fclose(fp);
		return (NULL);
	}
	if (feof(fp) || (rp != NULL && *rp != '\0')) {
		getdate_err = 7;
		return (NULL);
	}
	fclose(fp);

	time(&now);
	tmp = localtime(&now);
	tmnow = *tmp;

	/*
	 * This implementation does not accept setting the broken-down time
	 * to anything other than the localtime().  It is not possible to
	 * change the scanned timezone with %Z.
	 *
	 * Note IRIX and Solaris accept only the current zone for %Z.
	 * XXX Is there any implementation that matches the standard?
	 * XXX (Or am I reading the standard wrong?)
	 *
	 * Note: Neither XPG 6 (POSIX 2004) nor XPG 7 (POSIX 2008)
	 * requires strptime(3) support for %Z.
	 */

	/*
	 * Given only a weekday find the first matching weekday starting
	 * with the current weekday and moving into the future.
	 */
	if (rtm.tm_wday != TMSENTINEL && rtm.tm_year == TMSENTINEL &&
	    rtm.tm_mon == TMSENTINEL && rtm.tm_mday == TMSENTINEL) {
		rtm.tm_year = tmnow.tm_year;
		rtm.tm_mon = tmnow.tm_mon;
		rtm.tm_mday = tmnow.tm_mday +
			(rtm.tm_wday - tmnow.tm_wday + 7) % 7;
	}

	/*
	 * Given only a month (and no year) find the first matching month
	 * starting with the current month and moving into the future.
	 */
	if (rtm.tm_mon != TMSENTINEL) {
		if (rtm.tm_year == TMSENTINEL) {
			rtm.tm_year = tmnow.tm_year +
				((rtm.tm_mon < tmnow.tm_mon)? 1 : 0);
		}
		if (rtm.tm_mday == TMSENTINEL) {
			/* assume the first of the month */
			rtm.tm_mday = 1;
			/*
			 * XXX This isn't documented! Just observed behavior.
			 *
			 * Given the weekday find the first matching weekday
			 * starting with the weekday of the first day of the
			 * the month and moving into the future.
			 */
			if (rtm.tm_wday != TMSENTINEL) {
				struct tm tm;

				memset(&tm, 0, sizeof(struct tm));
				tm.tm_year = rtm.tm_year;
				tm.tm_mon = rtm.tm_mon;
				tm.tm_mday = 1;
				mktime(&tm);
				rtm.tm_mday +=
					(rtm.tm_wday - tm.tm_wday + 7) % 7;
			}
		}
	}

	/*
	 * Given no time of day assume the current time of day.
	 */
	if (rtm.tm_hour == TMSENTINEL &&
	    rtm.tm_min == TMSENTINEL && rtm.tm_sec == TMSENTINEL) {
		rtm.tm_hour = tmnow.tm_hour;
		rtm.tm_min = tmnow.tm_min;
		rtm.tm_sec = tmnow.tm_sec;
	}
	/*
	 * Given an hour and no date, find the first matching hour starting
	 * with the current hour and moving into the future
	 */
	if (rtm.tm_hour != TMSENTINEL &&
	    rtm.tm_year == TMSENTINEL && rtm.tm_mon == TMSENTINEL &&
	    rtm.tm_mday == TMSENTINEL) {
		rtm.tm_year = tmnow.tm_year;
		rtm.tm_mon = tmnow.tm_mon;
		rtm.tm_mday = tmnow.tm_mday;
		if (rtm.tm_hour < tmnow.tm_hour)
			rtm.tm_hour += 24;
	}

	/*
	 * Set to 'sane' values; mktime(3) does funny things otherwise.
	 * No hours, no minutes, no seconds, no service.
	 */
	if (rtm.tm_hour == TMSENTINEL)
		rtm.tm_hour = 0;
	if (rtm.tm_min == TMSENTINEL)
		rtm.tm_min = 0;
	if (rtm.tm_sec == TMSENTINEL)
		rtm.tm_sec = 0;

	/*
	 * Given only a year the values of month, day of month, day of year,
	 * week day and is daylight (summer) time are unspecified.
	 * (Specified on the Solaris man page not POSIX.)
	 */
	if (rtm.tm_year != TMSENTINEL &&
	    rtm.tm_mon == TMSENTINEL && rtm.tm_mday == TMSENTINEL) {
		rtm.tm_mon = 0;
		rtm.tm_mday = 1;
		/*
		 * XXX More undocumented functionality but observed.
		 *
		 * Given the weekday find the first matching weekday
		 * starting with the weekday of the first day of the the
		 * month and moving into the future.
		 */
		if (rtm.tm_wday != TMSENTINEL) {
			struct tm tm;

			memset(&tm, 0, sizeof(struct tm));
			tm.tm_year = rtm.tm_year;
			tm.tm_mon = rtm.tm_mon;
			tm.tm_mday = 1;
			mktime(&tm);
			rtm.tm_mday += (rtm.tm_wday - tm.tm_wday + 7) % 7;
		}
	}

	/*
	 * Given only the century but no year within, the current year
	 * is assumed.  (Specified on the Solaris man page not POSIX.)
	 *
	 * Warning ugly end case
	 *
	 * This is more work since strptime(3) doesn't "do the right thing".
	 */
	if (rtm.tm_year != TMSENTINEL && (rtm.tm_year - 1900) >= 0) {
		rtm.tm_year -= 1900;
		rtm.tm_year += (tmnow.tm_year % 100);
	}

	/*
	 * mktime() will normalize all values and also check that the
	 * value will fit into a time_t.
	 *
	 * This is only for POSIX correctness.	A date >= 1900 is
	 * really ok, but using a time_t limits things.
	 */
	if (mktime(rtmp) < 0) {
		getdate_err = 8;
		return (NULL);
	}

	return (rtmp);
}
Esempio n. 4
0
struct ttyent *
getttyent(void)
{
	static struct ttyent tty;
	int c;
	char *p;
	size_t len;
	static char *line = NULL;
	char zapchar;

	if (line)
		free(line);

	if (!tf && !setttyent())
		return NULL;

	for (;;) {
		errno = 0;
		line = fparseln(tf, &len, &lineno, NULL, FPARSELN_UNESCALL);
		if (line == NULL) {
			if (errno != 0)
				warn("%s", __func__);
			return NULL;
		}
		for (p = line; *p && isspace((unsigned char)*p); p++)
			continue;
		if (*p && *p != '#')
			break;
		free(line);
	}

	tty.ty_name = p;
	p = skip(p, &zapchar);
	if (*(tty.ty_getty = p) == '\0')
		tty.ty_getty = tty.ty_type = NULL;
	else {
		p = skip(p, &zapchar);
		if (*(tty.ty_type = p) == '\0')
			tty.ty_type = NULL;
		else
			p = skip(p, &zapchar);
	}
	tty.ty_status = 0;
	tty.ty_window = NULL;
	tty.ty_class = NULL;

#define	scmp(e)	!strncmp(p, e, sizeof(e) - 1) && (isspace((unsigned char) p[sizeof(e) - 1]) || p[sizeof(e) - 1] == '\0')
#define	vcmp(e)	!strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '='
	for (; *p; p = skip(p, &zapchar)) {
		if (scmp(_TTYS_OFF))
			tty.ty_status &= ~TTY_ON;
		else if (scmp(_TTYS_ON))
			tty.ty_status |= TTY_ON;
		else if (scmp(_TTYS_SECURE))
			tty.ty_status |= TTY_SECURE;
		else if (scmp(_TTYS_LOCAL))
			tty.ty_status |= TTY_LOCAL;
		else if (scmp(_TTYS_RTSCTS))
			tty.ty_status |= TTY_RTSCTS;
		else if (scmp(_TTYS_DTRCTS))
			tty.ty_status |= TTY_DTRCTS;
		else if (scmp(_TTYS_SOFTCAR))
			tty.ty_status |= TTY_SOFTCAR;
		else if (scmp(_TTYS_MDMBUF))
			tty.ty_status |= TTY_MDMBUF;
		else if (vcmp(_TTYS_WINDOW))
			tty.ty_window = value(p);
		else if (vcmp(_TTYS_CLASS))
			tty.ty_class = value(p);
		else
			warnx("%s: %s, %lu: unknown option `%s'",
			    __func__, _PATH_TTYS, (unsigned long)lineno, p);
	}

	if (zapchar == '#' || *p == '#')
		while ((c = *++p) == ' ' || c == '\t')
			continue;
	tty.ty_comment = p;
	if (*p == '\0')
		tty.ty_comment = NULL;
	if ((p = strchr(p, '\n')) != NULL)
		*p = '\0';
	return &tty;
}
Esempio n. 5
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);
}
Esempio n. 6
0
struct protoent *
getprotoent_r(struct protoent *pr, struct protoent_data *pd)
{
	char *p, *cp, **q;
	size_t i = 0;
	int oerrno;

	if (pd->fp == NULL && (pd->fp = fopen(_PATH_PROTOCOLS, "r")) == NULL)
		return NULL;

	for (;;) {
		if (pd->line)
			free(pd->line);
		pd->line = fparseln(pd->fp, NULL, NULL, NULL,
		    FPARSELN_UNESCALL);
		if (pd->line == NULL)
			return NULL;
		pr->p_name = p = pd->line;
		cp = strpbrk(p, " \t");
		if (cp == NULL)
			continue;
		*cp++ = '\0';
		while (*cp == ' ' || *cp == '\t')
			cp++;
		p = strpbrk(cp, " \t");
		if (p != NULL)
			*p++ = '\0';
		pr->p_proto = atoi(cp);
		if (pd->aliases == NULL) {
			pd->maxaliases = 10;
			pd->aliases = malloc(pd->maxaliases * sizeof(char *));
			if (pd->aliases == NULL) {
				oerrno = errno;
				endprotoent_r(pd);
				errno = oerrno;
				return NULL;
			}
		}
		q = pr->p_aliases = pd->aliases;
		if (p != NULL) {
			cp = p;
			while (cp && *cp) {
				if (*cp == ' ' || *cp == '\t') {
					cp++;
					continue;
				}
				if (i == pd->maxaliases - 2) {
					pd->maxaliases *= 2;
					q = realloc(q,
					    pd->maxaliases * sizeof(char *));
					if (q == NULL) {
						oerrno = errno;
						endprotoent_r(pd);
						errno = oerrno;
						return NULL;
					}
					pr->p_aliases = pd->aliases = q;
				}
				q[i++] = cp;

				cp = strpbrk(cp, " \t");
				if (cp != NULL)
					*cp++ = '\0';
			}
		}
		q[i] = NULL;
		return pr;
	}
}
/* read_config_file --
 *	Parse the /etc/hesiod.conf file.  Returns 0 on success,
 *	-1 on failure.  On failure, it might leave values in ctx->lhs
 *	or ctx->rhs which need to be freed by the caller.
 */
static int 
read_config_file(struct hesiod_p *ctx, const char *filename)
{
	char	*buf, *key, *data, *p, **which;
	int	 n;
	FILE	*fp;

	_DIAGASSERT(ctx != NULL);
	_DIAGASSERT(filename != NULL);

	/* Set default query classes. */
	ctx->classes[0] = C_IN;
	ctx->classes[1] = C_HS;

	/* Try to open the configuration file. */
	fp = fopen(filename, "re");
	if (!fp) {
		/* Use compiled in default domain names. */
		ctx->lhs = strdup(DEF_LHS);
		ctx->rhs = strdup(DEF_RHS);
		if (ctx->lhs && ctx->rhs)
			return 0;
		else {
			errno = ENOMEM;
			return -1;
		}
	}
	ctx->lhs = NULL;
	ctx->rhs = NULL;
	for (; (buf = fparseln(fp, NULL, NULL, NULL, FPARSELN_UNESCALL))
	    != NULL; free(buf)) {
		p = buf;
		while (*p == ' ' || *p == '\t')
			p++;
		key = p;
		while (*p != ' ' && *p != '\t' && *p != '=' && *p)
			p++;

		if (*p == '\0')
			continue;

		*p++ = 0;

		while (isspace((u_char) *p) || *p == '=')
			p++;

		if (*p == '\0')
			continue;

		data = p;
		while (!isspace((u_char) *p) && *p)
			p++;

		*p = 0;

		if (strcasecmp(key, "lhs") == 0 ||
		    strcasecmp(key, "rhs") == 0) {
			which = (strcasecmp(key, "lhs") == 0)
			    ? &ctx->lhs : &ctx->rhs;
			*which = strdup(data);
			if (!*which) {
				errno = ENOMEM;
				free(buf);
				(void)fclose(fp);
				return -1;
			}
		} else {
			if (strcasecmp(key, "classes") == 0) {
				n = 0;
				while (*data && n < 2) {
					p = data;
					while (*p && *p != ',')
						p++;
					if (*p)
						*p++ = 0;
					if (strcasecmp(data, "IN") == 0)
						ctx->classes[n++] = C_IN;
					else
						if (strcasecmp(data, "HS") == 0)
							ctx->classes[n++] =
							    C_HS;
					data = p;
				}
				while (n < 2)
					ctx->classes[n++] = 0;
			}
		}
	}
	fclose(fp);

	if (!ctx->rhs || ctx->classes[0] == 0 ||
	    ctx->classes[0] == ctx->classes[1]) {
		errno = ENOEXEC;
		return -1;
	}
	return 0;
}
Esempio n. 8
0
int
main(int argc, char *argv[])
{
	char *fn = NULL;
	int ch, lvl1;

	while ((ch = getopt(argc, argv, "Aaf:nqw")) != -1) {
		switch (ch) {

		case 'A':
			Aflag = 1;
			break;

		case 'a':
			aflag = 1;
			break;

		case 'f':
			fn = optarg;
			wflag = 1;
			break;

		case 'n':
			nflag = 1;
			break;

		case 'q':
			qflag = 1;
			break;

		case 'w':
			wflag = 1;
			break;

		default:
			usage();
		}
	}

	if (qflag && !wflag)
		usage();

	argc -= optind;
	argv += optind;

	if (Aflag || aflag) {
		debuginit();
		for (lvl1 = 1; lvl1 < CTL_MAXID; lvl1++)
			listall(topname[lvl1].ctl_name, &secondlevel[lvl1]);
		return 0;
	}

	if (fn) {
#ifndef __QNXNTO__
		FILE *fp;
		char *l;

		fp = fopen(fn, "r");
		if (fp == NULL) {
			err(1, "%s", fn);
		} else {
			for (; (l = fparseln(fp, NULL, NULL, NULL, 0)) != NULL;
			    free(l)) {
				if (*l)
					parse(l, 1);
			}
			fclose(fp);
		}
#endif
	} else {
		if (argc == 0)
			usage();
		while (argc-- > 0)
			parse(*argv++, 1);
	}
	return 0;
}
Esempio n. 9
0
int
wl_save(struct tab *t, struct karg *args, int list)
{
	char			file[PATH_MAX], *lst_str = NULL;
	FILE			*f = NULL;
	char			*line = NULL, *lt = NULL, *dom;
	size_t			linelen;
	const gchar		*uri;
	struct karg		a;
	struct domain		*d;
	GSList			*cf;
	SoupCookie		*ci, *c;

	if (t == NULL || args == NULL)
		return (1);

	if (runtime_settings[0] == '\0')
		return (1);

	switch (list) {
	case XT_WL_JAVASCRIPT:
		lst_str = "JavaScript";
		break;
	case XT_WL_COOKIE:
		lst_str = "Cookie";
		break;
	case XT_WL_PLUGIN:
		lst_str = "Plugin";
		break;
	default:
		show_oops(t, "Invalid list id: %d", list);
		return (1);
	}

	uri = get_uri(t);
	dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
	if (uri == NULL || dom == NULL ||
	    webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
		show_oops(t, "Can't add domain to %s white list", lst_str);
		goto done;
	}

	switch (list) {
	case XT_WL_JAVASCRIPT:
		lt = g_strdup_printf("js_wl=%s", dom);
		break;
	case XT_WL_COOKIE:
		lt = g_strdup_printf("cookie_wl=%s", dom);
		break;
	case XT_WL_PLUGIN:
		lt = g_strdup_printf("pl_wl=%s", dom);
		break;
	default:
		/* can't happen */
		show_oops(t, "Invalid list id: %d", list);
		goto done;
	}

	snprintf(file, sizeof file, "%s" PS "%s", work_dir, runtime_settings);
	if ((f = fopen(file, "r+")) == NULL) {
		show_oops(t, "can't open file %s");
		goto done;
	}

	while (!feof(f)) {
		line = fparseln(f, &linelen, NULL, NULL, 0);
		if (line == NULL)
			continue;
		if (!strcmp(line, lt))
			goto done;
		free(line);
		line = NULL;
	}

	fprintf(f, "%s\n", lt);

	a.i = XT_WL_ENABLE;
	a.i |= args->i;
	switch (list) {
	case XT_WL_JAVASCRIPT:
		d = wl_find(dom, &js_wl);
		if (!d) {
			settings_add("js_wl", dom);
			d = wl_find(dom, &js_wl);
		}
		toggle_js(t, &a);
		break;

	case XT_WL_COOKIE:
		d = wl_find(dom, &c_wl);
		if (!d) {
			settings_add("cookie_wl", dom);
			d = wl_find(dom, &c_wl);
		}
		toggle_cwl(t, &a);

		/* find and add to persistent jar */
		cf = soup_cookie_jar_all_cookies(s_cookiejar);
		for (;cf; cf = cf->next) {
			ci = cf->data;
			if (!strcmp(dom, ci->domain) ||
			    !strcmp(&dom[1], ci->domain)) /* deal with leading . */ {
				c = soup_cookie_copy(ci);
				_soup_cookie_jar_add_cookie(p_cookiejar, c);
			}
		}
		soup_cookies_free(cf);
		break;

	case XT_WL_PLUGIN:
		d = wl_find(dom, &pl_wl);
		if (!d) {
			settings_add("pl_wl", dom);
			d = wl_find(dom, &pl_wl);
		}
		toggle_pl(t, &a);
		break;
	default:
		abort(); /* can't happen */
	}
	if (d)
		d->handy = 1;

done:
	if (line)
		free(line);
	if (dom)
		g_free(dom);
	if (lt)
		g_free(lt);
	if (f)
		fclose(f);

	return (0);
}
Esempio n. 10
0
int
main(int argc, char *argv[], char *envp[])
{
	FILE *config;
	char *line, *cp, *from, *to, *ap;
	const char *progname;
	char localmailerconf[MAXPATHLEN];
	const char *mailerconf;
	size_t len, lineno = 0;
	int i;
	struct arglist al;

	/* change __progname to mailwrapper so we get sensible error messages */
	progname = getprogname();
	setprogname("mailwrapper");

	initarg(&al);
	addarg(&al, argv[0]);

	snprintf(localmailerconf, MAXPATHLEN, "%s/etc/mail/mailer.conf",
	    getenv("LOCALBASE") ? getenv("LOCALBASE") : "/usr/local");

	mailerconf = localmailerconf;
	if ((config = fopen(localmailerconf, "r")) == NULL)
		mailerconf = _PATH_MAILERCONF;

	if (config == NULL && ((config = fopen(mailerconf, "r")) == NULL)) {
		addarg(&al, NULL);
		openlog(getprogname(), LOG_PID, LOG_MAIL);
		syslog(LOG_INFO, "cannot open %s, using %s as default MTA",
		    mailerconf, _PATH_DEFAULTMTA);
		closelog();
		execve(_PATH_DEFAULTMTA, al.argv, envp);
		err(EX_OSERR, "cannot exec %s", _PATH_DEFAULTMTA);
		/*NOTREACHED*/
	}

	for (;;) {
		if ((line = fparseln(config, &len, &lineno, NULL, 0)) == NULL) {
			if (feof(config))
				errx(EX_CONFIG, "no mapping in %s", mailerconf);
			err(EX_CONFIG, "cannot parse line %lu", (u_long)lineno);
		}

#define	WS	" \t\n"
		cp = line;

		cp += strspn(cp, WS);
		if (cp[0] == '\0') {
			/* empty line */
			free(line);
			continue;
		}

		if ((from = strsep(&cp, WS)) == NULL || cp == NULL)
			goto parse_error;

		cp += strspn(cp, WS);

		if ((to = strsep(&cp, WS)) == NULL)
			goto parse_error;

		if (strcmp(from, progname) == 0) {
			for (ap = strsep(&cp, WS); ap != NULL;
			     ap = strsep(&cp, WS)) {
				if (*ap)
				    addarg(&al, ap);
			}
			break;
		}

		free(line);
	}

	(void)fclose(config);

	for (i = 1; i < argc; i++)
		addarg(&al, argv[i]);

	addarg(&al, NULL);
	execve(to, al.argv, envp);
	err(EX_OSERR, "cannot exec %s", to);
	/*NOTREACHED*/
parse_error:
	errx(EX_CONFIG, "parse error in %s at line %lu",
	    mailerconf, (u_long)lineno);
	/*NOTREACHED*/
}
Esempio n. 11
0
int
main(int argc, char *argv[])
{
	size_t len, lineno = 0;
	char *line, *eptr, *longopt, *ptr, *optstring = NULL, *result = NULL;
	char buf[1024];
	char *args[128];
	char arg[256];
	int nargs = -1;
	int c;
	int nlongopts = 0;
	int maxnlongopts = 0;
	int *longopt_flags = NULL;
	struct option *longopts = NULL;

	while ((line = fparseln(stdin, &len, &lineno, NULL, 0)) != NULL) {
		if (strncmp(line, "optstring:", 10) == 0) {
			if (optstring)
				free(optstring);
			optstring = strtok(&line[11], WS);
			if (optstring == NULL)
			    errx(1, "missing optstring at line %ld",
				(unsigned long)lineno);
			optstring = strdup(optstring);
		} else if (strncmp(line, "longopts:", 9) == 0) {
			if (longopts) {
				int i;
				for (i = 0; i < nlongopts; i++)
					if (longopts[i].name != NULL)
						free(__UNCONST(longopts[i].name));
				free(longopts);
			}
			if (longopt_flags)
				free(longopt_flags);
			nlongopts = 0;
			ptr = strtok(&line[10], WS);
			if (ptr == NULL)
				errx(1, "missing longopts at line %ld",
				    (unsigned long)lineno);
			maxnlongopts = strtoul(ptr, &eptr, 10);
			if (*eptr != '\0')
				warnx("garbage in longopts at line %ld",
				    (unsigned long)lineno);
			maxnlongopts++;		/* space for trailer */
			longopts =
			    (struct option *)calloc(sizeof(struct option),
						    maxnlongopts);
			if (longopts == NULL)
				err(1, "calloc");
			longopt_flags = (int *)calloc(sizeof(int), maxnlongopts);
			if (longopt_flags == NULL)
				err(1, "calloc");
		} else if (strncmp(line, "longopt:", 8) == 0) {
			if (longopts == NULL)
				errx(1, "longopt: without longopts at line %ld",
				    (unsigned long)lineno);
			if (nlongopts >= maxnlongopts)
				errx(1, "longopt: too many options at line %ld",
				    (unsigned long)lineno);
			/* name */
			ptr = &line[9];
			SKIPWS(ptr);
			longopt = strsep(&ptr, ",");
			if (longopt == NULL)
				errx(1, "missing longopt at line %ld",
				    (unsigned long)lineno);
			longopts[nlongopts].name = strdup(longopt);
			/* has_arg */
			SKIPWS(ptr);
			longopt = strsep(&ptr, ",");
			if (*longopt != '\0') {
				if (strncmp(longopt, "0", 1) == 0 ||
				    strncmp(longopt, "no_argument", 2) == 0)
					longopts[nlongopts].has_arg = no_argument;
				else if (strncmp(longopt, "1", 1) == 0 ||
					 strncmp(longopt, "required_argument", 8) == 0)
					longopts[nlongopts].has_arg = required_argument;
				else if (strncmp(longopt, "2", 1) == 0 ||
					 strncmp(longopt, "optional_argument", 8) == 0)
					longopts[nlongopts].has_arg = optional_argument;
				else
					errx(1, "unknown has_arg %s at line %ld",
					    longopt, (unsigned long)lineno);
			}
			/* flag */
			SKIPWS(ptr);
			longopt = strsep(&ptr, ",");
			if (*longopt != '\0' &&
			    strncmp(longopt, "NULL", 4) != 0)
				longopts[nlongopts].flag = &longopt_flags[nlongopts];
			/* val */
			SKIPWS(ptr);
			longopt = strsep(&ptr, ",");
			if (*longopt == '\0')
				errx(1, "missing val at line %ld",
				    (unsigned long)lineno);
			if (*longopt != '\'') {
				longopts[nlongopts].val =
			            (int)strtoul(longopt, &eptr, 10);
				if (*eptr != '\0')
					errx(1, "invalid val at line %ld",
					    (unsigned long)lineno);
			} else
				longopts[nlongopts].val = (int)longopt[1];
			nlongopts++;
		} else if (strncmp(line, "args:", 5) == 0) {
			for (; nargs >= 0; nargs--) {
				if (args[nargs] != NULL)
					free(args[nargs]);
			}
			args[nargs = 0] = strtok(&line[6], WS);
			if (args[nargs] == NULL)
				errx(1, "Missing args");

			args[nargs] = strdup(args[nargs]);
			while ((args[++nargs] = strtok(NULL, WS)) != NULL)
				args[nargs] = strdup(args[nargs]);
		} else if (strncmp(line, "result:", 7) == 0) {
			int li;
			buf[0] = '\0';
			optind = optreset = 1;
			if (result)
				free(result);
			result = strtok(&line[8], WS);
			if (result == NULL)
				errx(1, "missing result at line %ld",
				    (unsigned long)lineno);
			if (optstring == NULL)
				errx(1, "result: without optstring");
			if (longopts == NULL || nlongopts == 0)
				errx(1, "result: without longopts");
			result = strdup(result);
			if (nargs == -1)
				errx(1, "result: without args");
			li = -2;
			while ((c = getopt_long(nargs, args, optstring,
				       	longopts, &li)) != -1)  {
				if (c == ':')
					errx(1, "`:' found as argument char");
				if (li == -2) {
					ptr = strchr(optstring, c);
					if (ptr == NULL) {
						snprintf(arg, sizeof(arg),
						    "!%c,", c);
						strcat(buf, arg);
						continue;
					}
					if (ptr[1] != ':')
						snprintf(arg, sizeof(arg),
						    "%c,", c);
					else
						snprintf(arg, sizeof(arg),
						    "%c=%s,", c, optarg);
				} else {
					switch (longopts[li].has_arg) {
					case no_argument:
						snprintf(arg, sizeof(arg), "-%s,",
						    longopts[li].name);
						break;
					case required_argument:
						snprintf(arg, sizeof(arg),
						    "-%s=%s,",
						    longopts[li].name, optarg);
						break;
					case optional_argument:
						snprintf(arg, sizeof(arg),
						    "-%s%s%s,",
						    longopts[li].name,
						    (optarg)? "=" : "",
						    (optarg)? optarg : "");
						break;
					default:
						errx(1, "internal error");
					}
				}
				strcat(buf, arg);
				li = -2;
			}
			len = strlen(buf);
			if (len > 0) {
				buf[len - 1] = '|';
				buf[len] = '\0';
			} else {
				buf[0] = '|';
				buf[1] = '\0';
			}
			snprintf(arg, sizeof(arg), "%d", nargs - optind);
			strcat(buf, arg);
			if (strcmp(buf, result) != 0)
				errx(1, "`%s' != `%s'", buf, result);
		} else
			errx(1, "unknown directive at line %ld",
			    (unsigned long)lineno);
		free(line);
	}
	return 0;
}
Esempio n. 12
0
int
main(int argc, char *argv[])
{
	FILE *fp;
	char *readbuf;
	struct group_entry *gcur;
	struct member_entry *mcur;
	char *host, *user, *domain;
	extern char *optarg;
	int ch;
	char *key = NULL, *data = NULL;
	int hosts = -1, i;

	if (argc < 2)
		usage();

	while ((ch = getopt(argc, argv, "uhf:")) != -1) {
		switch (ch) {
		case 'u':
			if (hosts != -1) {
				warnx("please use only one of -h or -u");
				usage();
			}
			hosts = 0;
			break;
		case 'h':
			if (hosts != -1) {
				warnx("please use only one of -u or -h");
				usage();
			}
			hosts = 1;
			break;
		case 'f':
			netgroup = optarg;
			break;
		default:
			usage();
			break;
		}
	}

	if (hosts == -1)
		usage();

	if (strcmp(netgroup, "-")) {
		if ((fp = fopen(netgroup, "r")) == NULL) {
			err(1, "%s", netgroup);
		}
	} else {
		fp = stdin;
	}

	/* Stuff all the netgroup names and members into a hash table. */
	while ((readbuf = fparseln(fp, NULL, NULL, NULL, 0)) != NULL) {
		data = strpbrk(readbuf, " \t");
		if (data == NULL) {
			free(readbuf);
			continue;
		}
		*data = '\0';
		++data;
		key = readbuf;
		ngstore(gtable, key, data);
		free(readbuf);
	}

	fclose(fp);

	/*
	 * Find all members of each netgroup and keep track of which
	 * group they belong to.
	 */
	for (i = 0; i < TABLESIZE; i++) {
		gcur = gtable[i];
		while (gcur) {
			__setnetgrent(gcur->key);
			while (__getnetgrent(&host, &user, &domain) != 0) {
				if (hosts) {
					if (!(host && !strcmp(host,"-"))) {
						mstore(mtable,
						    host ? host : "*",
						    gcur->key,
						    domain ? domain : "*");
					}
				} else {
					if (!(user && !strcmp(user,"-"))) {
						mstore(mtable,
						    user ? user : "******",
						    gcur->key,
						    domain ? domain : "*");
					}
				}
			}
			gcur = gcur->next;
		}
	}

	/* Release resources used by the netgroup parser code. */
	__endnetgrent();

	/* Spew out the results. */
	for (i = 0; i < TABLESIZE; i++) {
		mcur = mtable[i];
		while (mcur) {
			struct grouplist *tmp;
			printf ("%s.%s\t", mcur->key, mcur->domain);
			tmp = mcur->groups;
			while (tmp) {
				printf ("%s", tmp->groupname);
				tmp = tmp->next;
				if (tmp)
					printf(",");
			}
			mcur = mcur->next;
			printf ("\n");
		}
	}

	/* Let the OS free all our resources. */
	exit(0);
}
Esempio n. 13
0
int
main(int argc, char *argv[])
{
	struct group_entry *gcur;
	struct member_entry *mcur;
	FILE	*fp;
	char	*line, *p, *host, *user, *domain;
	int	 ch, i;
	size_t	 len;
	char	*key;
	int	 hosts = -1;

	if (argc < 2)
		usage();

	while ((ch = getopt(argc, argv, "uhf:")) != -1) {
		switch(ch) {
		case 'u':
			if (hosts != -1) {
				warnx("please use only one of -u or -h");
				usage();
			}
			hosts = 0;
			break;
		case 'h':
			if (hosts != -1) {
				warnx("please use only one of -u or -h");
				usage();
			}
			hosts = 1;
			break;
		case 'f':
			netgroup = optarg;
			break;
		default:
			usage();
			break;
		}
	}

	if (hosts == -1)
		usage();

	if (strcmp(netgroup, "-")) {
		if ((fp = fopen(netgroup, "r")) == NULL) {
			err(1, "%s", netgroup);
		}
	} else {
		fp = stdin;
	}

	/* Stuff all the netgroup names and members into a hash table. */
	for (;
	    (line = fparseln(fp, &len, NULL, NULL, FPARSELN_UNESCALL));
	    free(line)) {
		if (len == 0)
			continue;
		p = line;

		for (key = p; *p && isspace((unsigned char)*p) == 0; p++)
			;
		while (*p && isspace((unsigned char)*p))
			*p++ = '\0';
		store(gtable, key, p);
	}

	fclose(fp);

	/*
	 * Find all members of each netgroup and keep track of which
	 * group they belong to.
	 */
	for (i = 0; i < TABLESIZE; i++) {
		gcur = gtable[i];
		while (gcur) {
			rng_setnetgrent(gcur->key);
			while (rng_getnetgrent(&host, &user, &domain) != 0) {
				if (hosts) {
					if (!(host && !strcmp(host,"-"))) {
						mstore(mtable,
						       host ? host : "*",
						       gcur->key,
						       domain ? domain : "*");
					}
				} else {
					if (!(user && !strcmp(user,"-"))) {
						mstore(mtable,
						       user ? user : "******",
						       gcur->key,
						       domain ? domain : "*");
					}
				}
			}
			gcur = gcur->next;
		}
	}

	/* Release resources used by the netgroup parser code. */
	rng_endnetgrent();

	/* Spew out the results. */
	for (i = 0; i < TABLESIZE; i++) {
		mcur = mtable[i];
		while (mcur) {
			struct grouplist *tmp;
			printf ("%s.%s\t", mcur->key, mcur->domain);
			tmp = mcur->groups;
			while (tmp) {
				printf ("%s", tmp->groupname);
				tmp = tmp->next;
				if (tmp)
					printf(",");
			}
			mcur = mcur->next;
			printf ("\n");
		}
	}

	/* Let the OS free all our resources. */
	exit(0);
}
Esempio n. 14
0
/* remove a favorite */
void
remove_favorite(struct tab *t, int index)
{
	char			file[PATH_MAX], *title, *uri = NULL;
	char			*new_favs, *tmp;
	FILE			*f;
	int			i;
	size_t			len, lineno;

	/* open favorites */
	snprintf(file, sizeof file, "%s" PS "%s", work_dir, XT_FAVS_FILE);

	if ((f = fopen(file, "r")) == NULL) {
		show_oops(t, "%s: can't open favorites: %s",
		    __func__, strerror(errno));
		return;
	}

	/* build a string which will become the new favroites file */
	new_favs = g_strdup("");

	for (i = 1;;) {
		if ((title = fparseln(f, &len, &lineno, NULL, 0)) == NULL)
			if (feof(f) || ferror(f))
				break;
		/* XXX THIS IS NOT THE RIGHT HEURISTIC */
		if (len == 0) {
			free(title);
			title = NULL;
			continue;
		}

		if ((uri = fparseln(f, &len, &lineno, NULL, 0)) == NULL) {
			if (feof(f) || ferror(f)) {
				show_oops(t, "%s: can't parse favorites %s",
				    __func__, strerror(errno));
				goto clean;
			}
		}

		/* as long as this isn't the one we are deleting add to file */
		if (i != index) {
			tmp = new_favs;
			new_favs = g_strdup_printf("%s%s\n%s\n",
			    new_favs, title, uri);
			g_free(tmp);
		}

		free(uri);
		uri = NULL;
		free(title);
		title = NULL;
		i++;
	}
	fclose(f);

	/* write back new favorites file */
	if ((f = fopen(file, "w")) == NULL) {
		show_oops(t, "%s: can't open favorites: %s",
		    __func__, strerror(errno));
		goto clean;
	}

	if (fwrite(new_favs, strlen(new_favs), 1, f) != 1)
		show_oops(t, "%s: can't fwrite", __func__);
	fclose(f);

clean:
	if (uri)
		free(uri);
	if (title)
		free(title);

	g_free(new_favs);
}
Esempio n. 15
0
/* read_line():
 *	Read a line from a file, parsing continuations ending in \
 *	and eliminating trailing newlines.
 *	Returns a pointer to an internal buffer that is reused upon
 *	next invocation.
 *
 * NOTE: if HAS_FPARSELN is not defined, delim and flags are currently unused.
 */
char *
read_line(FILE * fp, size_t * size, size_t * lineno, const char *delim,
	  int flags)
{
	static char *buf;
#ifdef HAS_FPARSELN

	if (buf != NULL)
		free(buf);
	return (buf = fparseln(fp, size, lineno, delim, flags));
#else
	char *n;
#ifndef HAS_FGETLN
	char sbuf[1024];
#endif
	static int buflen;

	size_t s, len;
	char *ptr;
	int cnt;

	len = 0;
	cnt = 1;
	while (cnt) {
		if (lineno != NULL)
			(*lineno)++;
#ifdef HAS_FGETLN
		if ((ptr = fgetln(fp, &s)) == NULL) {
			if (size != NULL)
				*size = len;
			if (len == 0)
				return NULL;
			else
				return buf;
		}
#else
		if ((ptr = fgets(sbuf, sizeof(sbuf) - 1, fp)) == NULL) {
			if (len == 0)
				return NULL;
			else
				return buf;
		} else {
			char *l;
			if ((l = strchr(sbuf, '\n')) == NULL) {
				if (sbuf[sizeof(sbuf) - 3] != '\\') {
					s = sizeof(sbuf);
					sbuf[sizeof(sbuf) - 2] = '\\';
					sbuf[sizeof(sbuf) - 1] = '\0';
				} else
					s = sizeof(sbuf) - 1;
			} else {
				s = l - sbuf;
			}
		}
#endif
		if (ptr[s - 1] == '\n')	/* the newline may be missing at EOF */
			s--;	/* forget newline */
		if (!s)
			cnt = 0;
		else {
			if ((cnt = (ptr[s - 1] == '\\')) != 0)
				s--;	/* forget \\ */
		}

		if (len + s + 1 > buflen) {
			n = realloc(buf, len + s + 1);
			if (n == NULL)
				err(1, "can't realloc");
			buf = n;
			buflen = len + s + 1;
		}
		memcpy(buf + len, ptr, s);
		len += s;
		buf[len] = '\0';
	}
	if (size != NULL)
		*size = len;
	return buf;
#endif				/* HAS_FPARSELN */
}