Beispiel #1
0
/*
 *  report a recipient to remote
 */
char *
rcptto(char *to)
{
	String *s;

	s = unescapespecial(bangtoat(to));
	if(toline == 0)
		toline = s_new();
	else
		s_append(toline, ", ");
	s_append(toline, s_to_c(s));
	if(strchr(s_to_c(s), '@'))
		dBprint("RCPT TO:<%s>\r\n", s_to_c(s));
	else {
		s_append(toline, "@");
		s_append(toline, ddomain);
		dBprint("RCPT TO:<%s@%s>\r\n", s_to_c(s), ddomain);
	}
	alarm(10*alarmscale);
	switch(getreply()){
	case 2:
		break;
	case 5:
		return Giveup;
	default:
		return Retry;
	}
	return 0;
}
Beispiel #2
0
int
ztns_append_bool (ztns_t *self, bool data)
{
    if (data)
        return s_append (self, "true", '!');
    return s_append (self, "false", '!');
}
Beispiel #3
0
FUNCTION COUNT t_highlight
(
 TEXT	string[]		/* in/out: string to highlight	*/
)
    {
    TEXT local[STRINGSIZ+1];

/*
 *	t_highlight has a conceptual problem in unix:  the escape
 *	sequences in the termcap file have numeric prefixes indicating
 *	the number of milliseconds delay required for highlighting.
 *	Such delays are normally interpreted by tputs, for example
 *	see t_clear.   With the TAE highlight concept--i.e., surrounding
 *	a string with escape sequence and letting the user 
 *	subsequently write the string with t_write/t_output--we
 *	never have the opportunity to call tputs to interpret the
 *	delays.
 *
 *	Our approach is to strip the highlighting escape
 *	sequence of this delay element during the initialization
 *	phase. See t_init() above.
 */
    if (stand_out1 == NULL || stand_out2 == NULL)
	return(0);
    s_copy (string, local);		/* local copy 		*/
    s_copy(stand_out1, string);	
    s_append(local, string);
    s_append(stand_out2, string);

    return (s_length(stand_out1) + s_length(stand_out2));
    }
Beispiel #4
0
FUNCTION VOID synerr 
(
    FAST struct SYNBLK	*sb,		/* in/out: syntax block			*/
    FAST TEXT		*es		/* in:  error message string		*/

#define		NERRCH	10		/* dump 10 chars of surrounding text	*/

 )
    {
    FAST COUNT	i;
    TEXT	txt[NERRCH+1];		/* buffer to hold surrounding text	*/

    
    for (i=0; *es != 0; es++, i++)	/* copy caller's string			*/
    	{
	if (i == EMSIZ - (NERRCH+sizeof(" at or near  ")+2) )
    	    break;					/* don't wipe out 	*/
    	(*sb).errmsg[i] = *es;		/* move caller's string to block	*/
    	}
    s_copy(" at or near  ", &(*sb).errmsg[i]);
    errstr(sb, NERRCH, txt);		/* get text surrounding error		*/
    s_append("'", (*sb).errmsg);	/* enclose in tick marks		*/
    s_append(txt, (*sb).errmsg);	/* append text to EM			*/
    s_append("'", (*sb).errmsg);
    return;
    }
Beispiel #5
0
void file_path_build( t_file *file)
{
	int c = 0;
	char path[_PATH_];
	bzero( path, _PATH_);
	if( file->path_type == PATH_RELATIVE)
	{
		path[0] = '.';
		c++;
	}
	else if( file->path_type == PATH_ABSOLUTE)
	{
		path[0] = '/';
		c++;
	}

	int i;
	for( i = 0; i <= file->dir_count; i++)
	{
		c = s_append( path, file->dirs[i], c);
		c = s_append( path, "/", c);
	}

	s_cp( file->path, path, _PATH_);
}
Beispiel #6
0
/*
 * if name is int32_ter than Namsiz bytes, try to split it at a slash and fit the
 * pieces into hp->prefix and hp->name.
 */
