Пример #1
0
static int
sfpzexcept(Sfio_t* sp, int op, void* val, Sfdisc_t* dp)
{
	register Sfpzip_t*	pz = (Sfpzip_t*)dp;
	int			r;

	NoP(sp);
	switch (op)
	{
	case SF_ATEXIT:
		sfdisc(sp, SF_POPDISC);
		return 0;
	case SF_CLOSING:
	case SF_DPOP:
	case SF_FINAL:
		if (pz->pz)
		{
			pz->pz->flags &= ~PZ_STREAM;
			r = pzclose(pz->pz);
			pz->pz = 0;
		}
		else
			r = 0;
		if (op != SF_CLOSING)
			free(dp);
		return r;
	case SF_DBUFFER:
		return 1;
	case SF_SYNC:
		return val ? 0 : pzsync(pz->pz);
	case SFPZ_HANDLE:
		return (*((Pz_t**)val) = pz->pz) ? 1 : -1;
	}
	return 0;
}
Пример #2
0
int sfdcsasl(Sfio_t *f, sasl_conn_t *conn)
{
    Sasldisc_t *sasl;
    
    if (conn == NULL) {
	/* no need to do anything */
	return 0;
    }

    if(!(sasl = (Sasldisc_t*)malloc(sizeof(Sasldisc_t))) )
	return -1;
    
    sasl->disc.readf = sasl_read;
    sasl->disc.writef = sasl_write;
    sasl->disc.seekf = NULL;
    sasl->disc.exceptf = NULL;

    sasl->conn = conn;

    if (sfdisc(f, (Sfdisc_t *) sasl) != (Sfdisc_t *) sasl) {
	free(sasl);
	return -1;
    }
    
    return 0;
}
Пример #3
0
Файл: tnoseek.c Проект: att/ast
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    char buf[1024];

    sfsetbuf(sfstdout, buf, sizeof(buf));
    sfset(sfstdout, SF_LINE, 0);

    if (sfdisc(sfstdout, &seekable) != &seekable) terror("Can't set discipline");
    if (sfseek(sfstdout, (Sfoff_t)0, 0) < 0) terror("Sfstdout should be seekable");
    if (sfwrite(sfstdout, "123\n", 4) != 4) terror("Can't write");
    if (sfwrite(sfstdout, "123\n", 4) != 4) terror("Can't write");
    if (sfdisc(sfstdout, NULL) != &seekable) terror("Can't pop discipline");

    if (buffer != buf || size != 8 || count != 1) terror("Wrong calls to write");

    texit(0);
}
Пример #4
0
tmain()
{
	char	buf[100];
	Sfio_t	*fp;
	int	i;
	char	*s;

	if(!(fp = sftmp(8)))
		terror("Can't open temp file");

	sfset(fp,SF_LINE,1);
	for(i = 0; i < 1000; ++i)
	{	sfsprintf(buf,sizeof(buf),"Number: %d",i);
		if(sfputr(fp,buf,'\n') <= 0)
			terror("Writing %s",buf);
	}

	sfseek(fp,(Sfoff_t)0,0);

	for(i = 0; i < 1000; ++i)
	{	sfsprintf(buf,sizeof(buf),"Number: %d",i);
		if(!(s = sfgetr(fp,'\n',1)))
			terror("Reading %s",buf);
		if(strcmp(s,buf) != 0)
			terror("Input=%s, Expect=%s",s,buf);
	}

	sfseek(fp,(Sfoff_t)0,0);
	s = sfgetr(fp,'\0',1);
	if(s)
		terror("Expecting a null string");
	s = sfgetr(fp,'\0',-1);
	if(!s)
		terror("Expecting a non-null string");
	if(sfvalue(fp) != sfsize(fp))
		terror("Wrong size");

	sfclose(fp);
	if(!(fp = sfnew(0, buf, 12, 1, SF_WRITE)) )
		terror("Opening a test stream");
	sfsetbuf(fp, buf, 12);
	sfset(fp, SF_LINE, 0);
	sfdisc(fp, &Disc);
	if(sfputr(fp, "0123456789", '\n') != 11)
		terror("Sfputr failed1");
	if(sfputr(fp, "0", -1) != 1)
		terror("Sfputr failed2");
	if(sfputr(fp, "1", -1) != 1)
		terror("Sfputr failed3");

	texit(0);
}
Пример #5
0
static void
tee_cleanup(register Tee_t* tp)
{
    register int*	hp;
    register int	n;

    if (tp)
    {
        sfdisc(sfstdout, NiL);
        if (tp->line >= 0)
            sfset(sfstdout, SF_LINE, tp->line);
        for (hp = tp->fd; (n = *hp) >= 0; hp++)
            close(n);
    }
}
Пример #6
0
Sfio_t*
tokline(const char* arg, int flags, int* line)
{
	Sfio_t*		f;
	Sfio_t*		s;
	Splice_t*	d;
	char*		p;
	char*		e;

	static int	hidden;

	if (!(d = newof(0, Splice_t, 1, 0)))
		return 0;
	if (!(s = sfopen(NiL, NiL, "s")))
	{
		free(d);
		return 0;
	}
	if (!(flags & (SF_STRING|SF_READ)))
		f = (Sfio_t*)arg;
	else if (!(f = sfopen(NiL, arg, (flags & SF_STRING) ? "s" : "r")))
	{
		free(d);
		sfclose(s);
		return 0;
	}
	else if ((p = sfreserve(f, 0, 0)) && sfvalue(f) > 11 && strmatch(p, "#!!! +([-0-9]) *([!\n]) !!!\n*") && (e = strchr(p, '\n')))
	{
		flags = strtol(p + 5, &p, 10);
		error(flags, "%s:%-.*s", arg, e - p - 4, p);
	}
	d->disc.exceptf = spliceline;
	d->sp = f;
	*(d->line = line ? line : &hidden) = 0;
	sfdisc(s, (Sfdisc_t*)d);
	return s;
}
Пример #7
0
static Sfio_t*
paxpart(Pax_t* pax, Paxarchive_t* ap, off_t n)
{
	register Part_t*	part;

	static int		fd = -1;

	if (!(part = ap->partio))
	{
		if (!(part = newof(0, Part_t, 1, 0)) || !(part->sp = sfstropen()))
		{
			paxnospace(pax);
			return 0;
		}
		part->sp->_flags &= ~(SF_READ|SF_WRITE|SF_STRING);
		if (ap->flags & PAX_IN)
			part->sp->_flags |= SF_READ;
		else
			part->sp->_flags |= SF_WRITE;
		if (fd < 0)
			fd = open("/dev/null", O_RDWR);
		part->sp->_file = fd;
		part->disc.readf = part_read;
		part->disc.writef = part_write;
		if (sfdisc(part->sp, &part->disc) != &part->disc)
		{
			sfclose(part->sp);
			free(part);
			return 0;
		}
		part->pax = pax;
		part->ap = ap;
		ap->partio = part;
	}
	part->n = n;
	return part->sp;
}
Пример #8
0
Файл: history.c Проект: att/ast
//
// Open the history file. If HISTNAME is not given and userid==0 then no history file. If login_sh
// and HISTFILE is longer than HIST_MAX bytes then it is cleaned up.
//
// hist_open() returns 1, if history file is opened.
//
int sh_histinit(void *sh_context) {
    Shell_t *shp = sh_context;
    int fd;
    History_t *hp;
    char *histname;
    char *fname = NULL;
    int histmask, maxlines, hist_start = 0;
    char *cp;
    off_t hsize = 0;

    shgd->hist_ptr = hist_ptr;
    if (shgd->hist_ptr) return 1;
    if (!(histname = nv_getval(HISTFILE))) {
        int offset = stktell(shp->stk);
        cp = nv_getval(HOME);
        if (cp) sfputr(shp->stk, cp, -1);
        sfputr(shp->stk, hist_fname, 0);
        stkseek(shp->stk, offset);
        histname = stkptr(shp->stk, offset);
    }

#if 0
// TODO: Figure out if this should be enabled. Originally excluded via `#ifdef future`.
    if (hp = wasopen) {
        // Reuse history file if same name.
        wasopen = 0;
        shgd->hist_ptr = hist_ptr = hp;
        if (strcmp(histname, hp->histname) == 0) {
            return 1;
        } else {
            hist_free();
        }
    }
#endif  // future

retry:
    cp = path_relative(shp, histname);
    if (!histinit) histmode = S_IRUSR | S_IWUSR;
    if ((fd = open(cp, O_BINARY | O_APPEND | O_RDWR | O_CREAT | O_CLOEXEC, histmode)) >= 0) {
        hsize = lseek(fd, (off_t)0, SEEK_END);
    }
    if ((unsigned)fd < 10) {
        int n;
        if ((n = sh_fcntl(fd, F_DUPFD_CLOEXEC, 10)) >= 0) {
            sh_close(fd);
            fd = n;
        }
    }
    // Make sure that file has history file format.
    if (hsize && hist_check(fd)) {
        sh_close(fd);
        hsize = 0;
        if (unlink(cp) >= 0) goto retry;
        fd = -1;
    }

    // Don't allow root a history_file in /tmp.
    if (fd < 0 && shgd->userid) {
        fname = ast_temp_file(NULL, NULL, &fd, O_APPEND | O_CLOEXEC);
        if (!fname) return 0;
    }

    if (fd < 0) return 0;
    // Set the file to close-on-exec.
    (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
    cp = nv_getval(HISTSIZE);
    if (cp) {
        maxlines = (unsigned)strtol(cp, NULL, 10);
    } else {
        maxlines = HIST_DFLT;
    }
    for (histmask = 16; histmask <= maxlines; histmask <<= 1) {
        ;  // empty loop
    }
    histmask -= 1;
    hp = calloc(1, sizeof(History_t) + histmask * sizeof(off_t));
    if (!hp) {
        sh_close(fd);
        return 0;
    }

    shgd->hist_ptr = hist_ptr = hp;
    hp->histshell = shp;
    hp->histsize = maxlines;
    hp->histmask = histmask;
    hp->histfp = sfnew(NULL, NULL, HIST_BSIZE, fd, SF_READ | SF_WRITE | SF_APPENDWR | SF_SHARE);
    hp->histind = 1;
    hp->histcmds[1] = 2;
    hp->histcnt = 2;
    hp->histname = strdup(histname);
    hp->histdisc = hist_disc;
    if (hsize == 0) {
        // Put special characters at front of file.
        sfwrite(hp->histfp, (char *)hist_stamp, 2);
        sfsync(hp->histfp);
    } else {
        // Initialize history list.
        int first, last;
        off_t mark, size = (HIST_MAX / 4) + maxlines * HIST_LINE;
        hp->histind = first = hist_nearend(hp, hp->histfp, hsize - size);
        histinit = 1;
        hist_eof(hp);  // this sets histind to last command
        if ((hist_start = (last = (int)hp->histind) - maxlines) <= 0) hist_start = 1;
        mark = hp->histmarker;
        while (first > hist_start) {
            size += size;
            first = hist_nearend(hp, hp->histfp, hsize - size);
            hp->histind = first;
        }
        histinit = hist_start;
        hist_eof(hp);
        if (!histinit) {
            sfseek(hp->histfp, hp->histcnt = hsize, SEEK_SET);
            hp->histind = last;
            hp->histmarker = mark;
        }
        histinit = 0;
    }
    if (fname) {
        unlink(fname);
        free(fname);
    }
    if (hist_clean(fd) && hist_start > 1 && hsize > HIST_MAX) {
#ifdef DEBUG
        sfprintf(sfstderr, "%d: hist_trim hsize=%d\n", getpid(), hsize);
        sfsync(sfstderr);
#endif  // DEBUG
        hp = hist_trim(hp, (int)hp->histind - maxlines);
    }
    sfdisc(hp->histfp, &hp->histdisc);
    STORE_VT((HISTCUR)->nvalue, i32p, &hp->histind);
    sh_timeradd(1000L * (HIST_RECENT - 30), 1, hist_touch, hp->histname);
    hp->auditfp = NULL;

    char buff[SF_BUFSIZE];
    if (!sh_isstate(shp, SH_INTERACTIVE)) return 1;
    hp->auditmask = sh_checkaudit(hp, AUDIT_FILE, buff, sizeof(buff));
    if (!hp->auditmask) return 1;

    if ((fd = sh_open(buff, O_BINARY | O_WRONLY | O_APPEND | O_CREAT | O_CLOEXEC,
                      S_IRUSR | S_IWUSR)) >= 0 &&
        fd < 10) {
        int n;
        if ((n = sh_fcntl(fd, F_DUPFD_CLOEXEC, 10)) >= 0) {
            sh_close(fd);
            fd = n;
        }
    }
    if (fd >= 0) {
        (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
        hp->tty = strdup(isatty(2) ? ttyname(2) : "notty");
        hp->auditfp = sfnew(NULL, NULL, -1, fd, SF_WRITE);
    }

    return 1;
}
Пример #9
0
Dssfile_t*
dssfopen(Dss_t* dss, const char* path, Sfio_t* io, Dssflags_t flags, Dssformat_t* format)
{
	Dssfile_t*	file;
	Vmalloc_t*	vm;
	char*		s;
	size_t		n;
	int		i;
	struct stat	st;
	Sfdisc_t	top;
	char		buf[PATH_MAX];

	if (flags & DSS_FILE_WRITE)
	{
		if (io)
		{
			memset(&top, 0, sizeof(top));
			if (sfdisc(io, &top))
			{
				n = top.disc == &dss->state->compress_preferred;
				sfdisc(io, SF_POPDISC);
				if (n)
				{
					sfdisc(io, SF_POPDISC);
					sfdczip(io, path, dss->meth->compress ? dss->meth->compress : "gzip", dss->disc->errorf);
				}
			}
		}
		if (dss->flags & DSS_APPEND)
			flags |= DSS_FILE_APPEND;
	}
	if (!path || !*path || streq(path, "-"))
	{
		if (flags & DSS_FILE_WRITE)
		{
			if (io)
				path = "output-stream";
			else
			{
				path = "/dev/stdout";
				io = sfstdout;
			}
		}
		else if (io)
			path = "input-stream";
		else
		{
			path = "/dev/stdin";
			io = sfstdin;
		}
		flags |= DSS_FILE_KEEP;
	}
	else if (io)
		flags |= DSS_FILE_KEEP;
	else if (flags & DSS_FILE_WRITE)
	{
		if (!(io = sfopen(NiL, path, (flags & DSS_FILE_APPEND) ? "a" : "w")))
		{
			if (dss->disc->errorf)
				(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: cannot open", path);
			return 0;
		}
	}
	else if (!(io = dssfind(path, "", DSS_VERBOSE, buf, sizeof(buf), dss->disc)))
		return 0;
	else
		path = (const char*)buf;
	if (!(vm = vmopen(Vmdcheap, Vmbest, 0)))
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space");
		return 0;
	}
	if (!(file = vmnewof(vm, 0, Dssfile_t, 1, strlen(path) + 1)))
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "out of space");
		if (!(flags & DSS_FILE_KEEP))
			sfclose(io);
		vmclose(vm);
		return 0;
	}
	strcpy(file->path = (char*)(file + 1), path);
	file->dss = dss;
	file->vm = vm;
	file->io = io;
	file->flags = flags;
	if (flags & DSS_FILE_WRITE)
	{
		if (!(file->format = format) && !(file->format = dss->format))
		{
			if (dss->disc->errorf)
				(*dss->disc->errorf)(NiL, dss->disc, 2, "output method format must be specified");
			if (!(flags & DSS_FILE_KEEP))
				sfclose(io);
			return 0;
		}
		file->readf = noreadf;
		file->writef = file->format->writef;
	}
	else
	{
		if (sfsize(file->io) || !fstat(sffileno(file->io), &st) && (S_ISFIFO(st.st_mode)
#ifdef S_ISSOCK
			|| S_ISSOCK(st.st_mode)
#endif
			))
		{
			if (sfdczip(file->io, file->path, NiL, dss->disc->errorf) < 0)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: inflate error", file->path);
				dssfclose(file);
				return 0;
			}
			s = sfreserve(file->io, SF_UNBOUND, SF_LOCKR);
			n = sfvalue(file->io);
			if (!s)
			{
				if (n && dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, ERROR_SYSTEM|2, "%s: cannot peek", file->path);
				dssfclose(file);
				return 0;
			}
			for (file->format = (Dssformat_t*)dtfirst(dss->meth->formats); file->format && !(i = (*file->format->identf)(file, s, n, dss->disc)); file->format = (Dssformat_t*)dtnext(dss->meth->formats, file->format));
			sfread(file->io, s, 0);
			if (!file->format)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: unknown %s format", file->path, dss->meth->name);
				dssfclose(file);
				return 0;
			}
			if (i < 0)
				return 0;
			if (format && format != file->format)
			{
				if (dss->disc->errorf)
					(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %s file format %s incompatible with %s", file->path, dss->meth->name, file->format->name, format->name);
				dssfclose(file);
				return 0;
			}
			if ((dss->flags & DSS_VERBOSE) && dss->disc->errorf)
				(*dss->disc->errorf)(dss, dss->disc, 1, "%s: %s method %s format", file->path, dss->meth->name, file->format->name);
			file->readf = file->format->readf;
		}
		else
		{
			file->format = format ? format : dss->format ? dss->format : (Dssformat_t*)dtfirst(dss->meth->formats);
			file->readf = nullreadf;
		}
		file->writef = nowritef;
		if (!dss->format)
			dss->format = file->format;
	}
	if (!file->format)
	{
		if (dss->disc->errorf)
			(*dss->disc->errorf)(NiL, dss->disc, 2, "%s: %s method did not set file format", file->path, dss->meth->name);
		dssfclose(file);
		return 0;
	}
	file->record.file = file;
	if ((*file->format->openf)(file, dss->disc))
	{
		dssfclose(file);
		return 0;
	}
	return file;
}
Пример #10
0
/*
 * open the history file
 * if HISTNAME is not given and userid==0 then no history file.
 * if login_sh and HISTFILE is longer than HIST_MAX bytes then it is
 * cleaned up.
 * hist_open() returns 1, if history file is open
 */
