Ejemplo n.º 1
0
/* return 1 if name found in one of the files
 *	  0 if name not found in one of the files
 *	  -1 if neither file exists
 */
extern int
lookup(char *cp, char *local, Biobuf **lfpp, char *global, Biobuf **gfpp)
{
	static String *file = 0;

	if (local) {
		if (file == 0)
			file = s_new();
		abspath(local, UPASLIB, s_restart(file));
		if (*lfpp != 0 || (*lfpp = sysopen(s_to_c(file), "r", 0)) != 0) {
			if (okfile(cp, *lfpp))
				return 1;
		} else
			local = 0;
	}
	if (global) {
		abspath(global, UPASLIB, s_restart(file));
		if (*gfpp != 0 || (*gfpp = sysopen(s_to_c(file), "r", 0)) != 0) {
			if (okfile(cp, *gfpp))
				return 1;
		} else
			global = 0;
	}
	return (local || global)? 0 : -1;
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
void
saveline(char *file, char *sender, Resub *rp)
{
    char *p, *q;
    int i, c;
    Biobuf *bp;

    if(rp->sp == 0 || rp->ep == 0)
        return;
    /* back up approx 20 characters to whitespace */
    for(p = rp->sp, i = 0; *p && i < 20; i++, p--)
        ;
    while(*p && *p != ' ')
        p--;
    p++;

    /* grab about 20 more chars beyond the end of the match */
    for(q = rp->ep, i = 0; *q && i < 20; i++, q++)
        ;
    while(*q && *q != ' ')
        q++;

    c = *q;
    *q = 0;
    bp = sysopen(file, "al", 0644);
    if(bp) {
        Bprint(bp, "%s-> %s\n", sender, p);
        Bterm(bp);
    }
    else if(debug)
        fprint(2, "can't save line: (%s) %s\n", sender, p);
    *q = c;
}
Ejemplo n.º 4
0
/*
 *  rules are of the form:
 *	<reg exp> <String> <repl exp> [<repl exp>]
 */
extern int
getrules(void)
{
	Biobuf	*rfp;
	String	*line;
	String	*type;
	String	*file;

	file = abspath("rewrite", UPASLIB, (String *)0);
	rfp = sysopen(s_to_c(file), "r", 0);
	if(rfp == 0) {
		rulep = 0;
		return -1;
	}
	rlastp = 0;
	line = s_new();
	type = s_new();
	while(s_getline(rfp, s_restart(line)))
		if(getrule(line, type, thissys) && altthissys)
			getrule(s_restart(line), type, altthissys);
	s_free(type);
	s_free(line);
	s_free(file);
	sysclose(rfp);
	return 0;
}
Ejemplo n.º 5
0
/*
 *  call up the connection server and get a translation
 */
static int nettrans(char *addr, char *naddr, int na, char *file, int nf)
{
	int i, fd;
	char buf[Maxpath];
	char netdir[NETPATHLEN];
	char *p, *p2;
	long n;

	/*
	 *  parse, get network directory
	 */
	p = strchr(addr, '!');
	if (p == 0) {
		set_errstr("bad dial string: %s", addr);
		return -1;
	}
	if (*addr != '/') {
		strlcpy(netdir, "/net", sizeof(netdir));
	} else {
		for (p2 = p; *p2 != '/'; p2--) ;
		i = p2 - addr;
		if (i == 0 || i >= sizeof(netdir)) {
			set_errstr("bad dial string: %s", addr);
			return -1;
		}
		strlcpy(netdir, addr, i + 1);
		addr = p2 + 1;
	}

	/*
	 *  ask the connection server
	 */
	snprintf(buf, sizeof(buf), "%s/cs", netdir);
	fd = sysopen(buf, O_RDWR);
	if (fd < 0)
		return identtrans(netdir, addr, naddr, na, file, nf);
	if (syswrite(fd, addr, strlen(addr)) < 0) {
		sysclose(fd);
		return -1;
	}
	sysseek(fd, 0, 0);
	n = sysread(fd, buf, sizeof(buf) - 1);
	sysclose(fd);
	if (n <= 0)
		return -1;
	buf[n] = 0;

	/*
	 *  parse the reply
	 */
	p = strchr(buf, ' ');
	if (p == 0)
		return -1;
	*p++ = 0;
	strlcpy(naddr, p, na);
	strlcpy(file, buf, nf);
	return 0;
}
Ejemplo n.º 6
0
extern int
open(const char* path, int flags, ...)
{
	int		fd;
	int		mode;
	int		oerrno;
	char		buf[PATH_MAX];
#if _win32_botch_copy
	struct stat	st;
#endif
	va_list		ap;

	va_start(ap, flags);
	mode = (flags & O_CREAT) ? va_arg(ap, int) : 0;
	oerrno = errno;
	fd = sysopen(path, flags, mode);
#if _win32_botch_open
	if (fd < 0 && errno == ENOENT && execrate(path, buf, sizeof(buf), 0))
	{
		errno = oerrno;
		fd = sysopen(buf, flags, mode);
	}
#endif
#if _win32_botch_copy
	if (fd >= 0 && fd < elementsof(exe) && strlen(path) < PATH_MAX &&
	    (flags & (O_CREAT|O_TRUNC)) == (O_CREAT|O_TRUNC) && (mode & 0111))
	{
		if (!suffix(path) && !fstat(fd, &st) && (exe[fd] || (exe[fd] = (Exe_test_t*)malloc(sizeof(Exe_test_t)))))
		{
			exe[fd]->test = -1;
			exe[fd]->ino = st.st_ino;
			strcpy(exe[fd]->path, path);
		}
		errno = oerrno;
	}
#endif
	va_end(ap);
	return fd;
}
Ejemplo n.º 7
0
/*
 *  announce a network service.
 */
int kannounce(char *addr, char *dir, size_t dirlen)
{
	int ctl, n, m;
	char buf[NETPATHLEN];
	char buf2[Maxpath];
	char netdir[NETPATHLEN];
	char naddr[Maxpath];
	char *cp;

	/*
	 *  translate the address
	 */
	if (nettrans(addr, naddr, sizeof(naddr), netdir, sizeof(netdir)) < 0)
		return -1;

	/*
	 * get a control channel
	 */
	ctl = sysopen(netdir, O_RDWR);
	if (ctl < 0)
		return -1;
	cp = strrchr(netdir, '/');
	*cp = 0;

	/*
	 *  find out which line we have
	 */
	n = snprintf(buf, sizeof(buf), "%.*s/", sizeof buf, netdir);
	m = sysread(ctl, &buf[n], sizeof(buf) - n - 1);
	if (m <= 0) {
		sysclose(ctl);
		return -1;
	}
	buf[n + m] = 0;

	/*
	 *  make the call
	 */
	n = snprintf(buf2, sizeof buf2, "announce %s", naddr);
	if (syswrite(ctl, buf2, n) != n) {
		sysclose(ctl);
		return -1;
	}

	/*
	 *  return directory etc.
	 */
	if (dir)
		strlcpy(dir, buf, dirlen);
	return ctl;
}
Ejemplo n.º 8
0
static int
magic(const char* path, int* ux)
{
	int		fd;
	int		r;
	int		n;
	int		m;
	int		oerrno;
#if CONVERT
	unsigned char	buf[512];
#else
	unsigned char	buf[2];
#endif

	oerrno = errno;
	if ((fd = sysopen(path, O_RDONLY, 0)) >= 0)
	{
#if CONVERT
		if (ux)
			n = sizeof(buf);
		else
#endif
			n = 2;
		r = (m = sysread(fd, buf, n)) >= 2 && (buf[1] == 0x5a && (buf[0] == 0x4c || buf[0] == 0x4d) || ux && buf[0] == '#' && buf[1] == '!' && (*ux = 1) && !(ux = 0)) ? 0 : -1;
		sysclose(fd);
		if (ux)
		{
			if (r)
				oerrno = ENOEXEC;
			else if (m > 61 && (n = buf[60] | (buf[61]<<8) + 92) < (m - 1))
				*ux = (buf[n] | (buf[n+1]<<8)) == 3;
			else
				*ux = 0;
		}
	}
	else if (!ux)
		r = -1;
	else if (errno == ENOENT)
	{
		oerrno = errno;
		r = -1;
	}
	else
	{
		r = 0;
		*ux = 0;
	}
	errno = oerrno;
	return r;
}
Ejemplo n.º 9
0
Biobuf*
opencopy(char *sender)
{
    int i;
    uint32_t h;
    char buf[512];
    Biobuf *b;

    h = 0;
    while(*sender)
        h = h*257 + *sender++;
    for(i = 0; i < 50; i++) {
        h += lrand();
        sprint(buf, "%s/%lud", copydir, h);
        b = sysopen(buf, "wlc", 0600);
        if(b)
            return b;
    }
    return 0;
}
Ejemplo n.º 10
0
Biobuf*
opendump(char *sender)
{
    int i;
    uint32_t h;
    char buf[512];
    Biobuf *b;
    char *cp;

    cp = ctime(time(0));
    cp[7] = 0;
    cp[10] = 0;
    if(cp[8] == ' ')
        sprint(buf, "%s/queue.dump/%s%c", SPOOL, cp+4, cp[9]);
    else
        sprint(buf, "%s/queue.dump/%s%c%c", SPOOL, cp+4, cp[8], cp[9]);
    cp = buf+strlen(buf);
    if(access(buf, 0) < 0 && sysmkdir(buf, 0777) < 0) {
        syslog(0, "smtpd", "couldn't dump mail from %s: %r", sender);
        return 0;
    }

    h = 0;
    while(*sender)
        h = h*257 + *sender++;
    for(i = 0; i < 50; i++) {
        h += lrand();
        sprint(cp, "/%lud", h);
        b = sysopen(buf, "wlc", 0644);
        if(b) {
            if(vflag)
                fprint(2, "saving in %s\n", buf);
            return b;
        }
    }
    return 0;
}
Ejemplo n.º 11
0
/*
 *  listen for an incoming call
 */
int klisten(char *dir, char *newdir, size_t newdirlen)
{
	int ctl, n, m;
	char buf[NETPATHLEN + 1];
	char *cp;

	/*
	 *  open listen, wait for a call
	 */
	snprintf(buf, sizeof buf, "%s/listen", dir);
	ctl = sysopen(buf, O_RDWR);
	if (ctl < 0)
		return -1;

	/*
	 *  find out which line we have
	 */
	strlcpy(buf, dir, sizeof(buf));
	cp = strrchr(buf, '/');
	*++cp = 0;
	n = cp - buf;
	m = sysread(ctl, cp, sizeof(buf) - n - 1);
	if (m <= 0) {
		sysclose(ctl);
		return -1;
	}
	buf[n + m] = 0;

	/*
	 *  return directory etc.
	 */
	if (newdir)
		strlcpy(newdir, buf, newdirlen);
	return ctl;

}
Ejemplo n.º 12
0
static void
_writembox(Mailbox *mb, Mlock *lk)
{
	Dir *d;
	Message *m;
	String *tmp;
	int mode, errs;
	Biobuf *b;

	tmp = s_copy(mb->path);
	s_append(tmp, ".tmp");

	/*
	 * preserve old files permissions, if possible
	 */
	d = dirstat(mb->path);
	if(d != nil){
		mode = d->mode&0777;
		free(d);
	} else
		mode = MBOXMODE;

	sysremove(s_to_c(tmp));
	b = sysopen(s_to_c(tmp), "alc", mode);
	if(b == 0){
		fprint(2, "can't write temporary mailbox %s: %r\n", s_to_c(tmp));
		return;
	}

	logmsg("writing new mbox", nil);
	errs = 0;
	for(m = mb->root->part; m != nil; m = m->next){
		if(lk != nil)
			syslockrefresh(lk);
		if(m->deleted)
			continue;
		logmsg("writing", m);
		if(Bwrite(b, m->start, m->end - m->start) < 0)
			errs = 1;
		if(Bwrite(b, "\n", 1) < 0)
			errs = 1;
	}
	logmsg("wrote new mbox", nil);

	if(sysclose(b) < 0)
		errs = 1;

	if(errs){
		fprint(2, "error writing temporary mail file\n");
		s_free(tmp);
		return;
	}

	sysremove(mb->path);
	if(sysrename(s_to_c(tmp), mb->path) < 0)
		fprint(2, "%s: can't rename %s to %s: %r\n", argv0,
			s_to_c(tmp), mb->path);
	s_free(tmp);
	if(mb->d != nil)
		free(mb->d);
	mb->d = dirstat(mb->path);
}
Ejemplo n.º 13
0
static int call(char *clone, char *dest, DS * ds)
{
	int fd, cfd, n, retval;
	char *name, *data, *err, *p;

	name = kmalloc(Maxpath, KMALLOC_WAIT);
	data = kmalloc(Maxpath, KMALLOC_WAIT);
	err = kmalloc(ERRMAX, KMALLOC_WAIT);

	cfd = sysopen(clone, O_RDWR);
	if (cfd < 0) {
		kerrstr(err, ERRMAX);
		set_errstr("%s (%s)", err, clone);
		retval = -1;
		goto out;
	}

	/* get directory name */
	n = sysread(cfd, name, Maxpath - 1);
	if (n < 0) {
		kerrstr(err, ERRMAX);
		sysclose(cfd);
		set_errstr("read %s: %s", clone, err);
		retval = -1;
		goto out;
	}
	name[n] = 0;
	for (p = name; *p == ' '; p++) ;
	snprintf(name, Maxpath, "%ld", strtoul(p, 0, 0));
	p = strrchr(clone, '/');
	*p = 0;
	if (ds->dir)
		snprintf(ds->dir, NETPATHLEN, "%s/%s", clone, name);
	snprintf(data, Maxpath, "%s/%s/data", clone, name);

	/* connect */
	if (ds->local)
		snprintf(name, Maxpath, "connect %s %s", dest, ds->local);
	else
		snprintf(name, Maxpath, "connect %s", dest);
	if (syswrite(cfd, name, strlen(name)) < 0) {
		err[0] = 0;
		kerrstr(err, ERRMAX);
		sysclose(cfd);
		set_errstr("%s (%s)", err, name);
		retval = -1;
		goto out;
	}

	/* open data connection */
	fd = sysopen(data, O_RDWR);
	if (fd < 0) {
		err[0] = 0;
		kerrstr(err, ERRMAX);
		set_errstr("%s (%s)", err, data);
		sysclose(cfd);
		retval = -1;
		goto out;
	}
	if (ds->cfdp)
		*ds->cfdp = cfd;
	else
		sysclose(cfd);
	retval = fd;
out:
	kfree(name);
	kfree(data);
	kfree(err);

	return retval;
}
Ejemplo n.º 14
0
static void
syscall_handler (struct intr_frame* frame) 
{
	// -------- System Call Handler Overview -------- 
	// Get system call number
	// switch statement using system call number
	// collect arguments for system call function if necessary
	// call system call function
	// set frame->eax to return value if necessary
	// ----------------------------------------------
	uintptr_t* kpaddr_sp = (uintptr_t*) frame->esp;
	int syscall_num = -1;
	if(check_uptr(kpaddr_sp))
		syscall_num = next_value(&kpaddr_sp);
	else
		sysexit(-1);

	switch(syscall_num)
	{
		case SYS_HALT:                   
			{
				// Terminates Pintos
				shutdown_power_off();
			}
			break;
		case SYS_EXIT:                 
			{
				uintptr_t status = -1;
				if(check_uptr(kpaddr_sp))
					status = next_value(&kpaddr_sp);
				sysexit(status);
			}
			break;
		case SYS_EXEC:  //pid_t exec (const char *file);
			{
				const char* file =  next_charptr(&kpaddr_sp);
				if(file == NULL)
					sysexit(-1);

				unsigned len = strlen(file);
				if(!check_buffer(file, len))
					sysexit(-1);
				else
					sysexec(frame, file);
			}
			break;
		case SYS_WAIT:  //int wait (pid_t);
			{
				uintptr_t childid = -1;
				if(check_uptr(kpaddr_sp))
					childid = next_value(&kpaddr_sp);
				else
					sysexit(childid);
			
				int retval = process_wait((tid_t) childid);
				frame->eax = retval;
			}
			break;
		case SYS_CREATE:	//bool create (const char *file, unsigned initial_size);
			{
				const char* file =  next_charptr(&kpaddr_sp);
				if(file == NULL)
					sysexit(-1);

				unsigned len = strlen(file);
				if(!check_buffer(file, len))
					sysexit(-1);

				uintptr_t size = 0;
				if(check_uptr(kpaddr_sp))
					size = next_value(&kpaddr_sp);
				else
					sysexit(-1);

				syscreate(frame, file, size);
			}
			break;
		case SYS_REMOVE:	//bool remove (const char *file);
			{
				const char* file =  next_charptr(&kpaddr_sp);
				if(file == NULL)
					sysexit(-1);

				unsigned len = strlen(file);
				if(!check_buffer(file, len))
					sysexit(-1);

				sysremove(frame, file);
			}
			break;
		case SYS_OPEN:          
			{
				//int open (const char *file);
				const char* file =  next_charptr(&kpaddr_sp);
				if(file == NULL)
					sysexit(-1);

				unsigned len = strlen(file);
				if(!check_buffer(file, len))
					sysexit(-1);

	      		sysopen(frame, file);
			}
			break;
		case SYS_FILESIZE:     
			{
				//int filesize (int fd);
	      		int fd = 0;
	      		if (check_uptr(kpaddr_sp))
					fd = (int) next_value(&kpaddr_sp);
	      		else
					sysexit(-1);

	      		sysfilesize(frame, fd);
			}
			break;
		case SYS_READ:        
			{
				//int read (int fd, void *buffer, unsigned length);
				int fd = 0;
				if (check_uptr(kpaddr_sp))
					fd = (int) next_value(&kpaddr_sp);
				else
					sysexit(-1);

				const char* file =  next_charptr(&kpaddr_sp);
				if(file == NULL)
					sysexit(-1);

				unsigned len = strlen(file);
				if(!check_buffer(file, len))
					sysexit(-1);

				unsigned length = 0;
				if (check_uptr(kpaddr_sp))
					length = (unsigned) next_value(&kpaddr_sp);
				else
					sysexit(-1);

				sysread(frame, fd, (void*) file, length);
			}
			break;
		case SYS_WRITE:      
			{
				//int write (int fd, const void *buffer, unsigned length);
				uintptr_t fd = 0;
				if(check_uptr(kpaddr_sp))
					fd = next_value(&kpaddr_sp);
				else
					sysexit(-1);

				const char* file =  next_charptr(&kpaddr_sp);
				if(file == NULL)
					sysexit(-1);

				unsigned len = strlen(file);
				if(!check_buffer(file, len))
					sysexit(-1);

				uintptr_t length = 0;
				if(check_uptr(kpaddr_sp))
					length = next_value(&kpaddr_sp);
				else
					sysexit(-1);

				if(fd == CONSOLEWRITE) // Write to Console
				{
					while(length > 0)
					{
						if(length > MAX_SIZE)
						{
							putbuf (file, MAX_SIZE);
							file += MAX_SIZE;
							length -= MAX_SIZE;
						}
						else
						{
							putbuf (file, length);
							length = 0;
						}
					}
				}
				else
				{
					syswrite(frame, fd, file, length);
				}
			}
			break;
		case SYS_SEEK:
			{
				//void seek (int fd, unsigned position);
				int fd = 0;
				if (check_uptr(kpaddr_sp))
					fd = (int) next_value(&kpaddr_sp);
				else
					sysexit(-1);

				unsigned position = 0;
				if (check_uptr(kpaddr_sp))
					position = (unsigned) next_value(&kpaddr_sp);
				else
					sysexit(-1);

				sysseek(fd, position);
			}
			break;
		case SYS_TELL:
			{
				//unsigned tell (int fd);
				int fd = 0;
				if (check_uptr(kpaddr_sp))
					fd = (int) next_value(&kpaddr_sp);
				else
					sysexit(-1);

				systell(frame, fd);
			}
			break;
		case SYS_CLOSE:    
			{
				//void close (int fd);
				int fd = 0;
				if (check_uptr(kpaddr_sp))
					fd = (int) next_value(&kpaddr_sp);
				else
					sysexit(-1);

				sysclose(fd);
			}
			break;
		default:
			{
				printf("Unrecognized System Call\n");
				sysexit(-1);
			}
			break;
	}
}
Ejemplo n.º 15
0
static int openSyscall(int* args) {
    return sysopen((const char*)args[0], (Caps)args[1]);
}
Ejemplo n.º 16
0
Archivo: runq.c Proyecto: 99years/plan9
/*
 *  try a message
 */
void
dofile(Dir *dp)
{
	Dir *d;
	int dfd, ac, dtime, efd, pid, i, etime;
	char *buf, *cp, **av;
	Waitmsg *wm;
	Biobuf *b;
	Mlock *l = nil;

	if(debug)
		fprint(2, "dofile %s\n", dp->name);
	/*
	 *  if no data file or empty control or data file, just clean up
	 *  the empty control file must be 15 minutes old, to minimize the
	 *  chance of a race.
	 */
	d = dirstat(file(dp->name, 'D'));
	if(d == nil){
		syslog(0, runqlog, "no data file for %s", dp->name);
		remmatch(dp->name);
		return;
	}
	if(dp->length == 0){
		if(time(0)-dp->mtime > 15*60){
			syslog(0, runqlog, "empty ctl file for %s", dp->name);
			remmatch(dp->name);
		}
		return;
	}
	dtime = d->mtime;
	free(d);

	/*
	 *  retry times depend on the age of the errors file
	 */
	if(!Eflag && (d = dirstat(file(dp->name, 'E'))) != nil){
		etime = d->mtime;
		free(d);
		if(etime - dtime < 15*60){
			/* up to the first 15 minutes, every 30 seconds */
			if(time(0) - etime < 30)
				return;
		} else if(etime - dtime < 60*60){
			/* up to the first hour, try every 15 minutes */
			if(time(0) - etime < 15*60)
				return;
		} else {
			/* after the first hour, try once an hour */
			if(time(0) - etime < 60*60)
				return;
		}

	}

	/*
	 *  open control and data
	 */
	b = sysopen(file(dp->name, 'C'), "rl", 0660);
	if(b == 0) {
		if(debug)
			fprint(2, "can't open %s: %r\n", file(dp->name, 'C'));
		return;
	}
	dfd = open(file(dp->name, 'D'), OREAD);
	if(dfd < 0){
		if(debug)
			fprint(2, "can't open %s: %r\n", file(dp->name, 'D'));
		Bterm(b);
		sysunlockfile(Bfildes(b));
		return;
	}

	/*
	 *  make arg list
	 *	- read args into (malloc'd) buffer
	 *	- malloc a vector and copy pointers to args into it
	 */
	buf = malloc(dp->length+1);
	if(buf == 0){
		warning("buffer allocation", 0);
		Bterm(b);
		sysunlockfile(Bfildes(b));
		close(dfd);
		return;
	}
	if(Bread(b, buf, dp->length) != dp->length){
		warning("reading control file %s\n", dp->name);
		Bterm(b);
		sysunlockfile(Bfildes(b));
		close(dfd);
		free(buf);
		return;
	}
	buf[dp->length] = 0;
	av = malloc(2*sizeof(char*));
	if(av == 0){
		warning("argv allocation", 0);
		close(dfd);
		free(buf);
		Bterm(b);
		sysunlockfile(Bfildes(b));
		return;
	}
	for(ac = 1, cp = buf; *cp; ac++){
		while(isspace(*cp))
			*cp++ = 0;
		if(*cp == 0)
			break;

		av = realloc(av, (ac+2)*sizeof(char*));
		if(av == 0){
			warning("argv allocation", 0);
			close(dfd);
			free(buf);
			Bterm(b);
			sysunlockfile(Bfildes(b));
			return;
		}
		av[ac] = cp;
		while(*cp && !isspace(*cp)){
			if(*cp++ == '"'){
				while(*cp && *cp != '"')
					cp++;
				if(*cp)
					cp++;
			}
		}
	}
	av[0] = cmd;
	av[ac] = 0;

	if(!Eflag &&time(0) - dtime > giveup){
		if(returnmail(av, dp->name, "Giveup") != 0)
			logit("returnmail failed", dp->name, av);
		remmatch(dp->name);
		goto done;
	}

	for(i = 0; i < nbad; i++){
		if(strcmp(av[3], badsys[i]) == 0)
			goto done;
	}

	/*
	 * Ken's fs, for example, gives us 5 minutes of inactivity before
	 * the lock goes stale, so we have to keep reading it.
 	 */
	l = keeplockalive(file(dp->name, 'C'), Bfildes(b));

	/*
	 *  transfer
	 */
	pid = fork();
	switch(pid){
	case -1:
		sysunlock(l);
		sysunlockfile(Bfildes(b));
		syslog(0, runqlog, "out of procs");
		exits(0);
	case 0:
		if(debug) {
			fprint(2, "Starting %s", cmd);
			for(ac = 0; av[ac]; ac++)
				fprint(2, " %s", av[ac]);
			fprint(2, "\n");
		}
		logit("execing", dp->name, av);
		close(0);
		dup(dfd, 0);
		close(dfd);
		close(2);
		efd = open(file(dp->name, 'E'), OWRITE);
		if(efd < 0){
			if(debug) syslog(0, "runq", "open %s as %s: %r", file(dp->name,'E'), getuser());
			efd = create(file(dp->name, 'E'), OWRITE, 0666);
			if(efd < 0){
				if(debug) syslog(0, "runq", "create %s as %s: %r", file(dp->name, 'E'), getuser());
				exits("could not open error file - Retry");
			}
		}
		seek(efd, 0, 2);
		exec(cmd, av);
		error("can't exec %s", cmd);
		break;
	default:
		for(;;){
			wm = wait();
			if(wm == nil)
				error("wait failed: %r", "");
			if(wm->pid == pid)
				break;
			free(wm);
		}
		if(debug)
			fprint(2, "wm->pid %d wm->msg == %s\n", wm->pid, wm->msg);

		if(wm->msg[0]){
			if(debug)
				fprint(2, "[%d] wm->msg == %s\n", getpid(), wm->msg);
			syslog(0, runqlog, "message: %s\n", wm->msg);
			if(strstr(wm->msg, "Ignore") != nil){
				/* fix for fish/chips, leave message alone */
				logit("ignoring", dp->name, av);
			}else if(!Rflag && strstr(wm->msg, "Retry")==0){
				/* return the message and remove it */
				if(returnmail(av, dp->name, wm->msg) != 0)
					logit("returnmail failed", dp->name, av);
				remmatch(dp->name);
			} else {
				/* add sys to bad list and try again later */
				nbad++;
				badsys = realloc(badsys, nbad*sizeof(char*));
				badsys[nbad-1] = strdup(av[3]);
			}
		} else {
			/* it worked remove the message */
			remmatch(dp->name);
		}
		free(wm);

	}
done:
	if (l)
		sysunlock(l);
	Bterm(b);
	sysunlockfile(Bfildes(b));
	free(buf);
	free(av);
	close(dfd);
}
Ejemplo n.º 17
0
static int csdial(DS * ds)
{
	int n, fd, rv = -1;
	char *p, *buf, *clone, *err, *besterr;

	buf = kmalloc(Maxstring, KMALLOC_WAIT);
	clone = kmalloc(Maxpath, KMALLOC_WAIT);
	err = kmalloc(ERRMAX, KMALLOC_WAIT);
	besterr = kmalloc(ERRMAX, KMALLOC_WAIT);
	/*
	 *  open connection server
	 */
	snprintf(buf, Maxstring, "%s/cs", ds->netdir);
	fd = sysopen(buf, O_RDWR);
	if (fd < 0) {
		/* no connection server, don't translate */
		snprintf(clone, Maxpath, "%s/%s/clone", ds->netdir, ds->proto);
		rv = call(clone, ds->rem, ds);
		goto out;
	}

	/*
	 *  ask connection server to translate
	 */
	snprintf(buf, Maxstring, "%s!%s", ds->proto, ds->rem);
	if (syswrite(fd, buf, strlen(buf)) < 0) {
		kerrstr(err, ERRMAX);
		sysclose(fd);
		set_errstr("%s (%s)", err, buf);
		goto out;
	}

	/*
	 *  loop through each address from the connection server till
	 *  we get one that works.
	 */
	*besterr = 0;
	strlcpy(err, errno_to_string(ECONNRESET), ERRMAX);
	sysseek(fd, 0, 0);
	while ((n = sysread(fd, buf, Maxstring - 1)) > 0) {
		buf[n] = 0;
		p = strchr(buf, ' ');
		if (p == 0)
			continue;
		*p++ = 0;
		rv = call(buf, p, ds);
		if (rv >= 0)
			break;
		err[0] = 0;
		kerrstr(err, ERRMAX);
		if (strstr(err, "does not exist") == 0)
			memmove(besterr, err, ERRMAX);
	}
	sysclose(fd);

	if (rv < 0 && *besterr)
		kerrstr(besterr, ERRMAX);
	else
		kerrstr(err, ERRMAX);
out:
	kfree(buf);
	kfree(clone);
	kfree(err);
	kfree(besterr);
	return rv;
}