static int
putfullname(Hdr *hp, char *name)
{
	int namlen, pfxlen;
	char *sl, *osl;
	String *slname = nil;

	if (isdir(hp)) {
		slname = s_new();
		s_append(slname, name);
		s_append(slname, "/");		/* posix requires this */
		name = s_to_c(slname);
	}

	namlen = strlen(name);
	if (namlen <= Namsiz) {
		strncpy(hp->name, name, Namsiz);
		hp->prefix[0] = '\0';		/* ustar paranoia */
		return 0;
	}

	if (!posix || namlen > Maxname) {
		fprint(2, "%s: name too int32_t for tar header: %s\n",
			argv0, name);
		return -1;
	}
	/*
	 * try various splits until one results in pieces that fit into the
	 * appropriate fields of the header.  look for slashes from right
	 * to left, in the hopes of putting the largest part of the name into
	 * hp->prefix, which is larger than hp->name.
	 */
	sl = strrchr(name, '/');
	while (sl != nil) {
		pfxlen = sl - name;
		if (pfxlen <= sizeof hp->prefix && namlen-1 - pfxlen <= Namsiz)
			break;
		osl = sl;
		*osl = '\0';
		sl = strrchr(name, '/');
		*osl = '/';
	}
	if (sl == nil) {
		fprint(2, "%s: name can't be split to fit tar header: %s\n",
			argv0, name);
		return -1;
	}
	*sl = '\0';
	strncpy(hp->prefix, name, sizeof hp->prefix);
	*sl++ = '/';
	strncpy(hp->name, sl, sizeof hp->name);
	if (slname)
		s_free(slname);
	return 0;
}
Beispiel #7
0
/* dispose of local addresses */
int
cat_mail(dest *dp, message *mp)
{
	Biobuf *fp;
	char *rcvr, *cp;
	Mlock *l;
	String *tmp, *s;
	int i, n;

	s = unescapespecial(s_clone(dp->repl1));
	if (nflg) {
		if(!xflg)
			print("cat >> %s\n", s_to_c(s));
		else
			print("%s\n", s_to_c(dp->addr));
		s_free(s);
		return 0;
	}
	for(i = 0;; i++){
		l = syslock(s_to_c(s));
		if(l == 0)
			return refuse(dp, mp, "can't lock mail file", 0, 0);

		fp = sysopen(s_to_c(s), "al", MBOXMODE);
		if(fp)
			break;
		tmp = s_append(0, s_to_c(s));
		s_append(tmp, ".tmp");
		fp = sysopen(s_to_c(tmp), "al", MBOXMODE);
		if(fp){
			syslog(0, "mail", "error: used %s", s_to_c(tmp));
			s_free(tmp);
			break;
		}
		s_free(tmp);
		sysunlock(l);
		if(i >= 5)
			return refuse(dp, mp, "mail file cannot be opened", 0, 0);
		sleep(1000);
	}
	s_free(s);
	n = m_print(mp, fp, (char *)0, 1);
	if (Bprint(fp, "\n") < 0 || Bflush(fp) < 0 || n < 0){
		sysclose(fp);
		sysunlock(l);
		return refuse(dp, mp, "error writing mail file", 0, 0);
	}
	sysclose(fp);
	sysunlock(l);
	rcvr = s_to_c(dp->addr);
	if(cp = strrchr(rcvr, '!'))
		rcvr = cp+1;
	logdelivery(dp, rcvr, mp);
	return 0;
}
Beispiel #8
0
/*
 *  walk up the tree building a Unix style path
 */
static void
unixpath(Node *node, String *path)
{
	if(node == node->parent){
		s_append(path, s_to_c(remrootpath));
		return;
	}
	unixpath(node->parent, path);
	if(s_len(path) > 0 && strcmp(s_to_c(path), "/") != 0)
		s_append(path, "/");
	s_append(path, s_to_c(node->remname));
}
Beispiel #9
0
/*
 *  walk up the tree building a MVS style path
 */
static void
mvspath(Node *node, String *path)
{
	if(node == node->parent){
		s_append(path, s_to_c(remrootpath));
		return;
	}
	mvspath(node->parent, path);
	if(s_len(path) > 0)
		s_append(path, ".");
	s_append(path, s_to_c(node->remname));
}
Beispiel #10
0
/*
 *  simplify an address, reduce to a domain
 */
