Exemple #1
0
static
void
dovalidate(void)
{
	const char *name;
	int fd, i, mykeys, keys_done, keys_to_do;
	int key, smallest, largest;

	name = PATH_SORTED;
	fd = doopen(name, O_RDONLY, 0);

	mykeys = getmykeys();
	seekmyplace(name, fd);

	smallest = RANDOM_MAX;
	largest = 0;

	keys_done = 0;
	while (keys_done < mykeys) {
		keys_to_do = mykeys - keys_done;
		if (keys_to_do > WORKNUM) {
			keys_to_do = WORKNUM;
		}

		doexactread(name, fd, workspace, keys_to_do * sizeof(int));

		for (i=0; i<keys_to_do; i++) {
			key = workspace[i];

			if (key < 0) {
				complain("%s: found negative key", name);
				exit(1);
			}
			if (key == 0) {
				complain("%s: found zero key", name);
				exit(1);
			}
			if (key >= RANDOM_MAX) {
				complain("%s: found too-large key", name);
				exit(1);
			}

			if (key < smallest) {
				smallest = key;
			}
			if (key > largest) {
				largest = key;
			}
		}

		keys_done += keys_to_do;
	}
	doclose(name, fd);

	name = validname(me);
	fd = doopen(name, O_WRONLY|O_CREAT|O_TRUNC, 0664);
	dowrite(name, fd, &smallest, sizeof(smallest));
	dowrite(name, fd, &largest, sizeof(largest));
	doclose(name, fd);
}
Exemple #2
0
static
void
bin(void)
{
	int infd, outfds[numprocs];
	const char *name;
	int i, mykeys, keys_done, keys_to_do;
	int key, pivot, binnum;

	infd = doopen(PATH_KEYS, O_RDONLY, 0);

	mykeys = getmykeys();
	seekmyplace(PATH_KEYS, infd);

	for (i=0; i<numprocs; i++) {
		name = binname(me, i);
		outfds[i] = doopen(name, O_WRONLY|O_CREAT|O_TRUNC, 0664);
	}

	pivot = (RANDOM_MAX / numprocs);

	keys_done = 0;
	while (keys_done < mykeys) {
		keys_to_do = mykeys - keys_done;
		if (keys_to_do > WORKNUM) {
			keys_to_do = WORKNUM;
		}

		doexactread(PATH_KEYS, infd, workspace,
			    keys_to_do * sizeof(int));

		for (i=0; i<keys_to_do; i++) {
			key = workspace[i];

			binnum = key / pivot;
			if (key <= 0) {
				complainx("proc %d: garbage key %d", me, key);
				key = 0;
			}
			assert(binnum >= 0);
			assert(binnum < numprocs);
			dowrite("bin", outfds[binnum], &key, sizeof(key));
		}

		keys_done += keys_to_do;
	}
	doclose(PATH_KEYS, infd);

	for (i=0; i<numprocs; i++) {
		doclose(binname(me, i), outfds[i]);
	}
}
Exemple #3
0
static
void
assemble(void)
{
	off_t mypos;
	int i, fd;
	const char *args[3];

	mypos = 0;
	for (i=0; i<me; i++) {
		mypos += getsize(mergedname(i));
	}

	fd = doopen(PATH_SORTED, O_WRONLY, 0);
	dolseek(PATH_SORTED, fd, mypos, SEEK_SET);

	if (dup2(fd, STDOUT_FILENO) < 0) {
		complain("dup2");
		exit(1);
	}

	doclose(PATH_SORTED, fd);

	args[0] = "cat";
	args[1] = mergedname(me);
	args[2] = NULL;
	execv("/bin/cat", (char **) args);
	complain("/bin/cat: exec");
	exit(1);
}
Exemple #4
0
static
void
docreate(const char *file, const char *sizespec, int doforce)
{
    int fd;
    off_t size;

    if (!doforce) {
        fd = open(file, O_RDONLY);
        if (fd >= 0) {
            fprintf(stderr, "disk161: %s: %s\n", file,
                    strerror(EEXIST));
            exit(1);
        }
    }

    fd = doopen(file, O_RDWR|O_CREAT|O_TRUNC, 0664);
    doflock(file, fd, LOCK_EX);
    size = getsize(sizespec);
    checksize(size);
    dotruncate(file, fd, HEADERSIZE + size);
    writeheader(file, fd);
    doflock(file, fd, LOCK_UN);
    close(fd);
}
Exemple #5
0
static
void
sortbins(void)
{
	const char *name;
	int i, fd;
	off_t binsize;

	for (i=0; i<numprocs; i++) {
		name = binname(me, i);
		binsize = getsize(name);
		if (binsize % sizeof(int) != 0) {
			complainx("%s: bin size %ld no good", name,
				  (long) binsize);
			exit(1);
		}
		if (binsize > (off_t) sizeof(workspace)) {
			complainx("proc %d: %s: bin too large", me, name);
			exit(1);
		}

		fd = doopen(name, O_RDWR, 0);
		doexactread(name, fd, workspace, binsize);

		sortints(workspace, binsize/sizeof(int));

		dolseek(name, fd, 0, SEEK_SET);
		dowrite(name, fd, workspace, binsize);
		doclose(name, fd);
	}
}
Exemple #6
0
/*
 *  the database entry in 'file' indicates the list of files
 *  that makeup the database.  Open each one and search in
 *  the same order.
 */