int  sh_histinit(void *sh_context)
{
	Shell_t *shp = (Shell_t*)sh_context;
	register int fd;
	register History_t *hp;
	register char *histname;
	char *fname=0;
	int histmask, maxlines, hist_start=0;
	register char *cp;
	register off_t hsize = 0;

	if(shgd->hist_ptr=hist_ptr)
		return(1);
	if(!(histname = nv_getval(HISTFILE)))
	{
		int offset = staktell();
		if(cp=nv_getval(HOME))
			stakputs(cp);
		stakputs(hist_fname);
		stakputc(0);
		stakseek(offset);
		histname = stakptr(offset);
	}
#ifdef future
	if(hp=wasopen)
	{
		/* reuse history file if same name */
		wasopen = 0;
		shgd->hist_ptr = hist_ptr = hp;
		if(strcmp(histname,hp->histname)==0)
			return(1);
		else
			hist_free();
	}
#endif
retry:
	cp = path_relative(shp,histname);
	if(!histinit)
		histmode = S_IRUSR|S_IWUSR;
	if((fd=open(cp,O_BINARY|O_APPEND|O_RDWR|O_CREAT,histmode))>=0)
	{
		hsize=lseek(fd,(off_t)0,SEEK_END);
	}
	if((unsigned)fd <=2)
	{
		int n;
		if((n=fcntl(fd,F_DUPFD,10))>=0)
		{
			close(fd);
			fd=n;
		}
	}
	/* make sure that file has history file format */
	if(hsize && hist_check(fd))
	{
		close(fd);
		hsize = 0;
		if(unlink(cp)>=0)
			goto retry;
		fd = -1;
	}
	if(fd < 0)
	{
#if KSHELL
		/* don't allow root a history_file in /tmp */
		if(shgd->userid)
#endif	/* KSHELL */
		{
			if(!(fname = pathtmp(NIL(char*),0,0,NIL(int*))))
				return(0);
			fd = open(fname,O_BINARY|O_APPEND|O_CREAT|O_RDWR,S_IRUSR|S_IWUSR);
		}
	}
	if(fd<0)
		return(0);
	/* set the file to close-on-exec */
	fcntl(fd,F_SETFD,FD_CLOEXEC);
	if(cp=nv_getval(HISTSIZE))
		maxlines = (unsigned)strtol(cp, (char**)0, 10);
	else
		maxlines = HIST_DFLT;
	for(histmask=16;histmask <= maxlines; histmask <<=1 );
	if(!(hp=new_of(History_t,(--histmask)*sizeof(off_t))))
	{
		close(fd);
		return(0);
	}
	shgd->hist_ptr = hist_ptr = hp;
	hp->histshell = (void*)shp;
	hp->histsize = maxlines;
	hp->histmask = histmask;
	hp->histfp= sfnew(NIL(Sfio_t*),hp->histbuff,HIST_BSIZE,fd,SF_READ|SF_WRITE|SF_APPENDWR|SF_SHARE);
	memset((char*)hp->histcmds,0,sizeof(off_t)*(hp->histmask+1));
	hp->histind = 1;
	hp->histcmds[1] = 2;
	hp->histcnt = 2;
	hp->histname = strdup(histname);
	hp->histdisc = hist_disc;
	if(hsize==0)
	{
		/* put special characters at front of file */
		sfwrite(hp->histfp,(char*)hist_stamp,2);
		sfsync(hp->histfp);
	}
	/* initialize history list */
	else
	{
		int first,last;
		off_t mark,size = (HIST_MAX/4)+maxlines*HIST_LINE;
		hp->histind = first = hist_nearend(hp,hp->histfp,hsize-size);
		histinit = 1;
		hist_eof(hp);	 /* this sets histind to last command */
		if((hist_start = (last=(int)hp->histind)-maxlines) <=0)
			hist_start = 1;
		mark = hp->histmarker;
		while(first > hist_start)
		{
			size += size;
			first = hist_nearend(hp,hp->histfp,hsize-size);
			hp->histind = first;
		}
		histinit = hist_start;
		hist_eof(hp);
		if(!histinit)
		{
			sfseek(hp->histfp,hp->histcnt=hsize,SEEK_SET);
			hp->histind = last;
			hp->histmarker = mark;
		}
		histinit = 0;
	}
	if(fname)
	{
		unlink(fname);
		free((void*)fname);
	}
	if(hist_clean(fd) && hist_start>1 && hsize > HIST_MAX)
	{
#ifdef DEBUG
		sfprintf(sfstderr,"%d: hist_trim hsize=%d\n",getpid(),hsize);
		sfsync(sfstderr);
#endif /* DEBUG */
		hp = hist_trim(hp,(int)hp->histind-maxlines);
	}
	sfdisc(hp->histfp,&hp->histdisc);
#if KSHELL
	(HISTCUR)->nvalue.lp = (&hp->histind);
#endif /* KSHELL */
	sh_timeradd(1000L*(HIST_RECENT-30), 1, hist_touch, (void*)hp->histname);
#if SHOPT_ACCTFILE
	if(sh_isstate(SH_INTERACTIVE))
		acctinit(hp);
#endif /* SHOPT_ACCTFILE */
#if SHOPT_AUDIT
	{
		char buff[SF_BUFSIZE];
		hp->auditfp = 0;
		if(sh_isstate(SH_INTERACTIVE) && (hp->auditmask=sh_checkaudit(hp,SHOPT_AUDITFILE, buff, sizeof(buff))))
		{
			if((fd=sh_open(buff,O_BINARY|O_WRONLY|O_APPEND|O_CREAT,S_IRUSR|S_IWUSR))>=0 && fd < 10)
			{
				int n;
				if((n = sh_fcntl(fd,F_DUPFD, 10)) >= 0)
				{
					sh_close(fd);
					fd = n;
				}
			}
			if(fd>=0)
			{
				fcntl(fd,F_SETFD,FD_CLOEXEC);
				hp->tty = strdup(ttyname(2));
				hp->auditfp = sfnew((Sfio_t*)0,NULL,-1,fd,SF_WRITE);
			}
		}
	}
#endif
	return(1);
}
Пример #11
0
Файл: texcept.c Проект: att/ast
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    Sfio_t *f, *f2;
    char buf[1024];
    char rbuf[4 * 1024];
    off_t o;
    int i;

    if (!(f = sfopen(NULL, tstfile("sf", 0), "w"))) terror("Can't open file");
    sfset(f, SF_IOCHECK, 1);

    Disc.exceptf = except;
    if (!sfdisc(f, &Disc)) terror("Pushing discipline failed");

    sfdisc(f, &Disc);
    if (Type != SF_DPUSH) terror("Did not get push event");

    /* this is to test sfraise(NULL,...) */
    if (!(f2 = sfopen(NULL, tstfile("sf", 0), "w"))) terror("Can't open file");
    sfdisc(f2, &Disc);

    Sfn = 0;
    if (sfraise(0, SF_WRITE, 0) < 0) terror("sfraise failed");
    if (Sfn != 2) terror("Didn't get right event count");

    sfdisc(f, NULL);
    if (Type != SF_DPOP) terror("Did not get pop event");

    sfwrite(f, "123", 3);
    sfsync(f);
    if (Type != SF_SYNC) terror("Did not get sync event");

    sfwrite(f, "123", 3);
    sfpurge(f);
    if (Type != SF_PURGE) terror("Did not get purge event");

    sfclose(f);
    if (Type != SF_CLOSING) terror("Did not get close event");

    sfclose(f);
    if (Type != SF_FINAL) terror("Did not get final event");

    if (!(f = sfopen(NULL, tstfile("sf", 0), "r"))) terror("Can't open file");
    Disc2.readf = readfunc;
    Disc2.exceptf = except3;
    sfdisc(f, &Disc2);
    if (sfgetc(f) >= 0) terror("There should be no data here");
    if (Type != SF_LOCKED) terror("Did not get lock event");

    /* test to see if sfclose() preserves seek location */
    if (!(f = sftmp(0))) terror("Can't create temp file");
    sfsetbuf(f, buf, sizeof(buf));
    for (i = 0; i < sizeof(rbuf); ++i) rbuf[i] = i;
    sfwrite(f, rbuf, sizeof(rbuf));
    sfset(f, SF_WRITE, 0);

    Disc.exceptf = except2;
    sfdisc(f, &Disc);
    sfseek(f, (Sfoff_t)0, 0);
    if (sfread(f, rbuf, 4) != 4) terror("reading 4 bytes");
    for (i = 0; i < 4; ++i) {
        if (rbuf[i] != i) terror("wrong 4 bytes");
    }

    sfsync(f);
    if ((o = lseek(sffileno(f), (off_t)0, SEEK_CUR)) != 4) {
        terror("Wrong seek location %lld", (Sfoff_t)o);
    }

    if ((i = dup(sffileno(f))) < 0) terror("Can't dup file descriptor");
    if ((o = lseek(i, (off_t)0, SEEK_CUR)) != 4) terror("Wrong seek location %lld", (Sfoff_t)o);

    sfclose(f);
    if ((o = lseek(i, (off_t)0, SEEK_CUR)) != 4) terror("Wrong seek location %lld", (Sfoff_t)o);

    texit(0);
}
Пример #12
0
int
sfdcpzip(Sfio_t* sp, const char* path, unsigned long flags, Pzdisc_t* disc)
{
	Sfio_t*		io;
	Sfpzip_t*	pz;
	Pz_t*		oz;

	if (flags & PZ_HANDLE)
	{
		oz = (Pz_t*)sp;
		sp = oz->io;
	}
	else
		oz = 0;
	if (sfset(sp, 0, 0) & SF_WRITE)
	{
		if (flags & PZ_STAT)
			return -1;
	}
	else if (!(flags & PZ_FORCE))
	{
		unsigned char*	s;
		int		r;
		int		m1;
		int		m2;

		if (!(r = sfset(sp, 0, 0) & SF_SHARE))
			sfset(sp, SF_SHARE, 1);
		s = (unsigned char*)sfreserve(sp, PZ_GZ_MAGOFF + 2, 1);
		if (!r)
			sfset(sp, SF_SHARE, 0);
		if (!s)
			return -1;
		m1 = s[0];
		m2 = s[1];
		r = m1 == PZ_MAGIC_1 && m2 == PZ_MAGIC_2 && s[2] > 0 && s[3] < 10 ||
		    m1 == GZ_MAGIC_1 && m2 == GZ_MAGIC_2 &&
		    s[PZ_GZ_MAGOFF] == PZ_GZ_MAGIC_1 && s[PZ_GZ_MAGOFF+1] == PZ_GZ_MAGIC_2;
		sfread(sp, s, 0);
		if (flags & PZ_STAT)
			return r;
		if (!r)
		{
			if (!(flags & PZ_NOGZIP))
			{
				if (m1 == GZ_MAGIC_1)
				{
					if (m2 == GZ_MAGIC_2)
						r = sfdcgzip(sp, (flags & PZ_CRC) ? 0 : SFGZ_NOCRC);
					else if (m2 == LZ_MAGIC_2)
						r = sfdclzw(sp, 0);
				}
				else if (m1 == 'B' && m2 == 'Z' && s[2] == 'h' && s[3] >= '1' && s[3] <= '9')
					r = sfdcbzip(sp, 0);
			}
			return r;
		}
		sfsync(sp);
	}
	if (!(io = sfnew(NiL, NiL, SF_UNBOUND, sffileno(sp), (sfset(sp, 0, 0) & (SF_READ|SF_WRITE)))))
		return -1;
	if (!(pz = newof(0, Sfpzip_t, 1, 0)))
	{
		io->_file = -1;
		sfclose(io);
		return -1;
	}
	pz->disc.version = PZ_VERSION;
	flags &= ~(PZ_READ|PZ_WRITE|PZ_STAT|PZ_STREAM|PZ_INTERNAL);
	flags |= PZ_PUSHED|PZ_STREAM|((sfset(sp, 0, 0) & SF_READ) ? PZ_READ : PZ_WRITE);
	if (oz && (oz->flags & PZ_WRITE))
		flags |= PZ_DELAY;
	if (disc)
	{
		pz->disc.errorf = disc->errorf;
		pz->disc.window = disc->window;
		pz->disc.options = disc->options;
		pz->disc.partition = disc->partition;
		if (disc->splitf)
			flags |= PZ_ACCEPT;
	}
	if (!(pz->pz = pzopen(&pz->disc, (char*)io, flags)) || (sp->_file = open("/dev/null", 0)) < 0)
	{
		io->_file = -1;
		sfclose(io);
		free(pz);
		return -1;
	}
	if (path)
		pz->pz->path = path;
	pz->sfdisc.exceptf = sfpzexcept;
	if (flags & PZ_WRITE)
	{
		pz->sfdisc.writef = sfpzwrite;
		pz->io = io;
	}
	else
		pz->sfdisc.readf = sfpzread;
	sfset(sp, SF_SHARE|SF_PUBLIC, 0);
	if (sfdisc(sp, &pz->sfdisc) != &pz->sfdisc)
	{
		close(sp->_file);
		sp->_file = io->_file;
		sfseek(sp, sftell(io), SEEK_SET);
		io->_file = -1;
		pzclose(pz->pz);
		free(pz);
		return -1;
	}
	if (oz)
		oz->flags |= pz->pz->flags & PZ_INTERNAL;
	return 1;
}
Пример #13
0
/*
 * This routine will turn the sftmp() file into a real /tmp file or pipe
 */