static String*
simplify(char *addr)
{
	int dots, dotlim;
	char *p, *at;
	String *s;

	mklower(addr);
	at = strchr(addr, '@');
	if(at == nil){
		/* local address, make it an exact match */
		s = s_copy("=");
		s_append(s, addr);
		return s;
	}

	/* copy up to, and including, the '@' sign */
	at++;
	s = s_copy("~");
	for(p = addr; p < at; p++){
		if(strchr(".*+?(|)\\[]^$", *p))
			s_putc(s, '\\');
		s_putc(s, *p);
	}

	/*
	 * just any address matching the two most significant domain elements,
	 * except for .uk, which needs three.
	 */
	s_append(s, "(.*\\.)?");
	p = addr+strlen(addr);			/* point at NUL */
	if (p[-1] == '.')
		*--p = '\0';
	if (p - addr > 3 && strcmp(".uk", p - 3) == 0)
		dotlim = 3;
	else
		dotlim = 2;
	dots = 0;
	while(--p > at)
		if(*p == '.' && ++dots >= dotlim){
			p++;
			break;
		}
	for(; *p; p++){
		if(strchr(".*+?(|)\\[]^$", *p) != nil)
			s_putc(s, '\\');
		s_putc(s, *p);
	}
	s_terminate(s);

	return s;
}
Beispiel #11
0
vlong
du(char *name, Dir *dir)
{
	int fd, i, n;
	Dir *buf, *d;
	String *file;
	vlong nk, t;

	if(dir == nil)
		return warn(name);

	if((dir->qid.type&QTDIR) == 0)
		return dirval(dir, blkmultiple(dir->length));

	fd = open(name, OREAD);
	if(fd < 0)
		return warn(name);
	nk = 0;
	while((n=dirread(fd, &buf)) > 0) {
		d = buf;
		for(i = n; i > 0; i--, d++) {
			if((d->qid.type&QTDIR) == 0) {
				nk += dufile(name, d);
				continue;
			}

			if(strcmp(d->name, ".") == 0 ||
			   strcmp(d->name, "..") == 0 ||
			   /* !readflg && */ seen(d))
				continue;	/* don't get stuck */

			file = s_copy(name);
			s_append(file, "/");
			s_append(file, d->name);

			t = du(s_to_c(file), d);

			nk += t;
			t = dirval(d, t);
			if(!sflag)
				printamt(t, s_to_c(file));
			s_free(file);
		}
		free(buf);
	}
	if(n < 0)
		warn(name);
	close(fd);
	return dirval(dir, nk);
}
Beispiel #12
0
/*
 *	ensure route addr has brackets around it
 */
String*
fixrouteaddr(String *raddr, Node *next, Node *last)
{
	String *a;

	if(last && last->c == '<' && next && next->c == '>')
		return raddr;			/* properly formed already */

	a = s_new();
	s_append(a, "<");
	s_append(a, s_to_c(raddr));
	s_append(a, ">");
	s_free(raddr);
	return a;
}
Beispiel #13
0
/*
 *  create abs path of the mailer
 */
String*
mailerpath(char *p)
{
	String *s;

	if(p == nil)
		return nil;
	if(*p == '/')
		return s_copy(p);
	s = s_new();
	s_append(s, UPASBIN);
	s_append(s, "/");
	s_append(s, p);
	return s;
}
Beispiel #14
0
/*
 *  Get the next token from `line'.  The symbol `\l' is replaced by
 *  the name of the local system.
 */
extern String *
rule_parse(String *line, char *system, int *backl)
{
	String *token;
	String *expanded;
	char *cp;

	token = s_parse(line, 0);
	if(token == 0)
		return(token);
	if(strchr(s_to_c(token), '\\')==0)
		return(token);
	expanded = s_new();
	for(cp = s_to_c(token); *cp; cp++) {
		if(*cp == '\\') switch(*++cp) {
		case 'l':
			s_append(expanded, system);
			*backl = 1;
			break;
		case '\\':
			s_putc(expanded, '\\');
			break;
		default:
			s_putc(expanded, '\\');
			s_putc(expanded, *cp);
			break;
		} else
			s_putc(expanded, *cp);
	}
	s_free(token);
	s_terminate(expanded);
	return(expanded);
}
Beispiel #15
0
/*
 *  like trylock, but we've already got the lock on fd,
 *  and don't want an L. lock file.
 */