struct ndb*
ndbopen(char *file)
{

	struct ndb *db, *first, *last;
	struct ndbs s;
	struct ndbtuple *t, *nt;

	if(file == 0)
		file = deffile;
	db = doopen(file);
	if(db == 0) {
		return 0;
	}
	first = last = db;
	t = ndbsearch(db, &s, "database", "");
	fseek(db->b, 0, 0);
	if(t == 0) {
		return db;
	}
	for(nt = t; nt; nt = nt->entry){
		if(strcmp(nt->attr, "file") != 0)
			continue;
		if(strcmp(nt->val, file) == 0){
			/* default file can be reordered in the list */
			if(first->next == 0)
				continue;
			if(strcmp(first->file, file) == 0){
				db = first;
				first = first->next;
				last->next = db;
				db->next = 0;
				last = db;
			}
			continue;
		}
		db = doopen(nt->val);
		if(db == 0)
			continue;
		last->next = db;
		last = db;
	}
	ndbfree(t);
	return first;
}
Exemple #7
0
static
void
docreate(const char *path)
{
	int fd;

	fd = doopen(path, O_WRONLY|O_CREAT|O_TRUNC, 0664);
	doclose(path, fd);
}
Exemple #8
0
static
void
cat(void)
{
	pid_t pid;
	int rfd, wfd, result, status;
	const char *args[2];

	rfd = doopen(INFILE, O_RDONLY);
	wfd = doopen(OUTFILE, O_WRONLY|O_CREAT|O_TRUNC);

	pid = fork();
	if (pid < 0) {
		err(1, "fork");
	}

	if (pid == 0) {
		/* child */
		dodup2(rfd, STDIN_FILENO, INFILE);
		dodup2(wfd, STDOUT_FILENO, OUTFILE);
		doclose(rfd, INFILE);
		doclose(wfd, OUTFILE);
		args[0] = "cat";
		args[1] = NULL;
		execv(PATH_CAT, (char **)args);
		warn("%s: execv", PATH_CAT);
		_exit(1);
	}

	/* parent */
	doclose(rfd, INFILE);
	doclose(wfd, OUTFILE);

	result = waitpid(pid, &status, 0);
	if (result == -1) {
		err(1, "waitpid");
	}
	if (WIFSIGNALED(status)) {
		errx(1, "pid %d: Signal %d", (int)pid, WTERMSIG(status));
	}
	if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
		errx(1, "pid %d: Exit %d", (int)pid, WEXITSTATUS(status));
	}
}
Exemple #9
0
static
void
randomize(void)
{
	int fd;

	fd = doopen(PATH_RANDOM, O_RDONLY, 0);
	doexactread(PATH_RANDOM, fd, &randomseed, sizeof(randomseed));
	doclose(PATH_RANDOM, fd);
}
Exemple #10
0
static
void
doresize(const char *file, const char *sizespec)
{
    enum { M_SET, M_PLUS, M_MINUS } mode;
    off_t oldsize, newsize;
    int fd;

    if (*sizespec == '+') {
        sizespec++;
        mode = M_PLUS;
    }
    else if (*sizespec == '-') {
        sizespec++;
        mode = M_MINUS;
    }
    else {
        mode = M_SET;
    }

    newsize = getsize(sizespec);
    fd = doopen(file, O_RDWR, 0);
    doflock(file, fd, LOCK_EX);
    checkheader(file, fd);
    oldsize = filesize(file, fd);
    oldsize -= HEADERSIZE;
    switch (mode) {
    case M_SET:
        break;
    case M_PLUS:
        if (oldsize + newsize < oldsize) {
            /* overflow */
            fprintf(stderr, "+%s: Result too large\n", sizespec);
            exit(1);
        }
        newsize = oldsize + newsize;
        break;
    case M_MINUS:
        if (oldsize < newsize) {
            /* underflow */
            fprintf(stderr, "-%s: Result too small\n", sizespec);
            exit(1);
        }
        newsize = oldsize - newsize;
        break;
    }

    checksize(newsize);
    dotruncate(file, fd, HEADERSIZE + newsize);
    doflock(file, fd, LOCK_UN);
    close(fd);
}
Exemple #11
0
static
void
validate(void)
{
	int smallest, largest, prev_largest;
	int i, fd;
	const char *name;

	doforkall("Validation", dovalidate);
	checksize_valid();

	prev_largest = 1;

	for (i=0; i<numprocs; i++) {
		name = validname(i);
		fd = doopen(name, O_RDONLY, 0);

		doexactread(name, fd, &smallest, sizeof(int));
		doexactread(name, fd, &largest, sizeof(int));

		if (smallest < 1) {
			complainx("Validation: block %d: bad SMALLEST", i);
			exit(1);
		}
		if (largest >= RANDOM_MAX) {
			complainx("Validation: block %d: bad LARGEST", i);
			exit(1);
		}
		if (smallest > largest) {
			complainx("Validation: block %d: SMALLEST > LARGEST",
				  i);
			exit(1);
		}

		if (smallest < prev_largest) {
			complain("Validation: block %d smallest key %d",
				 i, smallest);
			complain("Validation: previous block largest key %d",
				 prev_largest);
			complain("Validation failed");
			exit(1);
		}
	}


	for (i=0; i<numprocs; i++) {
		doremove(validname(i));
	}
}
Exemple #12
0
static
off_t
getsize(const char *path)
{
	struct stat buf;
	int fd;
	static int no_stat, no_fstat;

	if (!no_stat) {
		if (stat(path, &buf) == 0) {
			return buf.st_size;
		}
		if (errno != ENOSYS) {
			complain("%s: stat", path);
			exit(1);
		}
		/* Avoid further "Unknown syscall 81" messages */
		no_stat = 1;
	}

	fd = doopen(path, O_RDONLY, 0);
	if (!no_fstat) {
		if (fstat(fd, &buf) == 0) {
			close(fd);
			return buf.st_size;
		}
		if (errno != ENOSYS) {
			complain("%s: stat", path);
			exit(1);
		}
		/* Avoid further "Unknown syscall 82" messages */
		no_fstat = 1;
	}

	/* otherwise, lseek */
	if (lseek(fd, 0, SEEK_END) >= 0) {
		buf.st_size = lseek(fd, 0, SEEK_CUR);
		if (buf.st_size >= 0) {
			return buf.st_size;
		}
	}
	complain("%s: getting file size with lseek", path);
	close(fd);
	exit(1);
}
Exemple #13
0
void writefile(const char *to_write, const char *from, const char *to,
				const char *mode)
{
	int ofd;
	if (strcmp("-", to_write) == 0) {
		ofd = 1;	// stdout
	} else {
		ofd = doopen(to_write, mode);
	}
	ssize_t towrite = to - from;
	ssize_t written = write(ofd, from, towrite);
	if (written != towrite) {
		fprintf(stderr, "Expected to write %li bytes but %li written\n",
				towrite, written);
		perror(to_write);
		exit(EXIT_FAILURE);
	}
	if (ofd != 1) close(ofd);
} // writefile()
Exemple #14
0
static
void
mkfile(void)
{
	int fd;
	ssize_t r;

	fd = doopen(INFILE, O_WRONLY|O_CREAT|O_TRUNC);

	r = write(fd, slogan, strlen(slogan));
	if (r < 0) {
		err(1, "%s: write", INFILE);
	}
	if ((size_t)r != strlen(slogan)) {
		errx(1, "%s: write: Short count (got %zd, expected %zu)",
		     INFILE, r, strlen(slogan));
	}

	doclose(fd, INFILE);
}
Exemple #15
0
static
unsigned long
checksum_file(const char *path)
{
	int fd;
	char buf[512];
	size_t count, i;
	unsigned long sum = 0;

	fd = doopen(path, O_RDONLY, 0);

	while ((count = doread(path, fd, buf, sizeof(buf))) > 0) {
		for (i=0; i<count; i++) {
			sum += (unsigned char) buf[i];
		}
	}

	doclose(path, fd);

	return sum;
}
Exemple #16
0
static
void
genkeys_sub(void)
{
	int fd, i, mykeys, keys_done, keys_to_do, value;

	fd = doopen(PATH_KEYS, O_WRONLY, 0);

	mykeys = getmykeys();
	seekmyplace(PATH_KEYS, fd);

	srandom(seeds[me]);
	keys_done = 0;
	while (keys_done < mykeys) {
		keys_to_do = mykeys - keys_done;
		if (keys_to_do > WORKNUM) {
			keys_to_do = WORKNUM;
		}

		for (i=0; i<keys_to_do; i++) {
			value = random();

			// check bounds of value
			assert(value >= 0);
			assert(value <= RANDOM_MAX);

			// do not allow the value to be zero or RANDOM_MAX
			while (value == 0 || value == RANDOM_MAX) {
				value = random();
			}

			workspace[i] = value;
		}

		dowrite(PATH_KEYS, fd, workspace, keys_to_do*sizeof(int));
		keys_done += keys_to_do;
	}

	doclose(PATH_KEYS, fd);
}
Exemple #17
0
static
void
doinfo(const char *file)
{
    int fd;
    struct stat st;
    long long amt;

    fd = doopen(file, O_RDWR, 0);
    checkheader(file, fd);
    dofstat(file, fd, &st);

    amt = st.st_size - HEADERSIZE;
    printf("%s size %lld bytes (%lld sectors; %lldK; %lldM)\n", file,
           amt, amt / SECTORSIZE, amt / 1024, amt / (1024*1024));


    amt = st.st_blocks * 512LL;
    printf("%s spaceused %lld bytes (%lld sectors; %lldK; %lldM)\n", file,
           amt, amt / SECTORSIZE, amt / 1024, amt / (1024*1024));

    close(fd);
}
Exemple #18
0
static
void
chkfile(void)
{
	char buf[256];
	ssize_t r;
	int fd;

	fd = doopen(OUTFILE, O_RDONLY);

	r = read(fd, buf, sizeof(buf));
	if (r < 0) {
		err(1, "%s: read", OUTFILE);
	}
	if (r == 0) {
		errx(1, "%s: read: Unexpected EOF", OUTFILE);
	}
	if ((size_t)r != strlen(slogan)) {
		errx(1, "%s: read: Short count (got %zd, expected %zu)",
		     OUTFILE, r, strlen(slogan));
	}

	doclose(fd, OUTFILE);
}
Exemple #19
0
/*
 *	Print mail entries
 */
