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); }
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; } }
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); }
// 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'); }
/* * 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'); }
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); }
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); }
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); }
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); } } }
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; }
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; }
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; }
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; }
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); }
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; }
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); }
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; }
// // 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; }
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); }