static Mlock *
keeplockalive(char *path, int fd)
{
	char buf[1];
	Mlock *l;

	l = malloc(sizeof(Mlock));
	if(l == 0)
		return 0;
	l->fd = fd;
	l->name = s_new();
	s_append(l->name, path);

	/* fork process to keep lock alive until sysunlock(l) */
	switch(l->pid = rfork(RFPROC)){
	default:
		break;
	case 0:
		fd = l->fd;
		for(;;){
			sleep(1000*60);
			if(pread(fd, buf, 1, 0) < 0)
				break;
		}
		_exits(0);
	}
	return l;
}
Beispiel #16
0
String*
s_appendsub(String *s, char *p, int n, Sub *sub, int nsub)
{
	int i, m;
	char *q, *r, *ep;

	ep = p+n;
	while(p<ep){
		q = ep;
		m = -1;
		for(i=0; i<nsub; i++){
			if(sub[i].sub && (r = strstr(p, sub[i].match)) && r < q){
				q = r;
				m = i;
			}
		}
		s = s_nappend(s, p, q-p);
		p = q;
		if(m >= 0){
			s = s_append(s, sub[m].sub);
			p += strlen(sub[m].match);
		}
	}
	return s;
}
Beispiel #17
0
/*
 *  simplify an address, reduce to a domain
 */
static String*
simplify(char *addr)
{
	int dots;
	char *p, *at;
	String *s;

	mklower(addr);
	at = strchr(addr, '@');
	if(at == nil){
		/* local address, make it an exact match */
		s = s_copy("=");
		s_append(s, addr);
		return s;
	}

	/* copy up to the '@' sign */
	at++;
	s = s_copy("~");
	for(p = addr; p < at; p++){
		if(strchr(".*+?(|)\\[]^$", *p))
			s_putc(s, '\\');
		s_putc(s, *p);
	}

	/* just any address matching the two most significant domain elements */
	s_append(s, "(.*\\.)?");
	p = addr+strlen(addr);
	dots = 0;
	for(; p > at; p--){
		if(*p != '.')
			continue;
		if(dots++ > 0){
			p++;
			break;
		}
	}
	for(; *p; p++){
		if(strchr(".*+?(|)\\[]^$", *p) != 0)
			s_putc(s, '\\');
		s_putc(s, *p);
	}
	s_terminate(s);

	return s;
}
Beispiel #18
0
int
smbremovefile(SmbTree *t, char *dir, char *name)
{
	String *s;
	int rv;
	s = s_new();
	s_append(s, t->serv->path);
	s_append(s, "/");
	if (dir) {
		s_append(s, dir);
		s_append(s, "/");
	}
	s_append(s, name);
	rv = remove(s_to_c(s));
	s_free(s);
	return rv;
}
Beispiel #19
0
extern int
default_from(message *mp)
{
	char *cp, *lp;

	cp = getenv("upasname");
	lp = getlog();
	if(lp == nil)
		return -1;

	if(cp && *cp)
		s_append(mp->sender, cp);
	else
		s_append(mp->sender, lp);
	s_append(mp->date, thedate());
	return 0;
}
Beispiel #20
0
/* loop through the translation files */
static int
translate(char *name,		/* name to translate */
	char **namev,		/* names of this system */
	String *files,		/* names of system alias files */
	String *alias)		/* where to put the alias */
{
	String *file = s_new();
	String **fullnamev;
	int n, rv;

	rv = -1;

	DEBUG print("translate(%s, %s, %s)\n", name,
		s_to_c(files), s_to_c(alias));

	/* create the full name to avoid loops (system!name) */
	for(n = 0; namev[n]; n++)
		;
	fullnamev = (String**)malloc(sizeof(String*)*(n+2));
	n = 0;
	fullnamev[n++] = s_copy(name);
	for(; *namev; namev++){
		fullnamev[n] = s_copy(*namev);
		s_append(fullnamev[n], "!");
		s_append(fullnamev[n], name);
		n++;
	}
	fullnamev[n] = 0;

	/* look at system-wide names */
	s_restart(files);
	while (s_parse(files, s_restart(file)) != 0) {
		if (lookup(fullnamev, file, alias)==0) {
			rv = 0;
			goto out;
		}
	}

out:
	for(n = 0; fullnamev[n]; n++)
		s_free(fullnamev[n]);
	s_free(file);
	free(fullnamev);
	return rv;
}
Beispiel #21
0
vlong
dufile(char *name, Dir *d)
{
	vlong t = blkmultiple(d->length);

	if(aflag || readflg) {
		String *file = s_copy(name);

		s_append(file, "/");
		s_append(file, d->name);
		if (readflg)
			readfile(s_to_c(file));
		t = dirval(d, t);
		printamt(t, s_to_c(file));
		s_free(file);
	}
	return t;
}
Beispiel #22
0
/*
 *  add a domain onto an name, return the new name
 */