void
printmail()
{
	static char pn[] = "printmail";
	int	flg, curlet, showlet, k, print, aret, stret, rc;
	int	nsmbox = 0;	/* 1 ==> mailbox is in non-standard place */
	int	sav_j = -1;
	char	*p, *getarg();
	struct	stat stbuf;
	struct	stat *stbufp;
	int ttyf = isatty(1) ? TTY : ORDINARY;
	char	readbuf[LSIZE];	/* holds user's response in interactive mode */
	char	*resp;
	gid_t	savedegid;

	stbufp = &stbuf;

	/*
	 *	create working directory mbox name
	 */
	if ((hmbox = malloc(strlen(home) + strlen(mbox) + 1)) == NULL) {
		errmsg(E_MBOX, "");
		return;
	}
	cat(hmbox, home, mbox);

	/*
	 *	If we are not using an alternate mailfile, then get
	 *	the $MAIL value and build the filename for the mailfile.
	 *	If $MAIL is set, but is NOT the 'standard' place, then
	 *	use it but set flgf to circumvent :saved processing.
	 */
	if (!flgf) {
		if ((p = malloc(strlen(maildir) + strlen(my_name) + 1))
								== NULL) {
			errmsg(E_MEM, "");
			return;
		}
		cat(p, maildir, my_name);
		if (((mailfile = getenv("MAIL")) == NULL) ||
		    (strlen(mailfile) == 0)) {
			/* $MAIL not set, use standard path to mailfile */
			mailfile = p;
		} else {
			if (strcmp(mailfile, p) != 0) {
			    flgf = 1;
			    nsmbox = 1;
			    Dout(pn, 0, "$MAIL ('%s') != standard path\n",
				mailfile);
			    Dout("", 0, "\tSetting flgf to 1.\n");
			}
			free(p);
		}
	}

	/*
	 *	Get ACCESS and MODIFICATION times of mailfile BEFORE we
	 *	use it. This allows us to put them back when we are
	 *	done. If we didn't, the shell would think NEW mail had
	 *	arrived since the file times would have changed.
	 */
	stret = CERROR;
	if (access(mailfile, A_EXIST) == A_OK) {
		if ((stret = stat(mailfile, stbufp)) != A_OK) {
			errmsg(E_FILE, "Cannot stat mailfile");
			return;
		}
		mf_gid = stbufp->st_gid;
		mf_uid = stbufp->st_uid;
		utimep->actime = stbufp->st_atime;
		utimep->modtime = stbufp->st_mtime;
		file_size = stbufp->st_size;
	}

	/* Open the file as the real gid */
	savedegid = getegid();
	(void) setegid(getgid());
	malf = fopen(mailfile, "r");
	(void) setegid(savedegid);
	/*
	 *	stat succeeded, but we cannot access the mailfile
	 */
	if (stret == CSUCCESS && malf == NULL) {
		char buf[MAXFILENAME+50];
		(void) snprintf(buf, sizeof (buf),
		    "Invalid permissions on %s", mailfile);
		errmsg(E_PERM, buf);
		return;
	} else
	/*
	 *	using an alternate mailfile, but we failed on access
	 */
	if (!nsmbox && flgf && (malf == NULL)) {
		errmsg(E_FILE, "Cannot open mailfile");
		return;
	}
	/*
	 *	we failed to access OR the file is empty
	 */
	else if ((malf == NULL) || (stbuf.st_size == 0)) {
		if (!flge && !flgE) {
			printf("No mail.\n");
		}
		error = E_FLGE;
		Dout(pn, 0, "error set to %d\n", error);
		return;
	}
	if (flge)
		return;

	if (flgE) {
		if (utimep->modtime < utimep->actime) {
			error = E_FLGE_OM;
			Dout(pn, 0, "error set to %d\n", error);
		}
		return;
	}
	/*
	 *	Secure the mailfile to guarantee integrity
	 */
	lock(my_name);

	/*
	 *	copy mail to temp file and mark each letter in the
	 *	let array --- mailfile is still locked !!!
	 */
	mktmp();
	copymt(malf, tmpf);
	onlet = nlet;
	fclose(malf);
	fclose(tmpf);
	unlock();	/* All done, OK to unlock now */
	tmpf = doopen(lettmp, "r+", E_TMP);
	changed = 0;
	print = 1;
	curlet = 0;
	while (curlet < nlet) {
		/*
		 *	reverse order ?
		 */
		showlet = flgr ? curlet : nlet - curlet - 1;

		if (setjmp(sjbuf) == 0 && print != 0) {
				/* -h says to print the headers first */
				if (flgh) {
					gethead(showlet, 0);
					flgh = 0;	/* Only once */
					/* set letter # to invalid # */
					curlet--;
					showlet =
					    flgr ? curlet : nlet - curlet - 1;
				} else {
					if (showlet != sav_j) {
						/* Looking at new message. */
						/* Reset flag to override */
						/* non-display of binary */
						/* contents */
						sav_j = showlet;
						pflg = 0;
						Pflg = flgP;
					}
					copylet(showlet, stdout, ttyf);
				}
		}

		/*
		 *	print only
		 */
		if (flgp) {
			curlet++;
			continue;
		}
		/*
		 *	Interactive
		 */
		interactive = 1;
		setjmp(sjbuf);
		stat(mailfile, stbufp);
		if (stbufp->st_size != file_size) {
			/*
			 *	New mail has arrived, load it
			 */
			k = nlet;
			lock(my_name);
			malf = doopen(mailfile, "r", E_FILE);
			fclose(tmpf);
			tmpf = doopen(lettmp, "a", E_TMP);
			fseek(malf, let[nlet].adr, 0);
			copymt(malf, tmpf);
			file_size = stbufp->st_size;
			fclose(malf);
			fclose(tmpf);
			unlock();
			tmpf = doopen(lettmp, "r+", E_TMP);
			if (++k < nlet)
				printf("New mail loaded into letters %d - %d\n",
				    k, nlet);
			else
				printf("New mail loaded into letter %d\n",
				    nlet);
		}

		/* read the command */
		printf("? ");
		fflush(stdout);
		fflush(stderr);
		if (fgets(readbuf, sizeof (readbuf), stdin) == NULL) break;
		resp = readbuf;
		while (*resp == ' ' || *resp == '\t') resp++;
		print = 1;
		Dout(pn, 0, "resp = '%s'\n", resp);
		if ((rc = atoi(resp)) != 0) {
			if (!validmsg(rc)) print = 0;
			else curlet = flgr ? rc - 1 : nlet - rc;
		} else switch (resp[0]) {
			default:
				printf("Usage:\n");
			/*
			 *	help
			 */
			case '?':
				print = 0;
				for (rc = 0; help[rc]; rc++)
					printf("%s", help[rc]);
				break;
			/*
			 *	print message number of current message
			 */
			case '#':
				print = 0;
				if ((showlet == nlet) || (showlet < 0)) {
					printf("No message selected yet.\n");
				} else {
					printf("Current message number is %d\n",
					    showlet+1);
				}
				break;
			/*
			 *	headers
			 */
			case 'h':
				print = 0;
				if (resp[2] != 'd' &&
				    resp[2] != 'a' &&
				    (rc = getnumbr(resp+1)) > 0) {
					showlet = rc - 1;
					curlet = flgr ? rc - 1 : nlet - rc- 1;
				}
				if (rc == -1 && resp[2] != 'a' &&
				    resp[2] != 'd')
					break;
				if (resp[2] == 'a') rc = 1;
				else if (resp[2] == 'd') rc = 2;
					else rc = 0;

/*
 *				if (!validmsg(showlet)) break;
 */
				gethead(showlet, rc);
				break;
			/*
			 *	skip entry
			 */
			case '+':
			case 'n':
			case '\n':
				curlet++;
				break;
			case 'P':
				Pflg++;
				break;
			case 'p':
				pflg++;
				break;
			case 'x':
				changed = 0;
			case 'q':
				goto donep;
			/*
			 *	Previous entry
			 */
			case '^':
			case '-':
				if (--curlet < 0) curlet = 0;
				break;
			/*
			 *	Save in file without header
			 */
			case 'y':
			case 'w':
			/*
			 *	Save mail with header
			 */
			case 's':
				print = 0;
				if (!validmsg(curlet)) break;
				if (resp[1] == '\n' || resp[1] == '\0') {
					cat(resp+1, hmbox, "");
				} else if (resp[1] != ' ') {
					printf("Invalid command\n");
					break;
				}
				umask(umsave);
				flg = 0;
				if (getarg(lfil, resp + 1) == NULL) {
					cat(resp + 1, hmbox, "");
				}
				malf = (FILE *)NULL;
				p = resp + 1;
				while ((p = getarg(lfil, p)) != NULL) {
					if (flg) {
					    fprintf(stderr,
						"%s: File '%s' skipped\n",
						program, lfil);
					    continue;
					}
					malf = NULL;
					if ((aret = legal(lfil))) {
						malf = fopen(lfil, "a");
					}
					if ((malf == NULL) || (aret == 0)) {
					    fprintf(stderr,
						"%s: Cannot append to %s\n",
						program, lfil);
					    flg++;
					} else if (aret == 2) {
						chown(lfil, my_euid, my_gid);
					}
					if (!flg &&
					    copylet(showlet, malf, resp[0] ==
					    's'? ORDINARY: ZAP) == FALSE) {
						fprintf(stderr,
					    "%s: Cannot save mail to '%s'\n",
						    program, lfil);
						flg++;
					} else
						Dout(pn, 0, "!saved\n");
					if (malf != (FILE *)NULL) {
						fclose(malf);
					}
				}
				umask(7);
				if (!flg) {
					setletr(showlet, resp[0]);
					print = 1;
					curlet++;
				}
				break;
			/*
			 *	Reply to a letter
			 */
			case 'r':
				print = 0;
				if (!validmsg(curlet)) break;
				replying = 1;
				for (k = 1; resp[k] == ' ' || resp[k] == '\t';
				    ++k);
				resp[strlen(resp)-1] = '\0';
				(void) strlcpy(m_sendto, resp+k,
				    sizeof (m_sendto));
				goback(showlet);
				replying = 0;
				setletr(showlet, resp[0]);
				break;
			/*
			 *	Undelete
			 */
			case 'u':
				print = 0;
				if ((k = getnumbr(resp+1)) <= 0) k = showlet;
				else k--;
				if (!validmsg(k)) break;
				setletr(k, ' ');
				break;
			/*
			 *	Mail letter to someone else
			 */
			case 'm':
				{
				reciplist list;
				print = 0;
				if (!validmsg(curlet)) break;
				new_reciplist(&list);
				flg = 0;
				k = 0;
				if (substr(resp, " -") != -1 ||
					substr(resp, "\t-") != -1) {
					printf("Only users may be specified\n");
					break;
				}
				p = resp + 1;
				while ((p = getarg(lfil, p)) != NULL) {
					char *env;
					if (lfil[0] == '$') {
						if (!(env = getenv(&lfil[1]))) {
							fprintf(stderr,
				"%s: %s has no value or is not exported.\n",
							    program, lfil);
							flg++;
						} else
							add_recip(&list, env,
							    FALSE);
						k++;
					} else if (lfil[0] != '\0') {
						add_recip(&list, lfil, FALSE);
						k++;
					}
				}
				(void) strlcpy(Rpath, my_name, sizeof (Rpath));
				sending = TRUE;
				flg += sendlist(&list, showlet, 0);
				sending = FALSE;
				if (k) {
					if (!flg) {
						setletr(showlet, 'm');
						print = 1;
						curlet++;
					}
				} else
					printf("Invalid command\n");
				del_reciplist(&list);
				break;
				}
			/*
			 *	Read new letters
			 */
			case 'a':
				if (onlet == nlet) {
					printf("No new mail\n");
					print = 0;
					break;
				}
				curlet = 0;
				print = 1;
				break;
			/*
			 *	Escape to shell
			 */
			case '!':
				systm(resp + 1);
				printf("!\n");
				print = 0;
				break;
			/*
			 *	Delete an entry
			 */
			case 'd':
				print = 0;
				k = 0;
				if (strncmp("dq", resp, 2) != SAME &&
					strncmp("dp", resp, 2) != SAME)
					if ((k = getnumbr(resp+1)) == -1) break;
				if (k == 0) {
					k = showlet;
					if (!validmsg(curlet)) break;
					print = 1;
					curlet++;
				} else	k--;

				setletr(k, 'd');
				if (resp[1] == 'p') print = 1;
				else if (resp[1] == 'q') goto donep;
				break;
		}
	}
	/*
	 *	Copy updated mailfile back
	 */
donep:
	if (changed) {
		copyback();
		stamp();
	}
}
Exemple #20
0
static void* cacheopen(char const* url) {
    const char* basename = strrchr(url,'/');
    assert(basename);

    static char dest[508];
    snprintf(dest,508,"%s/%s",cacheDir,basename);

    bool didtemp = false;

    int doopen(void) {
        int result = open(dest,O_RDONLY);
        if(result<0) {
            char temp[512];
            snprintf(temp,512,"%s.temp",dest);

            if(xmlIOHTTPMatch(url)) {
                void* ctx = NULL;
#if W3_ARE_NOT_MORONS
                ctx = xmlNanoHTTPOpen(url, NULL);
                if(xmlNanoHTTPReturnCode(ctx) != 200)
#else
                if(true)
#endif
                {
                    // XXX: it always is... w3.org dies on HTTP/1.0
#if W3_ARE_NOT_MORONS
                    xmlNanoHTTPClose(ctx);
#endif
                    fprintf(stderr,"Curl fallback for %s\n",url);
                    int pid = fork();
                    if(pid == 0) {
                        execlp("curl","curl","-o",temp,url,NULL);
                        abort();
                    }
                    int status = 0;
                    waitpid(pid,&status,0);
                    if(!(WIFEXITED(status) && (0 == WEXITSTATUS(status)))) {
                        fprintf(stderr,"CUrl failed! %x %d\n",status,WEXITSTATUS(status));
                        abort();
                    }
                } else {
                    assert(0==xmlNanoHTTPSave(ctx,temp));
                }
            } else if(xmlIOFTPMatch(url)) {
                void* ftp = xmlNanoFTPOpen(url);
                int out = open(temp,O_WRONLY|O_TRUNC|O_CREAT,0644);
                assert(out>0);
                char buf[0x1000];
                for(;;) {
                    int amt = xmlNanoFTPRead(ftp, buf, 0x1000);
                    if(amt==0) break;
                    assert(amt>0);
                    write(out,buf,amt);
                }
                close(out);            
            } else {
                FILE* fp = xmlFileOpen(url);
                struct stat fpstat;
                if(!fp) {
                    fprintf(stderr,"No idea what to do with url %s\n",url);
                    abort();
                }
                int inp = fileno(fp);
                assert(0==fstat(inp,&fpstat));
                off_t left = fpstat.st_size;
                int out = open(temp,O_WRONLY|O_TRUNC|O_CREAT,0644);
                assert(out>0);
                do {
                    ssize_t amt = sendfile(out,inp,NULL,left);
                    if(amt<0) {
                        perror(url);
                    }
                    assert(amt>=0);
                    left -= amt;
                } while(left > 0);
                fclose(fp);
                close(out);
            }
            rename(temp,dest); // doesn't matter if fails
            unlink(temp); // in case it failed
            return doopen();
        }
        return result;
    }
Exemple #21
0
/*
	 Send mail - High level sending routine
 */
void 
sendmail(int argc, char **argv)
{
	char		**args;
	char		*tp, *zp;
	char		*buf = NULL;
	size_t		bufsize = 0;
	char		last1c;
	FILE		*input;
	struct stat 	sbuf;
	int		aret;
	int		i, n;
	int		oldn = 1;	
	int		ttyf = 0;
	int		pushrest = 0;
	int		hdrtyp = 0;
	int		ctf = FALSE;
	int		binflg = 0;
	long		count = 0L;
	struct tm	*bp;
	struct hdrs	*hptr;
	static char	pn[] = "sendmail";
	reciplist	list;

	buf = smalloc(bufsize = 2048);
	Dout(pn, 0, "entered\n");
	new_reciplist(&list);
	for (i = 1; i < argc; ++i) {
	        if (argv[i][0] == '-') {
		        if (argv[i][1] == '\0') {
				errmsg(E_SYNTAX,"Hyphens MAY NOT be followed by spaces");
			}
		        if (i > 1) {
				errmsg(E_SYNTAX,"Options MUST PRECEDE persons");
			}
		        done(0);
	        }
		/*
			Ensure no NULL names in list
		*/
	        if (argv[i][0] == '\0' || argv[i][strlen(argv[i])-1] == '!') {
			errmsg(E_SYNTAX,"Null names are not allowed");
	  	       	done(0);
		}
		add_recip(&list, argv[i], FALSE); /* Don't check for duplication */
	}

	mktmp();
	/*
		Format time
	*/
	time(&iop);
	bp = localtime(&iop);
	tp = asctime(bp);
	zp = tzname[bp->tm_isdst];
	sprintf(datestring, "%.16s %.4s %.5s", tp, zp, tp+20);
	trimnl (datestring);
	/* asctime: Fri Sep 30 00:00:00 1986\n */
	/*          0123456789012345678901234  */
	/* RFCtime: Fri, 28 Jul 89 10:30 EDT   */
	sprintf(RFC822datestring, "%.3s, %.2s %.3s %.4s %.5s %.3s",
		tp, tp+8, tp+4, tp+20, tp+11, zp);

	/*
		Write out the from line header for the letter
	*/
	if (fromflag && deliverflag && from_user[0] != '\0') {
		snprintf(buf, bufsize, "%s%s %s\n", 
			header[H_FROM].tag, from_user, datestring);
	} else {
		snprintf(buf, bufsize, "%s%s %s\n", 
			header[H_FROM].tag, my_name, datestring);
	}
	if (!wtmpf(buf, strlen(buf))) {
		done(0);
	}
	savehdrs(buf, H_FROM);

	/*
		Copy to list in mail entry?
	*/
	if (flgt == 1 && argc > 1) {
		aret = argc;
		args = argv;
		while (--aret > 0) {
			snprintf(buf, bufsize, "%s %s\n", header[H_TO].tag, *++args);
			if (!wtmpf(buf, strlen(buf))) {
				done(0);
			}
			savehdrs(buf, H_TO);
		}
	}

	flgf = 1;	/* reset when first read of message body succeeds */
	/*
		Read mail message, allowing for lines of infinite 
		length. This is tricky, have to watch for newlines.
	*/
	saveint = setsig(SIGINT, savdead);
	last1c = ' ';	/* anything other than newline */
	ttyf = isatty (fileno(stdin));
	pushrest = 0;

	/*
	 * scan header & save relevant info.
	 */
	cpy(&fromU, &fromUsize, my_name);
	cpy(&fromS, &fromSsize, "");
	input = stdin;
	if (fstat(fileno(input), &sbuf) < 0) {
#ifdef EOVERFLOW
		if (errno == EOVERFLOW) {
			perror("stdin");
			exit(1);
		}
#endif
	}

	while ((n = getline (&line, &linesize, stdin)) > 0) {
		last1c = line[n-1];
		if (pushrest) {
			if (!wtmpf(line,n)) {
				done(0);
			}
			pushrest = (last1c != '\n');
			continue;
		}
		pushrest = (last1c != '\n');

		if ((hdrtyp = isheader (line, &ctf)) == FALSE) {
			break;
		}
		flgf = 0;
		switch (hdrtyp) {
		case H_RVERS:
			/* Are we dealing with a delivery report? */
			/* dflag = 9 ==> do not return on failure */
			dflag = 9;
			Dout(pn, 0, "dflag = 9\n");
			break;
		case H_FROM:
			if (!wtmpf(">", 1)) {
				done(0);
			}
			/* note dropthru */
			hdrtyp = H_FROM1;
		case H_FROM1:
			if (substr(line, "forwarded by") > -1) {
				break;
			}
			pickFrom (line);
			if (Rpath[0] != '\0')
				concat(&Rpath, &Rpathsize, "!");
			concat(&Rpath, &Rpathsize, fromS);
			n = 0; /* don't copy remote from's into mesg. */
			break;
		case H_CTYPE:
			/* suppress it: only generated if needed */
			n = 0; /* suppress */
			break;
		case H_TCOPY:
			/* Write out placeholder for later */
			snprintf(buf, bufsize, "%s \n", header[H_TCOPY].tag);
			if (!wtmpf(buf, strlen(buf))) {
				done(0);
			}
			n = 0; /* suppress */
			break;
		case H_MTYPE:
			if (flgm) {
				/* suppress if message-type argument */
				n = 0;
			}
			break;
		case H_CONT:
			if (oldn == 0) {
				/* suppress continuation line also */
				n = 0;
			}
			break;
		}
		oldn = n;	/* remember if this line was suppressed */
		if (n && !wtmpf(line,n)) {
			done(0);
		}
		if (!n) savehdrs(line, hdrtyp);
	}
	if (Rpath != NULL && Rpath[0] != '\0')
		concat(&Rpath, &Rpathsize, "!");
	concat(&Rpath, &Rpathsize, fromU);

	/* push out message type if so requested */
	if (flgm) {	/* message-type */
		snprintf(buf, bufsize, "%s%s\n", header[H_MTYPE].tag, msgtype);
		if (!wtmpf(buf, strlen(buf))) {
			done(0);
		}
	}

	if (n > bufsize) {
		free(buf);
		buf = smalloc(bufsize = n);
	}
	memcpy (buf, line, n);
	if (n == 0 || (ttyf && !strncmp (buf, ".\n", 2)) ) {
		if (flgf) {
			/* no input */
			return;
		} else {
			/*
			 * no content: put content-type
			 * only if explicitly present.
			 * Write out 'place-holders' only. (see below....)
			 */
			if ((hptr = hdrlines[H_CTYPE].head) !=
						    (struct hdrs *)NULL) {
				snprintf(line, linesize, "%s \n", header[H_CTYPE].tag);
				if (!wtmpf(line, strlen(line))) {
					done(0);
				}
			}
			goto wrapsend;
		}
	}

	if (n == 1 && last1c == '\n') {	/* blank line -- suppress */
		n = getline (&buf, &bufsize, stdin);
		if (n == 0 || (ttyf && !strncmp (buf, ".\n", 2)) ) {
			/*
			 * no content: put content-type
			 * only if explicitly present.
			 * Write out 'place-holder' only. (see below....)
			 */
			if ((hptr = hdrlines[H_CTYPE].head) !=
						    (struct hdrs *)NULL) {
				snprintf(line, linesize, "%s \n", header[H_CTYPE].tag);
				if (!wtmpf(line, strlen(line))) {
					done(0);
				}
			}
			goto wrapsend;
		}
	}

	if (debug > 0) {
		buf[n] = '\0';
		Dout(pn, 0, "header scan complete, readahead %d = \"%s\"\n", n, buf);
	}

	/* 
	 * Write out H_CTYPE line. This is used only as 
	 * placeholders in the tmp file. When the 'real' message is sent,
	 * the proper value will be put out by copylet().
	 */
	snprintf(line, linesize, "%s \n", header[H_CTYPE].tag);
	if (!wtmpf(line, strlen(line))) {
		done(0);
	}
	if (hdrlines[H_CTYPE].head == (struct hdrs *)NULL) {
		savehdrs(line,H_CTYPE);
	}
	/* and a blank line */
	if (!wtmpf("\n", 1)) {
		done(0);
	}
	Dout(pn, 0, "header out completed\n");

	pushrest = 0;
	count = 0L;
	/*
	 *	Are we returning mail from a delivery failure of an old-style
	 *	(SVR3.1 or SVR3.0) rmail? If so, we won't return THIS on failure
	 *	[This line should occur as the FIRST non-blank non-header line]
	 */
	if (!strncmp("***** UNDELIVERABLE MAIL sent to",buf,32)) {
	     dflag = 9; /* 9 says do not return on failure */
	     Dout(pn, 0, "found old-style UNDELIVERABLE line. dflag = 9\n");
	}

	/* scan body of message */
	while (n > 0) {
		if (ttyf && !strcmp (buf, ".\n"))
			break;
		if (!binflg) {
			binflg = !istext ((unsigned char *)buf, n);
		}

		if (!wtmpf(buf, n)) {
			done(0);
		}
		count += n;
		n = ttyf
			? getline (&buf, &bufsize, stdin)
			: fread (buf, 1, bufsize, stdin);
	}
	setsig(SIGINT, saveint);

wrapsend:
	/*
	 *	In order to use some of the subroutines that are used to
	 *	read mail, the let array must be set up
	 */
	nlet = 1;
	let[0].adr = 0;
	let[1].adr = ftell(tmpf);
	let[0].text = (binflg == 1 ? FALSE : TRUE);
	Dout(pn, 0, "body copy complete, count %ld\n", count);
	/*
	 * Modify value of H_CTYPE if necessary.
	 */
	if ((hptr = hdrlines[H_CTYPE].head) != (struct hdrs *)NULL) {
		if (strlen(hptr->value) == 0)
			strcpy(hptr->value, binflg ? "binary" : "text");
	}

	if (fclose(tmpf) == EOF) {
		tmpf = NULL;
		tmperr();
		done(0);
	}

	tmpf = doopen(lettmp,"r+",E_TMP);

	/* Do not send mail on SIGINT */
	if (dflag == 2) {
		done(0);
	}

	sendlist(&list, 0, 0);
	done(0);
}
Exemple #22
0
static
void
mergebins(void)
{
	int infds[numprocs], outfd;
	int values[numprocs], ready[numprocs];
	const char *name, *outname;
	int i, result;
	int numready, place, val, worknum;

	outname = mergedname(me);
	outfd = doopen(outname, O_WRONLY|O_CREAT|O_TRUNC, 0664);

	for (i=0; i<numprocs; i++) {
		name = binname(i, me);
		infds[i] = doopen(name, O_RDONLY, 0);
		values[i] = 0;
		ready[i] = 0;
	}

	worknum = 0;

	while (1) {
		numready = 0;
		for (i=0; i<numprocs; i++) {
			if (infds[i] < 0) {
				continue;
			}

			if (!ready[i]) {
				result = doread("bin", infds[i], 
						&val, sizeof(int));
				if (result == 0) {
					doclose("bin", infds[i]);
					infds[i] = -1;
					continue;
				}
				if ((size_t) result != sizeof(int)) {
					complainx("%s: read: short count",
						  binname(i, me));
					exit(1);
				}
				values[i] = val;
				ready[i] = 1;
			}
			numready++;
		}
		if (numready == 0) {
			break;
		}

		/* find the smallest */
		place = -1;
		for (i=0; i<numprocs; i++) {
			if (!ready[i]) {
				continue;
			}
			if (place < 0 || values[i] < val) {
				val = values[i];
				place = i;
			}
		}
		assert(place >= 0);

		workspace[worknum++] = val;
		if (worknum >= WORKNUM) {
			assert(worknum == WORKNUM);
			dowrite(outname, outfd, workspace,
				worknum * sizeof(int));
			worknum = 0;
		}
		ready[place] = 0;
	}

	dowrite(outname, outfd, workspace, worknum * sizeof(int));
	doclose(outname, outfd);

	for (i=0; i<numprocs; i++) {
		assert(infds[i] < 0);
	}
}