void	sh_subtmpfile(int pflag)
{
	Shell_t *shp = &sh;
	int fds[2];
	Sfoff_t off;
	register struct checkpt	*pp = (struct checkpt*)shp->jmplist;
	register struct subshell *sp = subshell_data->pipe;
	if(sfset(sfstdout,0,0)&SF_STRING)
	{
		register int fd;
		/* save file descriptor 1 if open */
		if((sp->tmpfd = fd = fcntl(1,F_DUPFD,10)) >= 0)
		{
			fcntl(fd,F_SETFD,FD_CLOEXEC);
			shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX;
			close(1);
			shp->fdstatus[1] = IOCLOSE;
		}
		else if(errno!=EBADF)
		{
			((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
			shp->toomany = 1;
			errormsg(SH_DICT,ERROR_system(1),e_toomany);
		}
		if(shp->subshare || !pflag)
		{
			sfdisc(sfstdout,SF_POPDISC);
			if((fd=sffileno(sfstdout))>=0)
			{
				shp->fdstatus[fd] = IOREAD|IOWRITE;
				sfsync(sfstdout);
				if(fd==1)
					fcntl(1,F_SETFD,0);
				else
				{
					sfsetfd(sfstdout,1);
					shp->fdstatus[1] = shp->fdstatus[fd];
					shp->fdstatus[fd] = IOCLOSE;
				}
				goto skip;
			}
		}
	}
	if(sp && (shp->fdstatus[1]==IOCLOSE || (!shp->subshare && !(shp->fdstatus[1]&IONOSEEK))))
	{
		struct stat statb,statx;
		int fd;
		sh_pipe(fds);
		sp->pipefd = fds[0];
		sh_fcntl(sp->pipefd,F_SETFD,FD_CLOEXEC);
		/* write the data to the pipe */
		if(off = sftell(sfstdout))
		{
			write(fds[1],sfsetbuf(sfstdout,(Void_t*)sfstdout,0),(size_t)off);
			sfpurge(sfstdout);
		}
		if((sfset(sfstdout,0,0)&SF_STRING) || fstat(1,&statb)<0)
			statb.st_ino = 0;
		sfclose(sfstdout);
		if((sh_fcntl(fds[1],F_DUPFD, 1)) != 1)
			errormsg(SH_DICT,ERROR_system(1),e_redirect);
		sh_close(fds[1]);
		if(statb.st_ino) for(fd=0; fd < 10; fd++)
		{
			if(fd==1 || ((shp->fdstatus[fd]&(IONOSEEK|IOSEEK|IOWRITE))!=(IOSEEK|IOWRITE)) || fstat(fd,&statx)<0)
				continue;
			if(statb.st_ino==statx.st_ino && statb.st_dev==statx.st_dev)
			{
				sh_close(fd);
				fcntl(1,F_DUPFD, fd);
			}
		}
	skip:
		sh_iostream(shp,1);
		sfset(sfstdout,SF_SHARE|SF_PUBLIC,1);
		sfpool(sfstdout,shp->outpool,SF_WRITE);
		if(pp && pp->olist  && pp->olist->strm == sfstdout)
			pp->olist->strm = 0;
	}
}
Пример #14
0
int
b_tee(int argc, register char** argv, void* context)
{
    register Tee_t*		tp = 0;
    register int		oflag = O_WRONLY|O_TRUNC|O_CREAT|O_BINARY;
    register int*		hp;
    register char*		cp;
    int			line;

    if (argc <= 0)
    {
        if (context && (tp = (Tee_t*)sh_context(context)->data))
        {
            sh_context(context)->data = 0;
            tee_cleanup(tp);
        }
        return 0;
    }
    cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_CALLBACK);
    line = -1;
    for (;;)
    {
        switch (optget(argv, usage))
        {
        case 'a':
            oflag &= ~O_TRUNC;
            oflag |= O_APPEND;
            continue;
        case 'i':
            signal(SIGINT, SIG_IGN);
            continue;
        case 'l':
            line = sfset(sfstdout, 0, 0) & SF_LINE;
            if ((line == 0) == (opt_info.num == 0))
                line = -1;
            else
                sfset(sfstdout, SF_LINE, !!opt_info.num);
            continue;
        case ':':
            error(2, "%s", opt_info.arg);
            break;
        case '?':
            error(ERROR_usage(2), "%s", opt_info.arg);
            break;
        }
        break;
    }
    if (error_info.errors)
        error(ERROR_usage(2), "%s", optusage(NiL));
    argv += opt_info.index;
    argc -= opt_info.index;
#if _ANCIENT_BSD_COMPATIBILITY
    if (*argv && streq(*argv, "-"))
    {
        signal(SIGINT, SIG_IGN);
        argv++;
        argc--;
    }
#endif
    if (argc > 0)
    {
        if (tp = (Tee_t*)stakalloc(sizeof(Tee_t) + argc * sizeof(int)))
        {
            memset(&tp->disc, 0, sizeof(tp->disc));
            tp->disc.writef = tee_write;
            if (context)
                sh_context(context)->data = (void*)tp;
            tp->line = line;
            hp = tp->fd;
            while (cp = *argv++)
            {
                if ((*hp = open(cp, oflag, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0)
                    error(ERROR_system(0), "%s: cannot create", cp);
                else
                    hp++;
            }
            if (hp == tp->fd)
                tp = 0;
            else
            {
                *hp = -1;
                sfdisc(sfstdout, &tp->disc);
            }
        }
        else
            error(ERROR_exit(0), "out of space");
    }
    if ((sfmove(sfstdin, sfstdout, SF_UNBOUND, -1) < 0 || !sfeof(sfstdin)) && errno != EPIPE)
        error(ERROR_system(0), "read error");
    if (sfsync(sfstdout))
        error(ERROR_system(0), "write error");
    tee_cleanup(tp);
    return error_info.errors;
}
Пример #15
0
Файл: tstack.c Проект: att/ast
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    Sfio_t *f1, *f2, *f3, *f;
    char *s, *s1, *s2, *s3, *s4;
    int n;
    int fd[2];

    if (!(f1 = sfopen(NULL, tstfile("sf", 0), "w+"))) terror("Opening file1");
    if (!(f2 = sfopen(NULL, tstfile("sf", 0), "w+"))) terror("Opening file2");
    Fclose = f2;
    sfdisc(f1, &Disc);
    sfdisc(f2, &Disc);
    sfstack(f1, f2);
    if ((n = sfgetc(f1)) >= 0 || !sfeof(f1)) terror("There should be no data n=%d", n);
    if (sfstacked(f1)) terror("There should be no stack");
    Fclose = f1;
    if (sfclose(f1) < 0) terror("Can't close f1");
    tcleanup();

    s1 = "1234567890";
    s2 = "abcdefghijklmnopqrstuvwxyz";
    s3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    s4 = "!@#$%^&*()_-+={}[]~`':;?/><,|";

    if (!(f1 = sfopen(NULL, s1, "s")) || !(f2 = sfopen(NULL, s2, "s")) ||
        !(f3 = sfopen(NULL, s3, "s"))) {
        terror("Opening strings");
    }

    sfdisc(sfstdin, &Disc);
    sfclose(sfstdin);
    if (sffileno(sfstdin) != 0) terror("Bad fd for stdin");

    if (!(f = sfopen(NULL, tstfile("sf", 0), "w+"))) terror("Opening file");
    if (sfwrite(f, "0123456789", 10) != 10) terror("Write file");
    if (sfseek(f, (Sfoff_t)0, 0) != 0) terror("Seek file");

    if (sfstack(sfstdin, f) != sfstdin) terror("Stacking on stdin2");
    if (sfopen(sfstdout, "/dev/null", "w") != sfstdout) terror("Opening sfstdout");
    if (sfmove(sfstdin, sfstdout, (Sfoff_t)SF_UNBOUND, -1) != 10 || !sfeof(sfstdin) ||
        sferror(sfstdout)) {
        terror("Bad sfmove");
    }

    tcleanup();

    if (!(f = sftmp(0))) terror("Opening temp file");
    if (sfputr(f, s4, -1) != (ssize_t)strlen(s4)) terror("Writing s4");
    sfseek(f, (Sfoff_t)0, 0);

#if FIX_THIS_TEST_2008_08_11
    if (sfstack(f, f3) != f) terror("Stacking s3");
    if (sfstack(f, f2) != f) terror("Stacking s2");
    if (sfstack(f, f1) != f) terror("Stacking s1");

    sfsprintf(str, sizeof(str), "%s%s%s%s", s1, s2, s3, s4);
    if ((ss = sfgetr(f, '\n', 1)))
        terror("There shouldn't have been any new-line");
    else {
        if (!(ss = sfgetr(f, '\n', -1))) terror("Reading streams");
        n = sfvalue(f);
        if (ss[n]) ss[n] = 0;
    }

    if (strcmp(ss, str) != 0) terror("Expect=%s Got=%s", str, ss);
#endif

    if (!(f1 = sfopen(NULL, s1, "s")) || !(f2 = sfopen(NULL, s2, "s")) ||
        !(f3 = sfopen(NULL, s3, "s"))) {
        terror("Opening strings2");
    }
    sfseek(f, (Sfoff_t)0, 0);

    if (sfstack(f, f3) != f || sfstack(f, f2) != f || sfstack(f, f1) != f) {
        terror("Stacking streams2");
    }

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || s != s1) terror("Sfpeek1");

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || s != s2) terror("Sfpeek2");

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || s != s3) terror("Sfpeek3");

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || strncmp(s, s4, strlen(s4)) != 0) terror("Sfpeek4");

    /* test to see if hidden read data still accessible */
    if (pipe(fd) < 0) terror("Can't create pipe");
    if (!(f1 = sfnew(0, NULL, (size_t)SF_UNBOUND, fd[0], SF_READ | SF_WRITE))) {
        terror("Can't create stream");
    }

    if (write(fd[1], "0123", 4) != 4) terror("Can't write to pipe");
    if (sfgetc(f1) != '0') terror("sfgetc failed");

    /* hack to create hidden reserved buffer */
    f1->file = fd[1];
    if (sfwrite(f1, "4", 1) != 1) terror("Can't write to stream");
    sfsync(f1);
    f1->file = fd[0];
    close(fd[1]);

    /* now stack stream */
    if (!(f2 = sfopen(0, "abcd\n", "s"))) terror("Can't open string stream");

    sfstack(f2, f1);

    if (!(s = sfgetr(f2, '\n', 1))) terror("sfgetr failed");

    if (strcmp(s, "1234abcd") != 0) terror("sfgetr got wrong data");

    texit(0);
}
Пример #16
0
main()
{
	int	n, fd;
	Sfio_t	*f;
	char	*s, buf[1024];
	int	fdv[100];

	buf[0] = 0;
	sfsetbuf(sfstdout,buf,sizeof(buf));
	if(!sfstdout->pool)
		terror("No pool\n");
	sfdisc(sfstdout,&Disc);
	sfset(sfstdout,SF_SHARE,0);
	sfputr(sfstdout,"123456789",0);
	if(strcmp(buf,"123456789") != 0)
		terror("Setting own buffer for stdout\n");
	if(sfpurge(sfstdout) < 0)
		terror("Purging sfstdout\n");

	if((fd = creat("xxx",0666)) < 0)
		terror("Creating xxx\n");

	if(write(fd,buf,sizeof(buf)) != sizeof(buf))
		terror("Writing to xxx\n");
	if(lseek(fd,0L,0) < 0)
		terror("Seeking back to origin\n");

	if(!(f = sfnew((Sfio_t*)0,buf,sizeof(buf),fd,SF_WRITE)))
		terror("Making stream\n");

	if(!(s = sfreserve(f,SF_UNBOUND,1)) || s != buf)
		terror("sfreserve1 returns the wrong pointer\n");
	sfwrite(f,s,0);

#define NEXTFD	12
	if((fd+NEXTFD) < (sizeof(fdv)/sizeof(fdv[0])) )
	{	struct stat	st;
		int		i;
		for(i = 0; i < fd+NEXTFD; ++i)
			fdv[i] = fstat(i,&st);
	}
	if((n = sfsetfd(f,fd+NEXTFD)) != fd+NEXTFD)
		terror("Try to set file descriptor to %d but get %d\n",fd+NEXTFD,n);
	if((fd+NEXTFD) < (sizeof(fdv)/sizeof(fdv[0])) )
	{	struct stat	st;
		int		i;
		for(i = 0; i < fd+NEXTFD; ++i)
			if(i != fd && fdv[i] != fstat(i,&st))
				terror("Fd %d changes status after sfsetfd %d->%d\n",
					i, fd, fd+NEXTFD);
	}

	if(!(s = sfreserve(f,SF_UNBOUND,1)) || s != buf)
		terror("sfreserve2 returns the wrong pointer\n");
	sfwrite(f,s,0);

	if(sfsetbuf(f,NIL(Void_t*),(size_t)SF_UNBOUND) != buf)
		terror("sfsetbuf didnot returns last buffer\n");

	sfsetbuf(f,buf,sizeof(buf));

	if(sfreserve(f,SF_UNBOUND,1) != buf || sfvalue(f) != sizeof(buf) )
		terror("sfreserve3 returns the wrong value\n");
	sfwrite(f,s,0);

	system("rm xxx >/dev/null 2>&1");
	return 0;
}