char *
domainify(char *name, char *domain)
{
	static String *s;
	char *p;

	if(domain==0 || strchr(name, '.')!=0)
		return name;

	s = s_reset(s);
	s_append(s, name);
	p = strchr(domain, '.');
	if(p == 0){
		s_append(s, ".");
		p = domain;
	}
	s_append(s, p);
	return s_to_c(s);
}
Beispiel #23
0
/*
 *	Convert from `bang' to `source routing' format.
 *
 *	   a.x.y!b.p.o!c!d ->	@a.x.y:[email protected]
 */
String *
bangtoat(char *addr)
{
	String *buf;
	register int i;
	int j, d;
	char *field[128];

	/* parse the '!' format address */
	buf = s_new();
	for(i = 0; addr; i++){
		field[i] = addr;
		addr = strchr(addr, '!');
		if(addr)
			*addr++ = 0;
	}
	if (i==1) {
		s_append(buf, field[0]);
		return buf;
	}

	/*
	 *  count leading domain fields (non-domains don't count)
	 */
	for(d = 0; d<i-1; d++)
		if(strchr(field[d], '.')==0)
			break;
	/*
	 *  if there are more than 1 leading domain elements,
	 *  put them in as source routing
	 */
	if(d > 1){
		addhostdom(buf, field[0]);
		for(j=1; j<d-1; j++){
			s_append(buf, ",");
			s_append(buf, "@");
			s_append(buf, field[j]);
		}
		s_append(buf, ":");
	}

	/*
	 *  throw in the non-domain elements separated by '!'s
	 */
	s_append(buf, field[d]);
	for(j=d+1; j<=i-1; j++) {
		s_append(buf, "!");
		s_append(buf, field[j]);
	}
	if(d)
		addhostdom(buf, field[d-1]);
	return buf;
}
Beispiel #24
0
/*
 *  convert header addresses to @ format.
 *  if the address is a source address, and a domain is specified,
 *  make sure it falls in the domain.
 */
