Exemplo n.º 1
0
Sfio_t*
fdopen(int fd, const char* mode)
{
	int	flags;

	if (fd < 0 || !(flags = _sftype(mode, NiL, NiL)))
		return 0;
	return sfnew(NiL, NiL, (size_t)SF_UNBOUND, fd, flags);
}
Exemplo n.º 2
0
void
getdeltaheader(register Archive_t* ap, register File_t* f)
{
	register char*	s;
	int		n;
	unsigned long	sum;
	Sfio_t*		sp;
	char		c;

	if (!(ap->format->flags & COMPRESSED))
	{
		if (ap->delta && ap->delta->format && (ap->delta->format->variant == DELTA_94 || ap->delta->format->variant == DELTA_IGNORE && state.delta2delta))
		{
			ap->delta->index++;
			if (ap->delta->tab && f->name && (f->delta.base = (Member_t*)hashget(ap->delta->tab, f->name)))
				f->delta.base->mark = 1;
			if (!(ap->format->flags & DELTAINFO))
			{
				if (f->st->st_size <= 0 || bread(ap, &c, (off_t)1, (off_t)1, 1) <= 0)
					f->delta.op = DELTA_create;
				else
				{
					f->st->st_size--;
					f->delta.op = c;
					getdeltaops(ap, f);
					if (f->st->st_size >= 12 && (f->delta.op == DELTA_create || f->delta.op == DELTA_update))
					{
						sum = ap->memsum;
						s = ap->delta->hdrbuf;
						n = 12;
						if (bread(ap, s, (off_t)n, (off_t)n, 1) > 0)
						{
							if (ap->delta->format->variant == DELTA_88)
							{
								unsigned char*	u = (unsigned char*)s;
								int		i;

								i = *u++;
								u += (i >> 3) & 07;
								f->uncompressed = 0;
								i &= 07;
								while (i-- > 0)
									f->uncompressed = f->uncompressed * 256 + *u++;
							}
							else if (sp = sfnew(NiL, s + 4, n, -1, SF_READ|SF_STRING))
							{
								f->uncompressed = sfgetu(sp);
								sfclose(sp);
							}
							bunread(ap, s, n);
						}
						ap->memsum = sum;
					}
				}
Exemplo n.º 3
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);
}
Exemplo n.º 4
0
Arquivo: deparse.c Projeto: att/ast
// Output `here` documents.
static_fn void here_body(const struct ionod *iop) {
    Sfio_t *infile;
#if 0
    // TODO: Figure out if this should be enabled. Originally excluded via `#ifdef xxx`.
    if (iop->iolink) here_body((struct inode *)iop->iolink);
    iop->iolink = 0;
#endif
    if (iop->iofile & IOSTRG) {
        infile = sfnew(NULL, iop->ioname, iop->iosize, -1, SF_STRING | SF_READ);
    } else {
        sfseek(infile = sh.heredocs, iop->iooffset, SEEK_SET);
    }
    sfmove(infile, outfile, iop->iosize, -1);
    if (iop->iofile & IOSTRG) sfclose(infile);
    sfputr(outfile, iop->iodelim, '\n');
}
Exemplo n.º 5
0
/*
 * output here documents
 */
static void here_body(register const struct ionod *iop)
{
	Sfio_t *infile;
#ifdef xxx
	if(iop->iolink)
		here_body((struct inode*)iop->iolink);
	iop->iolink = 0;
#endif
	if(iop->iofile&IOSTRG)
		infile = sfnew((Sfio_t*)0,iop->ioname,iop->iosize,-1,SF_STRING|SF_READ);
	else
		sfseek(infile=sh.heredocs,iop->iooffset,SEEK_SET);
	sfmove(infile,outfile,iop->iosize,-1);
	if(iop->iofile&IOSTRG)
		sfclose(infile);
	sfputr(outfile,iop->iodelim,'\n');
}
Exemplo n.º 6
0
static char *walk_class(register Namval_t *np, int dlete, struct dcclass *dcp)
{
	static Sfio_t *out;
	Sfio_t *outfile;
	int savtop = stktell(stkstd);
	char *savptr =  stkfreeze(stkstd,0);
	if(dlete)
		outfile = 0;
	else if(!(outfile=out))
                outfile = out =  sfnew((Sfio_t*)0,(char*)0,-1,-1,SF_WRITE|SF_STRING);
	else
		sfseek(outfile,0L,SEEK_SET);
	genvalue(outfile,&dcp->sclass,0,np);
	stkset(stkstd,savptr,savtop);
	if(!outfile)
		return((char*)0);
	sfputc(out,0);
	return((char*)out->_data);
}
Exemplo n.º 7
0
tmain()
{
	Sfio_t		*fr;
	int		p[2];
	char		wbuf[1023], rbuf[RBUF*1023], *s;
	int		i, r, n;

	if(pipe(p) < 0 )
		terror("Making pipe for communication");

	if(!(fr = sfnew(0, 0, (size_t)SF_UNBOUND, p[0], SF_READ)) )
		terror("Making read stream");

	for(i = 0; i < sizeof(wbuf); ++i)
		wbuf[i] = (i%10) + '0';

	switch(fork())
	{
		case -1 :
			terror("fork() failed");
		case 0 :
			for(i = 0; i < RBUF*ITER; ++i)
				if(write(p[1], wbuf, sizeof(wbuf)) != sizeof(wbuf))
					terror("Write to pipe failed i=%d", i);
			break;
		default:
			for(i = 0; i < ITER; ++i)
			{	if(sfread(fr, rbuf, sizeof(rbuf)) != sizeof(rbuf))
					terror("Read from pipe failed i=%d", i);
				for(r = 0, s = rbuf; r < RBUF; r += 1, s += n)
				for(n = 0; n < sizeof(wbuf); ++n)
					if(s[n] != (n%10)+'0')
						terror("Bad data i=%d n=%d", i, n);
			}
			break;
	}

	texit(0);
}
Exemplo n.º 8
0
Arquivo: tpkrd.c Projeto: att/ast
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    char *s;
    char buf[1024];
    int n;

    if (pipe(Fd) < 0) terror("Can't make pipe");

    if (sfnew(sfstdin, NULL, (size_t)SF_UNBOUND, Fd[0], SF_READ) != sfstdin) {
        terror("Can't renew stdin");
    }
    sfset(sfstdin, SF_SHARE, 1);

    if (sfpkrd(Fd[0], (void *)buf, 10, -1, 1000, 1) >= 0) terror("There isn't any data yet");

    if ((n = sfpkrd(Fd[0], (void *)buf, sizeof(buf), -1, 0L, 0)) >= 0) {
        terror("Wrong data size %d, expecting < 0", n);
    }

    if (write(Fd[1], "abcd", 4) != 4) terror("Couldn't write to pipe");

    if ((n = sfpkrd(Fd[0], (void *)buf, sizeof(buf), -1, 0L, 0)) != 4) {
        terror("Wrong data size %d, expecting 4", n);
    }

    signal(SIGALRM, alarmhandler);
    alarm(2);
    if (!(s = sfgetr(sfstdin, '\n', 1)) || strcmp(s, "01234") != 0) terror("Expecting 01234");

    if (sfstdin->next < sfstdin->endb) terror("Sfgetr read too much");

    if (!(s = sfgetr(sfstdin, '\n', 1)) || strcmp(s, "56789") != 0) terror("Expecting 56789");

    texit(0);
}
Exemplo n.º 9
0
void HRSstreamStart(HRSstream_t s,
		    void *filterFunction,
                    int numSlices,
		    HRSslice_t slices)
{
  assert(s != NULL);

  if (s->type == HRS_BINARYSTREAM) {
    s->bs->filter = (int (*)(char, void *, char *, char *))filterFunction;
    openFirstBinaryFile(s->bs);
  }
  else if (s->type == HRS_GENERALSTREAM) {
    s->gs->filter = (int (*)(char, void *, Sfio_t *, char *))filterFunction;
    openFirstGeneralFile(s->gs);
  }
  else if (s->type == HRS_GENERATIVESTREAM) {
    s->gens->filter = (int (*)(char, void *, char *))filterFunction;
  }
  else if (s->type == HRS_MAPSTREAM) {
    s->ms->filter = (int (*)(char, void *, char *, char *))filterFunction;
  }

  if (numSlices == 0)
    /* filter only stream */
    s->filterOnly = 1;
  else {
    int from_pipe[2];
    int to_pipe[2];
    int keySize;
    int recSize;
    Sfio_t *tp;
    fchandle *fch;
    int i;

    s->filterOnly = 0;

    /* set up fixcut to munge the data */
    fch = fcopen();
    for (i=0; i < numSlices; i++) {
      int bStrSize = numDigits(slices[i].begin);
      int eStrSize = numDigits(slices[i].end);
      int strSize = bStrSize + 1 + eStrSize + 
	                    strlen(slices[i].description) + 1;
      char *str = HRSmalloc(strSize, "HRSstreamStart");

      sfsprintf(str, strSize, "%d,%d%s", slices[i].begin,
		slices[i].end, slices[i].description);

      if (fcslice(fch, 'k', str) != 0)
	HRSerrorExit1("Fixcut error: %s\n" , fcerror(fch));

      /* do we need to/can we free str here? */
    }

    if ((recSize = fcready(fch, s->logicalSize)) < 0)
      HRSerrorExit1("Fixcut error: %s\n" , fcerror(fch));

    keySize = recSize - s->logicalSize;

    pipe(from_pipe);
    pipe(to_pipe);
    if (fork() == 0) {
      /* child */
      extern int HRSpuntExit;
      int ac;
      char **av;

      HRSpuntExit = 1;   /* don't do any work on exit in the child */

      av = buildSortStr(s, keySize, 0, 1, &ac);
      close(to_pipe[1]);
      close(from_pipe[0]);
      close(0); dup(to_pipe[0]); close(to_pipe[0]);
      close(1); dup(from_pipe[1]); close(from_pipe[1]);

      amrRSORT(ac, av);
      _exit(1);

    }
    else {
      /* parent */
      char *logicalData;
      uchar *mungedData;

      close(to_pipe[0]);
      close(from_pipe[1]);

      tp = sfnew(NULL, NULL, SF_UNBOUND, to_pipe[1], SF_WRITE | SF_SHARE);

      logicalData = HRSmalloc(s->logicalSize, "HRSstreamStart");

      while (getNextElement(s, logicalData) != 0) {
	int v;

	if ((mungedData = fcbuild(fch, (uchar *) logicalData, NULL)) == NULL)
	  HRSerrorExit1("Fixcut error: %s\n" , fcerror(fch));

        v = sfwrite(tp, mungedData, recSize);
	if (v == 0)
	  HRSerrorExit1("stream write to %s failed\n", s->streamName);
      }
      sfclose(tp);
      fcclose(fch);

      s->lfp = 
	sfnew(NULL, NULL, SF_UNBOUND, from_pipe[0], SF_READ | SF_SHARE);

      HRSfree(logicalData);
    }
  }
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
static int
print(Expr_t* ex, Exnode_t* expr, void* env, Sfio_t* sp)
{
	register Print_t*	x;
	Extype_t		v;
	Fmt_t			fmt;

	if (!sp)
	{
		v = eval(ex, expr->data.print.descriptor, env);
		if (v.integer < 0 || v.integer >= elementsof(ex->file) || !(sp = ex->file[v.integer]) && !(sp = ex->file[v.integer] = sfnew(NiL, NiL, SF_UNBOUND, v.integer, SF_READ|SF_WRITE)))
		{
			exerror("printf: %d: invalid descriptor", v.integer);
			return 0;
		}
	}
	memset(&fmt, 0, sizeof(fmt));
	fmt.fmt.version = SFIO_VERSION;
	fmt.fmt.extf = prformat;
	fmt.expr = ex;
	fmt.env = env;
	x = expr->data.print.args;
	if (x->format)
		do
		{
			if (x->arg)
			{
				fmt.fmt.form = x->format;
				fmt.args = x;
				sfprintf(sp, "%!", &fmt);
			}
			else
				sfputr(sp, x->format, -1);
		} while (x = x->next);
	else
	{
		v = eval(ex, x->arg->data.operand.left, env);
		fmt.fmt.form = v.string;
		fmt.actuals = x->arg;
		sfprintf(sp, "%!", &fmt);
		if (fmt.actuals->data.operand.right)
			exerror("printf: \"%s\": too many arguments", fmt.fmt.form);
	}
	if (fmt.tmp)
		sfstrclose(fmt.tmp);
	return 1;
}
Exemplo n.º 12
0
int
sendsmtp(Sfio_t* fp, char* host, char** argv, off_t original)
{
	register char*	s;
	register char*	t;
	char*		e;
	int		n;
	int		fd;
	int		r;
	off_t		z;
	Sfio_t*		sp;
	Sfio_t*		rp;
	char		buf[PATH_MAX];
	char		svc[PATH_MAX];

	/*
	 * connect to the service
	 */

	sfsprintf(svc, sizeof(svc), "/dev/tcp/%s/inet.smtp", host);
	if ((fd = csopen(&cs, svc, 0)) < 0)
	{
		note(SYSTEM, "smtp: %s: cannot connect to service", svc);
		return -1;
	}
	if (!(sp = sfnew(NiL, NiL, SF_UNBOUND, fd, SF_WRITE)) ||
	    !(rp = sfnew(NiL, NiL, SF_UNBOUND, fd, SF_READ)))
	{
		if (sp)
			sfclose(sp);
		else
			close(fd);
		note(SYSTEM, "smtp: %s: cannot buffer service", svc);
		return -1;
	}

	/*
	 * verify
	 */

	do
	{
		if (!(s = sfgetr(rp, '\n', 1)))
			goto bad_recv;
		if (strtol(s, &e, 10) != SMTP_READY)
			goto bad_prot;
	} while (*e == '-');

	/*
	 * identify
	 */

	if (!(s = state.var.domain) || !*s)
		s = state.var.hostname;
	if (sfprintf(sp, "HELO %s\r\n", s) < 0)
		goto bad_send;
	do
	{
		if (!(s = sfgetr(rp, '\n', 1)))
			goto bad_recv;
		if (strtol(s, &e, 10) != SMTP_OK)
			goto bad_prot;
	} while (*(unsigned char*)e == SMTP_OK);

	/*
	 * from
	 */

	if (original)
	{
		if (!(s = sfgetr(fp, '\n', 1)) || !strneq(s, "From ", 5))
			goto bad_mesg;
		for (s += 5; isspace(*s); s++);
		for (t = s; *t && !isspace(*t); t++);
		if (!(n = t - s))
			goto bad_mesg;
		z = sfvalue(fp);
		if (sfprintf(sp, "MAIL FROM:<%*.*s>\r\n", n, n, s) < 0)
			goto bad_send;
	}
	else
	{
		z = 0;
		if ((state.var.domain ?
		     sfprintf(sp, "MAIL FROM:<%s@%s>\r\n", state.var.user, state.var.domain) :
		     sfprintf(sp, "MAIL FROM:<%s>\r\n", state.var.user)) < 0)
			goto bad_send;
	}
	do
	{
		if (!(s = sfgetr(rp, '\n', 1)))
			goto bad_recv;
		if (strtol(s, &e, 10) != SMTP_OK)
			goto bad_prot;
	} while (*e == '-');

	/*
	 * to
	 */

	while (s = *argv++)
	{
		if ((state.var.domain && !strchr(s, '@') ?
		     sfprintf(sp, "RCPT TO:<%s@%s>\r\n", s, state.var.domain) :
		     sfprintf(sp, "RCPT TO:<%s>\r\n", s)) < 0)
			goto bad_send;
		do
		{
			if (!(s = sfgetr(rp, '\n', 1)))
				goto bad_recv;
			if (strtol(s, &e, 10) != SMTP_OK)
				goto bad_prot;
		} while (*e == '-');
	}

	/*
	 * body
	 */

	if (sfprintf(sp, "DATA\r\n") < 0)
		goto bad_send;
	do
	{
		if (!(s = sfgetr(rp, '\n', 1)))
			goto bad_recv;
		if (strtol(s, &e, 10) != SMTP_START)
			goto bad_prot;
	} while (*e == '-');
	tmfmt(buf, sizeof(buf), "%+uDate: %a, %d %b %Y %H:%M:%S UT", NiL);
	if (sfputr(sp, buf, '\n') < 0)
		goto bad_send;
	if (sfprintf(sp, "From: <%s@%s>\n", state.var.user, host) < 0)
		goto bad_send;
	while (s = sfgetr(fp, '\n', 1))
	{
		if (sfprintf(sp, "%s%s\r\n", *s == '.' ? "." : "", s) < 0)
			goto bad_send;
		if (original && (z += sfvalue(fp)) >= original)
			break;
	}
	if (sfprintf(sp, ".\r\n") < 0)
		goto bad_send;
	do
	{
		if (!(s = sfgetr(rp, '\n', 1)))
			goto bad_recv;
		if (strtol(s, &e, 10) != SMTP_OK)
			goto bad_prot;
	} while (*e == '-');

	/*
	 * quit
	 */

	if (sfprintf(sp, "QUIT\r\n") < 0)
		goto bad_send;
	do
	{
		if (!(s = sfgetr(rp, '\n', 1)))
			goto bad_recv;
		if (strtol(s, &e, 10) != SMTP_CLOSE)
			goto bad_prot;
	} while (*e == '-');
	r = 0;
	goto done;
 bad_mesg:
	note(0, "smtp: bad message -- no From header");
	goto bad;
 bad_prot:
	if ((n = strlen(e)) > 0 && e[n - 1] == '\r')
		e[n - 1] = 0;
	note(0, "smtp: %s: service error:%s", svc, e);
	goto bad;
 bad_send:
	note(SYSTEM, "smtp: %s: service write error", svc);
	goto bad;
 bad_recv:
	note(SYSTEM, "smtp: %s: service read error", svc);
 bad:
	r = -1;
 done:
	sfclose(sp);
	sfclose(rp);
	return r;
}
Exemplo n.º 13
0
Arquivo: misc.c Projeto: att/ast
int b_dot_cmd(int n, char *argv[], Shbltin_t *context) {
    char *script;
    Namval_t *np;
    int jmpval;
    Shell_t *shp = context->shp;
    struct sh_scoped savst, *prevscope = shp->st.self;
    int fd;
    char *filename = NULL;
    char *buffer = NULL;
    struct dolnod *saveargfor = NULL;
    volatile struct dolnod *argsave = NULL;
    checkpt_t buff;
    Sfio_t *iop = NULL;
    short level;
    Optdisc_t disc;

    memset(&disc, 0, sizeof(disc));
    disc.version = OPT_VERSION;
    opt_info.disc = &disc;

    while ((n = optget(argv, sh_optdot))) {
        switch (n) {
            case ':': {
                errormsg(SH_DICT, 2, "%s", opt_info.arg);
                break;
            }
            case '?': {
                errormsg(SH_DICT, ERROR_usage(0), "%s", opt_info.arg);
                return 2;
            }
            default: { break; }
        }
    }

    argv += opt_info.index;
    script = *argv;
    if (error_info.errors || !script) {
        errormsg(SH_DICT, ERROR_usage(2), "%s", optusage(NULL));
        __builtin_unreachable();
    }
    if (shp->dot_depth + 1 > DOTMAX) {
        errormsg(SH_DICT, ERROR_exit(1), e_toodeep, script);
        __builtin_unreachable();
    }
    np = shp->posix_fun;
    if (!np) {
        // Check for KornShell style function first.
        np = nv_search(script, shp->fun_tree, 0);
        if (np && is_afunction(np) && !nv_isattr(np, NV_FPOSIX)) {
            if (!FETCH_VT(np->nvalue, ip)) {
                // TODO: Replace this with a comment explaining why the return value of this
                // path_search() call is ignored. At the time I wrote this (2019-03-16) no unit test
                // exercises this statement. I added the void cast to silence Coverity Scan 253792.
                (void)path_search(shp, script, NULL, 0);
                if (FETCH_VT(np->nvalue, ip)) {
                    if (nv_isattr(np, NV_FPOSIX)) np = NULL;
                } else {
                    errormsg(SH_DICT, ERROR_exit(1), e_found, script);
                    __builtin_unreachable();
                }
            }
        } else {
            np = NULL;
        }

        if (!np) {
            fd = path_open(shp, script, path_get(shp, script));
            if (fd < 0) {
                errormsg(SH_DICT, ERROR_system(1), e_open, script);
                __builtin_unreachable();
            }
            filename = path_fullname(shp, stkptr(shp->stk, PATH_OFFSET));
        }
    }
    *prevscope = shp->st;
    shp->st.lineno = np ? ((struct functnod *)nv_funtree(np))->functline : 1;
    shp->st.var_local = shp->st.save_tree = shp->var_tree;
    if (filename) {
        shp->st.filename = filename;
        shp->st.lineno = 1;
    }
    level = shp->fn_depth + shp->dot_depth + 1;
    nv_putval(SH_LEVELNOD, (char *)&level, NV_INT16);
    shp->st.prevst = prevscope;
    shp->st.self = &savst;
    shp->topscope = (Shscope_t *)shp->st.self;
    prevscope->save_tree = shp->var_tree;
    if (np) {
        struct Ufunction *rp = FETCH_VT(np->nvalue, rp);
        shp->st.filename = strdup(rp->fname ? rp->fname : "");
    }
    nv_putval(SH_PATHNAMENOD, shp->st.filename, NV_NOFREE);
    shp->posix_fun = NULL;
    if (np || argv[1]) argsave = sh_argnew(shp, argv, &saveargfor);
    sh_pushcontext(shp, &buff, SH_JMPDOT);
    jmpval = sigsetjmp(buff.buff, 0);
    if (jmpval == 0) {
        shp->dot_depth++;
        if (np) {
            sh_exec(shp, (Shnode_t *)(nv_funtree(np)), sh_isstate(shp, SH_ERREXIT));
        } else {
            buffer = malloc(IOBSIZE + 1);
            iop = sfnew(NULL, buffer, IOBSIZE, fd, SF_READ);
            sh_offstate(shp, SH_NOFORK);
            sh_eval(shp, iop, sh_isstate(shp, SH_PROFILE) ? SH_FUNEVAL : 0);
        }
    }
    sh_popcontext(shp, &buff);
    if (buffer) free(buffer);
    if (!np) {
        free(shp->st.filename);
        shp->st.filename = NULL;
    }
    shp->dot_depth--;
    if ((np || argv[1]) && jmpval != SH_JMPSCRIPT) {
        sh_argreset(shp, (struct dolnod *)argsave, saveargfor);
    } else {
        prevscope->dolc = shp->st.dolc;
        prevscope->dolv = shp->st.dolv;
    }
    if (shp->st.self != &savst) *shp->st.self = shp->st;
    // Only restore the top Shscope_t portion for posix functions.
    memcpy(&shp->st, prevscope, sizeof(Shscope_t));
    shp->topscope = (Shscope_t *)prevscope;
    nv_putval(SH_PATHNAMENOD, shp->st.filename, NV_NOFREE);
    if (jmpval && jmpval != SH_JMPFUN) siglongjmp(shp->jmplist->buff, jmpval);
    return shp->exitval;
}
Exemplo n.º 14
0
Arquivo: tstack.c Projeto: 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);
}
Exemplo n.º 15
0
static int
scan(Expr_t* ex, Exnode_t* expr, void* env, Sfio_t* sp)
{
	Extype_t		v;
	Extype_t		u;
	Fmt_t			fmt;
	int			n;

	if (!sp)
	{
		if (expr->data.scan.descriptor)
		{
			v = eval(ex, expr->data.scan.descriptor, env);
			if (expr->data.scan.descriptor->type == STRING)
				goto get;
		}
		else
			v.integer = 0;
		if (v.integer < 0 || v.integer >= elementsof(ex->file) || !(sp = ex->file[v.integer]) && !(sp = ex->file[v.integer] = sfnew(NiL, NiL, SF_UNBOUND, v.integer, SF_READ|SF_WRITE)))
		{
			exerror("scanf: %d: invalid descriptor", v.integer);
			return 0;
		}
	}
 get:
	memset(&fmt, 0, sizeof(fmt));
	fmt.fmt.version = SFIO_VERSION;
	fmt.fmt.extf = scformat;
	fmt.expr = ex;
	fmt.env = env;
	u = eval(ex, expr->data.scan.format, env);
	fmt.fmt.form = u.string;
	fmt.actuals = expr->data.scan.args;
	n = sp ? sfscanf(sp, "%!", &fmt) : sfsscanf(v.string, "%!", &fmt);
	if (fmt.actuals && !*fmt.fmt.form)
		exerror("scanf: %s: too many arguments", fmt.actuals->data.operand.left->data.variable.symbol->name);
	return n;
}
Exemplo n.º 16
0
Arquivo: pack.c Projeto: DataIX/ast
int
main(int argc, register char *argv[])
{
	static char command[] = "pack";
	register Huff_t	*hp;
	register char	*infile,*outfile;
	Sfio_t		*fpin,*fpout;
	int		nfile=0, npack=0, force=0, verbose=0;
	int		out, deleted, dsize, n;
	struct stat	statb;

	NOT_USED(argc);
	error_info.id = command;
	while(n = optget(argv,usage)) switch(n)
	{
	case 'f':
		force++;
		break;
	case 'v':
		verbose = !verbose;
		break;
	case ':':
		error(2, opt_info.arg);
		break;
	case '?':
		error(ERROR_usage(2), "%s", opt_info.arg);
		break;
	}
	argv += opt_info.index;
	if(error_info.errors || !*argv)
		error(ERROR_usage(2), "%s", optusage((char*)0));

	while (infile = *argv++)
	{
		if(*infile == '-')
		{
			/* awful way to handle options, but preserves SVID */
			switch(infile[1])
			{
				case 'f':
					force++;
					continue;
				case 0:
					verbose = !verbose;
					continue;
			}
		}
		nfile++;
		fpin = fpout = (Sfio_t*)0;
		hp = (Huff_t*)0;
		deleted = 0;
		if(!(outfile = outname(infile)))
			continue;
		if (!(fpin=sfopen((Sfio_t*)0,infile,"r")))
			error(ERROR_system(0), "%s: cannot open", infile);
		else if(fstat(sffileno(fpin),&statb) < 0)
			error(ERROR_system(0), "%s: cannot stat", infile);
		else if(S_ISDIR(statb.st_mode))
			error(2, "%s: cannot pack a directory", infile);
		else if(statb.st_nlink > 1)
			error(2, "%s: has links", infile);
		else if(statb.st_size ==0)
			error(2, "%s: cannot pack a zero length file", infile);
		else if(access(outfile,F_OK) ==0)
			error(ERROR_system(0), "%s: already exists", outfile);
		else if(((out=open(outfile,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,PERM(statb.st_mode))) < 0) ||
			!(fpout = sfnew((Sfio_t*)0,(char*)0,SF_UNBOUND,out,SF_WRITE)))
			error(ERROR_system(0), "%s: cannot create", outfile);
		else if((deleted++,chmod(outfile,statb.st_mode)) < 0)
			error(ERROR_system(0), "%s: cannot change mode to %o",outfile,statb.st_mode);
		else
		{
			chown(outfile,statb.st_uid,statb.st_gid);
			if(!(hp = huffinit(fpin,(Sfoff_t)-1)))
				error(2, "%s: read error", infile);
			else if(sfseek(fpin,(Sfoff_t)0,0) < 0)
				error(ERROR_system(0),"%s: seek error", infile);
			else if((dsize = huffputhdr(hp,fpout)) < 0)
				error(2, "%s: write error", infile);
			else if(!force && block(huffisize(hp)) <= block(huffosize(hp)+dsize))
				error(2, "%s:no savings - file unchanged", infile);
			else if(huffencode(hp,fpin,fpout,SF_UNBOUND)<0)
				error(2, "%s: read error", infile);
			else
			{
				double diff;
				if(remove(infile) < 0)
					error(ERROR_system(0), "%s: cannot remove", infile);
				diff = huffisize(hp) - (dsize+huffosize(hp));
				sfprintf(sfstdout,"%s: %s : %.1f%% Compression\n",command,
					infile,(100*diff)/((double)huffisize(hp)));
				if(verbose)
					vprint(hp,dsize);
				npack++;
				deleted = 0;
			}
		}
		if(hp)
			huffend(hp);
		if(fpin)
			sfclose(fpin);
		if(fpout)
			sfclose(fpout);
		if(deleted)
			remove(outfile);
		if(outfile)
			free(outfile);
	}
	nfile -= npack;
	if(nfile > 125)
		nfile = 125;
	exit(nfile);
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
0
Arquivo: history.c Projeto: 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;
}
Exemplo n.º 19
0
Arquivo: tsize.c Projeto: att/ast
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    Sfio_t *f, *f2;
    char *s;
    int i, n;
    char buf[16 * 1024];

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

    if (sfnputc(f, 'a', 1000) != 1000) terror("Writing");

    if (sfseek(f, (Sfoff_t)0, 0) != 0) terror("Seeking");

    if ((n = (int)sfsize(f)) != 1000) terror("Wrong size %d", n);

    if (!(f2 = sfnew(NULL, NULL, (size_t)SF_UNBOUND, sffileno(f), SF_WRITE))) {
        terror("Can't open stream");
    }

    if (sfseek(f2, (Sfoff_t)1999, 0) != (Sfoff_t)1999) terror("Seeking2");
    sfputc(f2, 'b');
    sfsync(f2);
    if ((n = (int)sfsize(f2)) != 2000) terror("Wrong size2 %d", n);

    if ((n = (int)sfsize(f)) != 1000) terror("Wrong size3 %d", n);

    sfputc(f, 'a');
    sfset(f, SF_SHARE, 1);
    if ((n = (int)sfsize(f)) != 2000) terror("Wrong size4 %d", n);

    if (!(f = sfopen(f, NULL, "srw"))) terror("Can't open string stream");

    sfwrite(f, "0123456789", 10);
    if (sfsize(f) != 10) terror("String size is wrong1");
    sfseek(f, (Sfoff_t)19, 0);
    if (sfsize(f) != 10) terror("String size is wrong2");
    sfputc(f, 'a');
    if (sfsize(f) != 20) terror("String size is wrong3");
    sfseek(f, (Sfoff_t)0, 0);
    if (sfsize(f) != 20) terror("String size is wrong4");
    sfseek(f, (Sfoff_t)0, 0);
    if (!(s = sfreserve(f, SF_UNBOUND, SF_LOCKR)) && sfvalue(f) != 20) {
        terror("String size is wrong5");
    }
    sfread(f, s, 5);
    if (sfsize(f) != 20) terror("String size is wrong6");
    sfwrite(f, "01234567890123456789", 20);
    if (sfsize(f) != 25) terror("String size is wrong7");

    strcpy(buf, "0123456789");
    if (!(f = sfopen(f, buf, "s+"))) terror("Can't open string stream2");
    if (sfset(f, 0, 0) & SF_MALLOC) terror("SF_MALLOC should not have been set");
    if (sfsize(f) != 10) terror("String size is wrong8");
    sfread(f, buf, 5);
    if ((n = (int)sfwrite(f, "0123456789", 10)) != 5) terror("Write wrong amount %d", n);
    if (sfsize(f) != 10) terror("String size is wrong9");

    if (!(f = sfopen(f, tstfile("sf", 0), "w"))) terror("Reopening file1");
    for (i = 0; i < 10000; ++i) {
        if (sfputc(f, '0' + (i % 10)) != '0' + (i % 10)) terror("sfputc failed");
    }

    if (!(f = sfopen(f, tstfile("sf", 0), "r+"))) terror("Reopening file2");
    if (sfsize(f) != 10000) terror("Bad size of file1");

    sfsetbuf(f, buf, 1024);
    for (i = 0; i < 20; ++i) {
        if (!sfreserve(f, 100, 0)) terror("Reserve failed");
    }

    s = buf + 1024;
    for (i = 0; i < 20; ++i) s[i] = '0' + i % 10;
    sfseek(f, (Sfoff_t)(10000 - 10), 0);
    if (sfwrite(f, s, 20) != 20) terror("Write failed");
    if (sfsize(f) != 10010) terror("Bad size of file2");
    sfseek(f, (Sfoff_t)0, 0);
    for (i = 0; i < 10; ++i) {
        if (!(s = sfreserve(f, 1001, 0))) terror("Reserve failed2");
        if (s[0] != '0' + i) terror("Bad data1");
    }
    for (n = 0; n < 1001; ++n) {
        if (s[n] != ((n + i - 1) % 10 + '0')) terror("Bad data");
    }

    /* test to see if a string stream extends ok during writes */
    s = malloc(5);
    f = sfnew(NULL, (void *)s, 5, -1, SF_STRING | SF_READ | SF_WRITE | SF_MALLOC);
    if (!f) terror("Can't create string stream");
    if (sfwrite(f, "01", 2) != 2) terror("Bad write to string stream");
    if (sfwrite(f, "2345678", 7) != 7) terror("Bad write to string stream2");
    if (sfputc(f, 0) != 0) terror("sfputc failed");
    if (sfseek(f, (Sfoff_t)0, 0) != 0) terror("sfseek failed");
    if ((n = (int)sfread(f, buf, 100)) != 10) terror("sfread gets wrong amount of data %d", n);
    if (strcmp(buf, "012345678") != 0) terror("Get wrong data");

    texit(0);
}