String*
convertheader(String *from)
{
	Field *f;
	Node *p, *lastp;
	String *a;

	if(!returnable(s_to_c(from))){
		from = s_new();
		s_append(from, "Postmaster");
		addhostdom(from, hostdomain);
	} else
	if(strchr(s_to_c(from), '@') == 0){
		a = username(from);
		if(a) {
			s_append(a, " <");
			s_append(a, s_to_c(from));
			addhostdom(a, hostdomain);
			s_append(a, ">");
			from = a;
		} else {
			from = s_copy(s_to_c(from));
			addhostdom(from, hostdomain);
		}
	} else
		from = s_copy(s_to_c(from));
	for(f = firstfield; f; f = f->next){
		lastp = 0;
		for(p = f->node; p; lastp = p, p = p->next){
			if(!p->addr)
				continue;
			a = bangtoat(s_to_c(p->s));
			s_free(p->s);
			if(strchr(s_to_c(a), '@') == 0)
				addhostdom(a, hostdomain);
			else if(*s_to_c(a) == '@')
				a = fixrouteaddr(a, p->next, lastp);
			p->s = a;
		}
	}
	return from;
}
Beispiel #25
0
int
ztns_append_llong (ztns_t *self, long long data)
{
    uint str_len = s_get_str_len (data);
    char data_str[str_len + NULL_LENGTH];
    int chars_written = snprintf (data_str, str_len + NULL_LENGTH, "%lld", data);
    assert (chars_written >= 0 || chars_written <= str_len);
    if (chars_written < 0 || chars_written > str_len)
        return -1;
    return s_append (self, data_str, '#');
}
Beispiel #26
0
int
ztns_append_float (ztns_t *self, float data)
{
    const uint MAX_FLOAT_CHARS = strlen("-0.") + FLT_MANT_DIG - FLT_MIN_EXP;
    char data_str[MAX_FLOAT_CHARS + NULL_LENGTH];
    int chars_written = snprintf (data_str, MAX_FLOAT_CHARS + NULL_LENGTH, "%.*f", MAX_FLOAT_CHARS, data);
    assert (chars_written >= 0 || chars_written <= MAX_FLOAT_CHARS);
    if (chars_written < 0 || chars_written > MAX_FLOAT_CHARS)
        return -1;
    return s_append (self, data_str, '^');
}
Beispiel #27
0
/* get the text of a header line minus the field name */
static String*
getstring(Node *p)
{
	String *s;

	s = s_new();
	if(p == nil)
		return s;

	for(p = p->next; p; p = p->next){
		if(p->s){
			s_append(s, s_to_c(p->s));
		}else{
			s_putc(s, p->c);
			s_terminate(s);
		}
		if(p->white)
			s_append(s, s_to_c(p->white));
	}
	return s;
}
Beispiel #28
0
String*
s_appendlist(String *s, ...)
{
	char *x;
	va_list arg;

	va_start(arg, s);
	while(x = va_arg(arg, char*))
		s = s_append(s, x);
	va_end(arg);
	return s;
}
Beispiel #29
0
static void
addtreetoar(int ar, char *file, char *shortf, int fd)
{
	int n;
	Dir *dent, *dirents;
	String *name = s_new();

	n = dirreadall(fd, &dirents);
	if (n < 0)
		fprint(2, "%s: dirreadall %s: %r\n", argv0, file);
	close(fd);
	if (n <= 0)
		return;

	if (chdir(shortf) < 0)
		sysfatal("chdir %s: %r", file);
	if (Debug)
		fprint(2, "chdir %s\t# %s\n", shortf, file);

	for (dent = dirents; dent < dirents + n; dent++) {
		s_reset(name);
		s_append(name, file);
		s_append(name, "/");
		s_append(name, dent->name);
		addtoar(ar, s_to_c(name), dent->name);
	}
	s_free(name);
	free(dirents);

	/*
	 * this assumes that shortf is just one component, which is true
	 * during directory descent, but not necessarily true of command-line
	 * arguments.  Our caller (or addtoar's) must reset the working
	 * directory if necessary.
	 */
	if (chdir("..") < 0)
		sysfatal("chdir %s/..: %r", file);
	if (Debug)
		fprint(2, "chdir ..\n");
}
Beispiel #30
0
int
matcher(char *action, Pattern *p, char *message, Resub *m)
{
    char *cp;
    String *s;

    for(cp = message; matchpat(p, cp, m); cp = m->ep) {
        switch(p->action) {
        case SaveLine:
            if(vflag)
                xprint(2, action, m);
            saveline(linefile, sender, m);
            break;
        case HoldHeader:
        case Hold:
            if(nflag)
                continue;
            if(vflag)
                xprint(2, action, m);
            *qdir = holdqueue;
            if(hflag && qname) {
                cp = strchr(sender, '!');
                if(cp) {
                    *cp = 0;
                    *qname = strdup(sender);
                    *cp = '!';
                } else
                    *qname = strdup(sender);
            }
            return 1;
        case Dump:
            if(vflag)
                xprint(2, action, m);
            *(m->ep) = 0;
            if(!tflag) {
                s = s_new();
                s_append(s, sender);
                s = unescapespecial(s);
                syslog(0, "smtpd", "Dumped %s [%s] to %s", s_to_c(s), m->sp,
                       s_to_c(s_restart(recips)));
                s_free(s);
            }
            tflag = 1;
            if(sflag)
                cout = opendump(sender);
            return 1;
        default:
            break;
        }
    }
    return 0;
}