Exemple #1
0
static char*
getfile(void)
{
	register char*	s;
	register int	n;
	register int	m;

	if (!(s = sfgetr(ed.iop, '\n', 1))) {
		if (!(s = sfgetr(ed.iop, '\n', -1)))
			return 0;
		ed.warn_newline = 1;
	}
	if ((n = sfvalue(ed.iop)) > 0 && s[n - 1] == '\r')
		s[--n] = 0;
	if ((m = strlen(s)) < n) {
		register char*	t;
		register char*	u;
		register char*	x;

		t = u = s + m;
		x = s + n;
		while (u < x)
			if (!(*t++ = *u++))
				t--;
		*t++ = 0;
		n = t - s;
		ed.warn_null += x - t;
	}
	ed.bytes += n;
	ed.lines++;
	return s;
}
Exemple #2
0
/*
 * Handles paste -s, for file <in> to file <out> using delimiters <delim>
 */
static int spaste(Sfio_t *in,register Sfio_t* out,register const char *delim,int dsiz,int dlen,Delim_t* mp)
{
	register const char *cp;
	register int d=0;
	if((cp = sfgetr(in,'\n',0)) && sfwrite(out,cp,sfvalue(in)-1) < 0)
		return(-1);
	while(cp=sfgetr(in, '\n',0)) 
	{
		if(dlen)
		{
			register int c;
			if(d >= dlen)
				d = 0;
			if(mp)
				sfwrite(out,mp[d].chr,mp[d].len);
			else if(c=delim[d])
				sfputc(out,c);
			d++;
		}
		if(sfwrite(out,cp,sfvalue(in)-1) < 0)
			return(-1);
	}
	sfputc(out,'\n');
	return(0);
}
Exemple #3
0
MAIN()
{
	Sfio_t*	f;
	char	buf[1024], *s;
	int	n;
#ifdef DEBUG
	Sfio_t*	logf = sfopen(0,"LOG","a"); sfsetbuf(logf,NIL(Void_t*),0);
#endif

	alarm(10);
	if(argc > 1)
	{	/* coprocess only */
		while((s = sfreserve(sfstdin,-1,0)) )
		{
#ifdef DEBUG
			sfwrite(logf, s, sfvalue(sfstdin));
#endif
			sfwrite(sfstdout, s, sfvalue(sfstdin));
		}
		return 0;
	}

	/* make coprocess */
	if(!(f = sfpopen(NIL(Sfio_t*), sfprints("%s -p",argv[0]), "r+")))
		terror("Opening for read/write\n");
	for(n = 0; n < 10; ++n)
	{	sfsprintf(buf,sizeof(buf),"Line %d",n);
		sfputr(f,buf,'\n');
		if(!(s = sfgetr(f,'\n',1)))
			terror("Did not read back line\n");
		if(strcmp(s,buf) != 0)
			terror("Input=%s, Expect=%s\n",s,buf);
	}

	if(sfputr(f,"123456789",'\n') != 10)
		terror("Bad write");

	if(sfread(f,buf,3) != 3)
		terror("Did not get data back\n");
	if(strncmp(s,"123",3) != 0)
		terror("Wrong data\n");

	if(sfwrite(f,"aaa",3) != 3 || sfputc(f,'\n') != '\n')
		terror("Fail on write\n");

	if(!(s = sfgetr(f,'\n',1)) )
		terror("Should have gotten 456789\n"); 
	if(strcmp(s,"456789") != 0)
		terror("Wrong data2\n");

	if(!(s = sfgetr(f,'\n',1)) )
		terror("Should have gotten aaa\n"); 
	if(strcmp(s,"aaa") != 0)
		terror("Wrong data3\n");

	sfclose(f);
	
	TSTEXIT(0);
}
Exemple #4
0
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    Sfio_t *f;
    char *str, *alpha, *s;
    char buf[128];
    int n;

    str = "0123456789";
    alpha = "abcdefghijklmnop";

    if (!(f = sfopen(NULL, alpha, "s"))) terror("Opening stream");

    for (n = 9; n >= 0; --n) {
        if (sfungetc(f, n + '0') != n + '0') terror("Ungetc");
    }

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || sfvalue(f) != 10) terror("Peek stream1");
    if (strncmp(s, str, 10) != 0) terror("Bad data1");

    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || sfvalue(f) != (ssize_t)strlen(alpha)) {
        terror("Peek stream2");
    }
    if (strncmp(s, alpha, strlen(alpha)) != 0) terror("Bad data2");

    sfseek(f, (Sfoff_t)0, 0);
    for (n = 9; n >= 0; --n) {
        if (sfungetc(f, n + '0') != n + '0') terror("Ungetc2");
    }
    if (sfgetc(f) != '0') terror("Sfgetc");
    sfseek(f, (Sfoff_t)0, 0);
    if (!(s = sfreserve(f, SF_UNBOUND, 0)) || sfvalue(f) != (ssize_t)strlen(alpha)) {
        terror("Peek stream3");
    }
    if (strncmp(s, alpha, strlen(alpha)) != 0) terror("Bad data2");

    sfseek(f, (Sfoff_t)0, 0);
    if (sfungetc(f, '0') != '0') terror("Ungetc3");

    strcpy(buf, "0123456789\n");
    if (!(f = sfopen(f, buf, "s+"))) terror("Reopening  string");
    if (sfungetc(f, '\n') != '\n') terror("Can't unget new-line2");
    if (sfungetc(f, 'd') != 'd') terror("Can't unget d");
    if (sfungetc(f, 'c') != 'c') terror("Can't unget c");
    if (sfungetc(f, '\n') != '\n') terror("Can't unget new-line");
    if (sfungetc(f, 'b') != 'b') terror("Can't unget b");
    if (sfungetc(f, 'a') != 'a') terror("Can't unget a");

    if (!(s = sfgetr(f, '\n', 1)) || strcmp(s, "ab") != 0) terror("Did not get ab");
    if (!(s = sfgetr(f, '\n', 1)) || strcmp(s, "cd") != 0) terror("Did not get cd");
    if (!(s = sfgetr(f, '\n', 1)) || strcmp(s, "0123456789") != 0) terror("Did not get 0123456789");

    texit(0);
}
Exemple #5
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);
}
Exemple #6
0
tmain()
{
	Sfio_t*	f1;
	Sfio_t* f2;
	char*	s;

	if(!(f1 = sfopen(NIL(Sfio_t*), tstfile("sf", 0),"w+")) )
		terror("Can't open file");
	if(sfwrite(f1,"0123456789\n",11) != 11)
		terror("Can't write to file");

	sfclose(sfstdin);
	if(sfswap(f1,sfstdin) != sfstdin)
		terror("Can't swap with sfstdin");
	sfseek(sfstdin,(Sfoff_t)0,0);
	if(!(s = sfgetr(sfstdin,'\n',1)) )
		terror("sfgetr failed");
	if(strcmp(s,"0123456789") != 0)
		terror("Get wrong data");

	if(!(f1 = sfswap(sfstdin,NIL(Sfio_t*))) )
		terror("Failed swapping to NULL");
	if(!sfstack(sfstdout,f1) )
		terror("Failed stacking f1");

	if(!(f2 = sfopen(NIL(Sfio_t*), tstfile("sf", 0), "r")) )
		terror("Can't open for read");

	if(sfswap(f1,f2) != NIL(Sfio_t*) )
		terror("sfswap should have failed");

	texit(0);
}
int timerangesload (char *file, int size) {
    Sfio_t *fp;
    char *line, *s1, *s2;
    int trm;

    trm = 0, trn = atoi (getenv ("TIMERANGESSIZE"));
    if (trn > 0) {
        if (!(trs = vmalloc (Vmheap, sizeof (timerange_t) * trn)))
            SUerror ("vg_timeranges", "cannot allocate trs");
        memset (trs, 0, sizeof (timerange_t) * trn);
        if (!(fp = sfopen (NULL, getenv ("TIMERANGESFILE"), "r")))
            SUerror ("vg_timeranges", "cannot open inv filter file");
        while ((line = sfgetr (fp, '\n', 1))) {
            if (!(s1 = strchr (line, '|'))) {
                SUwarning (0, "vg_timeranges", "bad line: %s", line);
                break;
            }
            *s1++ = 0;
            trs[trm].ft = strtoll (line, &s2, 10);
            trs[trm].lt = strtoll (s1, &s2, 10);
            trm++;
        }
        sfclose (fp);
    }
    if (trm != trn)
        trn = -1;

    return 0;
}
Exemple #8
0
int EMinit (char *file) {
    Sfio_t *fp;
    char *line, *s1;

    EMops = NULL;
    EMopn = EMopm = 0;
    if (!(imagedict = dtopen (&imagedisc, Dtset))) {
        SUwarning (0, "EMinit", "cannot create imagedict");
        return -1;
    }
    if (!(nodedict = dtopen (&nodedisc, Dtset))) {
        SUwarning (0, "EMinit", "cannot create nodedict");
        return -1;
    }
    if (!(edgedict = dtopen (&edgedisc, Dtset))) {
        SUwarning (0, "EMinit", "cannot create edgedict");
        return -1;
    }

    if (!(fp = sfopen (NULL, file, "r")))
        SUerror ("EMinit", "cannot open file %s", file);
    while ((line = sfgetr (fp, '\n', 1))) {
        if (!(s1 = strchr (line, '|'))) {
            SUwarning (0, "EMinit", "bad line: %s", line);
            continue;
        }
        *s1++ = 0;
        if (load (line, s1) == -1)
            SUerror ("EMinit", "cannot load embed file %s", line);
    }
    sfclose (fp);

    return 0;
}
Exemple #9
0
extern char*	getpass(const char *prompt)
{
	struct termios told,tnew;
	Sfio_t *iop;
	static char *cp, passwd[32];
	void (*savesig)(int);
	if(!(iop = sfopen((Sfio_t*)0, "/dev/tty", "r")))
		return(0);
	if(tcgetattr(sffileno(iop),&told) < 0)
		return(0);
	interrupt = 0;
	tnew = told;
	tnew.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL);
	if(tcsetattr(sffileno(iop),TCSANOW,&tnew) < 0)
		return(0);
	savesig = signal(SIGINT, handler);
	sfputr(sfstderr,prompt,-1);
	if(cp = sfgetr(iop,'\n',1))
		strncpy(passwd,cp,sizeof(passwd)-1);
	tcsetattr(sffileno(iop),TCSANOW,&told);
	sfputc(sfstderr,'\n');
	sfclose(iop);
	signal(SIGINT, savesig);
	if(interrupt)
		kill(getpid(),SIGINT);
	return(cp?passwd:0);
}
Exemple #10
0
static void
splice(void)
{
	char*	s;
	int	n;

	if (ed.spend) {
		if (!ed.spl && !(ed.spl = sfstropen()))
			error(ERROR_SYSTEM|3, "cannot initialize splice buffer");
		sfwrite(ed.spl, ed.spbeg, ed.spend - ed.spbeg);
		ed.spend = 0;
		sfputc(ed.spl, '\n');
		while (s = sfgetr(sfstdin, '\n', 1)) {
			if ((n = sfvalue(sfstdin) - 1) > 0 && s[n - 1] == '\r')
				n--;
			if (n > 0 && s[n - 1] == '\\') {
				sfwrite(ed.spl, s, n - 1);
				sfputc(ed.spl, '\n');
			}
			else {
				sfwrite(ed.spl, s, n);
				break;
			}
		}
		if (!(s = sfstruse(ed.spl)))
			error(ERROR_SYSTEM|3, "out of space");
		ed.input = s + (ed.input - ed.spbeg);
	}
}
Exemple #11
0
static int loadnpanxx (char *file) {
    Sfio_t *fp;
    char *s, *line, *avs[10];

    SUmessage (1, "loadnpanxx", "loading file %s", file);
    if (!(fp = sfopen (NULL, file, "r"))) {
        SUwarning (1, "loadnpanxx", "open failed for file %s", file);
        return -1;
    }
    while ((line = sfgetr (fp, '\n', 1))) {
        if (line[strlen (line) - 1] == '\r')
            line[strlen (line) - 1] = 0;
        if (tokscan (
            line, &s, "%s:%s:%s:%s\n", &avs[0], &avs[1], &avs[2], &avs[3]
        ) != 4) {
            SUwarning (1, "loadnpanxx", "bad line in file %s, %s", file, line);
            continue;
        }
        if (additem (avs[0], avs[1], avs[2], avs[3]) == -1) {
            SUwarning (1, "loadnpanxx", "additem failed");
            return -1;
        }
    }
    sfclose (fp);
    return 0;
}
Exemple #12
0
static int
getchr(void)
{
	int	n;

	if (ed.lastc = ed.peekc) {
		ed.peekc = 0;
		return ed.lastc;
	}
	if (ed.global) {
		if (ed.lastc = *ed.global++)
			return ed.lastc;
		ed.global = 0;
		return EOF;
	}
	if (!ed.input) {
		if (!(ed.input = sfgetr(sfstdin, '\n', 1))) {
			trap();
			return EOF;
		}
		if ((n = sfvalue(sfstdin) - 2) >= 0 && ed.input[n] == '\r')
			ed.input[n--] = 0;
		ed.spbeg = ed.input;
		ed.spend = (n >= 0 && ed.input[n] == '\\') ? (ed.input + n) : (char*)0;
	}
	if (!(ed.lastc = *ed.input++)) {
		ed.input = 0;
		ed.lastc = '\n';
	}
	return ed.lastc;
}
Exemple #13
0
static int paste(int nstream,Sfio_t* streams[],Sfio_t *out, register const char *delim, int dsiz, int dlen, Delim_t* mp)
{
	register const char *cp;
	register int d, n, i, z, more=1;
	register Sfio_t *fp;
	do
	{
		d = (dlen>0?0:-1);
		for(n=more-1,more=0; n < nstream;)
		{
			if(fp=streams[n])
			{
				if(cp = sfgetr(fp,'\n',0))
				{
					if(n==0)
						more = 1;
					else if(!more) /* first stream with output */
					{
						if(dsiz == 1)
							sfnputc(out, *delim, n);
						else if(dlen>0)
						{
							for(d=n; d>dlen; d-=dlen)
								sfwrite(out,delim,dsiz);
							if(d)
							{
								if(mp)
									for (i = z = 0; i < d; i++)
										z += mp[i].len;
								else
									z = d;
								sfwrite(out,delim,z);
							}
						}
						more = n+1;
					}
					if(sfwrite(out,cp,sfvalue(fp)-((n+1)<nstream)) < 0)
						return(-1);
				}
				else
					streams[n] = 0;
			}
			if(++n<nstream && more && d>=0)
			{
				register int c;
				if(d >= dlen)
					d = 0;
				if(mp)
					sfwrite(out,mp[d].chr,mp[d].len);
				else if(c=delim[d])
					sfputc(out,c);
				d++;
			}
			else if(n==nstream && !streams[n-1] && more)
				sfputc(out,'\n');
		}
	} while(more);
	return(0);
}
Exemple #14
0
tmain() {
    UNUSED(argc);
    UNUSED(argv);
    Sfio_t *f1, *f2;
    char *s;
    Sfoff_t p;
    char buf[1024];
    int r, w;

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

    if (!(f2 = sfopen(NULL, tstfile("sf", 0), "a+"))) terror("Can't open f2");

    if (sfwrite(f1, "012345678\n", 10) != 10 || sfsync(f1) < 0) terror("Writing to f1");
    if ((p = sftell(f1)) != 10) terror("Bad sftell1 %ld", p);

    if (sfwrite(f2, "abcdefghi\n", 10) != 10 || sfsync(f2) < 0) terror("Writing to f2");
    if ((p = sftell(f2)) != 20) terror("Bad sftell2");

    if ((p = sfseek(f1, (Sfoff_t)0, 0)) != 0) terror("Bad seek");
    if (!(s = sfgetr(f1, '\n', 1))) terror("Bad getr1");
    if (strcmp(s, "012345678") != 0) terror("Bad input1");

    if ((p = sftell(f1)) != 10) terror("Bad sftell3");

    if (sfwrite(f1, "012345678\n", 10) != 10 || sfsync(f1) < 0) terror("Writing to f1");
    if ((p = sftell(f1)) != 30) terror("Bad sftell4");

    if ((p = sfseek(f2, (Sfoff_t)10, 0)) != 10) terror("Bad seek");
    if (!(s = sfgetr(f2, '\n', 1))) terror("Bad getr2");
    if (strcmp(s, "abcdefghi") != 0) terror("Bad input2");

    if (!(s = sfgetr(f2, '\n', 1))) terror("Bad getr3");
    if (strcmp(s, "012345678") != 0) terror("Bad input3");

    if (!(f1 = sfopen(f1, tstfile("sf", 0), "w"))) terror("Can't open file to write");
    for (r = 0; r < 1024; ++r) buf[r] = 'a';
    if ((w = sfwrite(f1, buf, 1024)) != 1024) terror("writing w=%d", w);
    if (!(f1 = sfopen(f1, tstfile("sf", 0), "a"))) terror("Can't open file to append");
    sfseek(f1, (Sfoff_t)0, 0);
    if ((w = sfwrite(f1, buf, 64)) != 64) terror("writing w=%d", w);
    if ((r = (int)sftell(f1)) != (1024 + 64)) terror("seek position wrong s=%d", r);

    texit(0);
}
Exemple #15
0
static char*
lineget(off_t off)
{
	char*	s;

	off &= ~(LINE_GLOBAL|LINE_MARKED);
	if (sfseek(ed.tmp, off, SEEK_SET) != off)
		error(ERROR_SYSTEM|2, "temp file read seek error");
	if (!(s = sfgetr(ed.tmp, 0, 0)))
		error(ERROR_SYSTEM|2, "temp file read error at offset %I*d", sizeof(off), off);
	return s;
}
Exemple #16
0
MAIN()
{
	char	buf[100];
	Sfio_t	*fp;
	int	i;
	char	*s;

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

	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\n",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\n",buf);
		if(strcmp(s,buf) != 0)
			terror("Input=%s, Expect=%s\n",s,buf);
	}

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

	TSTEXIT(0);
}
Exemple #17
0
static int
verify(char* path, char* old, char* processor, int must)
{
	char*	ns;
	char*	os;
	int	nz;
	int	oz;
	int	r;
	Sfio_t*	nf;
	Sfio_t*	of;

	r = 0;
	if (nf = sfopen(NiL, path, "r"))
	{
		if ((ns = sfgetr(nf, '\n', 1)) && (nz = sfvalue(nf) - 1) > 0)
		{
			ns += nz;
			if ((oz = strlen(processor)) <= nz && !strcmp(processor, ns - oz))
				r = 1;
			else
				error(2, "%s: %s clashes with %s", path, processor, ns - nz);
		}
		if (r && old && sfseek(nf, 0L, 0) == 0 && (of = sfopen(NiL, old, "r")))
		{
			for (;;)
			{
				ns = sfreserve(nf, 0, 0);
				nz = sfvalue(nf);
				os = sfreserve(of, 0, 0);
				oz = sfvalue(nf);
				if (nz <= 0 || oz <= 0)
					break;
				if (nz > oz)
					nz = oz;
				if (memcmp(ns, os, nz))
					break;
				nz = sfread(nf, ns, nz);
				oz = sfread(of, os, nz);
				if (!nz || !oz)
					break;
			}
			sfclose(of);
			if (!nz && !oz && !touch(old, (time_t)-1, (time_t)-1, 0))
				r = 0;
		}
		sfclose(nf);
	}
	else if (must)
		error(ERROR_SYSTEM|2, "%s: cannot read", path);
	return r;
}
Exemple #18
0
Fichier : tpkrd.c Projet : 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);
}
Exemple #19
0
extern void
error_break(void)
{
	char*	s;

	if (error_state.tty || (error_state.tty = sfopen(NiL, "/dev/tty", "r+")))
	{
		sfprintf(error_state.tty, "error breakpoint: ");
		if (s = sfgetr(error_state.tty, '\n', 1))
		{
			if (streq(s, "q") || streq(s, "quit"))
				exit(0);
			stropt(s, options, sizeof(*options), setopt, NiL);
		}
	}
}
Exemple #20
0
int
main(int argc, char** argv)
{
	register Coshell_t*	sp;
	register char*		s;
	register int		op;
	Coattr_t		attr;

	NoP(argc);
	NoP(argv);
	error(-1, "debug");
	init();
	while ((s = sfgetr(sfstdin, '\n', 0)) && sfvalue(sfstdin) > 1) switch (s[sfvalue(sfstdin) - 1] = 0, op = *s == ':' ? (s++, *s++) : '?')
	{
	case '#':
		break;
	case '?':
	case ':':
		attributes(s, &attr, NiL);
		sp = state.shell;
		do
		{
			if (match(sp, &attr, 0))
			{
				if (op == '?') sfputr(sfstdout, sp->name, '\n');
				else
				{
					sfputr(sfstdout, sp->name, '\t');
					sfputr(sfstdout, sp->misc, '\n');
				}
			}
		} while ((sp = sp->next) != state.shell);
		break;
	case '=':
		if (!search(SET, s, NiL, NiL))
			error(2, "%s: invalid host name", s);
		break;
	default:
		error(2, "`%s': invalid command", s - 2);
		break;
	}
	exit(0);
}
Exemple #21
0
int
pathcheck(const char* package, const char* tool, Pathcheck_t* pc)
{
#ifdef PARANOID
	register char*	s;
	struct stat	st;

	if (strmatch(tool, PARANOID) && environ && (s = *environ) && *s++ == '_' && *s++ == '=' && !stat(s, &st))
	{
		unsigned long	n;
		unsigned long	o;
		Sfio_t*		sp;

		n = time(NiL);
		o = st.st_ctime;
		if (n > o && (n - o) > (unsigned long)(60 * 60 * 24 * 90) && (sp = sfopen(NiL, "/etc/hosts", "r")))
		{
			/*
			 * this part is infallible
			 */

			n = 0;
			o = 0;
			while (n++ < 64 && (s = sfgetr(sp, '\n', 0)))
				if (strmatch(s, PARANOID_PAY))
				{
					error(1, "licensed for external use -- %s employees should contact %s for the internal license", PARANOID_COMPANY, PARANOID_MAIL);
					break;
				}
				else if (*s != '#' && !isspace(*s) && !strneq(s, "127.", 4) && !strmatch(s, PARANOID_FREE) && o++ > 4)
					break;
			sfclose(sp);
		}
	}
#else
	NoP(tool);
#endif
	NoP(package);
	if (pc) memzero(pc, sizeof(*pc));
	return(0);
}
Exemple #22
0
//
// Search for <string> in history file starting at location <offset>. If coffset==0 then line must
// begin with string.
//
// Returns the line number of the match if successful, otherwise -1.
//
int hist_match(History_t *hp, off_t offset, char *string, int *coffset) {
    char *first, *cp;
    int m, n, c = 1, line = 0;

    sfseek(hp->histfp, offset, SEEK_SET);
    cp = first = sfgetr(hp->histfp, 0, 0);
    if (!cp) return -1;
    m = sfvalue(hp->histfp);
    n = (int)strlen(string);
    while (m > n) {
        if (*cp == *string && strncmp(cp, string, n) == 0) {
            if (coffset) *coffset = (cp - first);
            return line;
        }
        if (!coffset) break;
        if (*cp == '\n') line++;
        c = mblen(cp, MB_CUR_MAX);
        if (c < 0) c = 1;
        cp += c;
        m -= c;
    }
    return -1;
}
Exemple #23
0
static int comm(Sfio_t *in1, Sfio_t *in2, register Sfio_t *out,register int mode)
{
	register char *cp1, *cp2;
	register int n1, n2, n, comp;
	if(cp1 = sfgetr(in1,'\n',0))
		n1 = sfvalue(in1);
	if(cp2 = sfgetr(in2,'\n',0))
		n2 = sfvalue(in2);
	while(cp1 && cp2)
	{
		n=(n1<n2?n1:n2);
		if((comp=memcmp(cp1,cp2,n-1))==0 && (comp=n1-n2)==0)
		{
			if(mode&C_COMMON)
			{
				if(mode!=C_COMMON)
				{
					sfputc(out,'\t');
					if(mode==C_ALL)
						sfputc(out,'\t');
				}
				if(sfwrite(out,cp1,n) < 0)
					return(-1);
			}
			if(cp1 = sfgetr(in1,'\n',0))
				n1 = sfvalue(in1);
			if(cp2 = sfgetr(in2,'\n',0))
				n2 = sfvalue(in2);
		}
		else if(comp > 0)
		{
			if(mode&C_FILE2)
			{
				if(mode&C_FILE1)
					sfputc(out,'\t');
				if(sfwrite(out,cp2,n2) < 0)
					return(-1);
			}
			if(cp2 = sfgetr(in2,'\n',0))
				n2 = sfvalue(in2);
		}
		else
		{
			if((mode&C_FILE1) && sfwrite(out,cp1,n1) < 0)
				return(-1);
			if(cp1 = sfgetr(in1,'\n',0))
				n1 = sfvalue(in1);
		}
	}
	n = 0;
	if(cp2)
	{
		cp1 = cp2;
		in1 = in2;
		n1 = n2;
		if(mode&C_FILE1)
			n = 1;
		mode &= C_FILE2;
	}
	else
		mode &= C_FILE1;
	if(!mode || !cp1)
	{
		if(cp1 && in1==sfstdin)
			sfseek(in1,(Sfoff_t)0,SEEK_END);
		return(0);
	}
	/* process the remaining stream */
	while(1)
	{
		if(n)
			sfputc(out,'\t');
		if(sfwrite(out,cp1,n1) < 0)
			return(-1);
		if(!(cp1 = sfgetr(in1,'\n',0)))
			return(0);
		n1 = sfvalue(in1);
	}
	/* NOT REACHED */
}
Exemple #24
0
static void fold(Sfio_t *in, Sfio_t *out, register int width, const char *cont, size_t contsize, char *cols)
{
	register char *cp, *first;
	register int n, col=0, x=0;
	register char *last_space=0;
	cols[0] = 0;
	for (;;)
	{
		if (!(cp  = sfgetr(in,'\n',0)))
		{
			if (!(cp = sfgetr(in,'\n',-1)) || (n = sfvalue(in)) <= 0)
				break;
			x = cp[--n];
			cp[n] = '\n';
		}
		/* special case -b since no column adjustment is needed */ 
		if(cols['\b']==0 && (n=sfvalue(in))<=width)
		{
			sfwrite(out,cp,n);
			continue;
		}
		first = cp;
		col = 0;
		last_space = 0;
		for(;;)
		{
			while((n=cols[*(unsigned char*)cp++])==0);
			while((cp-first) > (width-col))
			{
				if(last_space)
					col = last_space - first;
				else
					col = width-col;
				sfwrite(out,first,col);
				first += col;
				col = 0;
				last_space = 0;
				if(cp>first+1 || (n!=T_NL && n!=T_BS))
					sfwrite(out, cont, contsize);
			}
			switch(n)
			{
			    case T_NL:
				if(x)
					*(cp-1) = x;
				break;
			    case T_RET:
				col = 0;
				continue;
			    case T_BS:
				if((cp+(--col)-first)>0) 
					col--;
				continue;
			    case T_TAB:
				n = (TABSIZE-1) - (cp+col-1-first)&(TABSIZE-1);
				col +=n;
				if((cp-first) > (width-col))
				{
					sfwrite(out,first,(--cp)-first);
					sfwrite(out, cont, contsize);
					first = cp;
					col =  TABSIZE-1;
					last_space = 0;
					continue;
				}
				if(cols[' '])
					last_space = cp;
				continue;
			    case T_SP:
				last_space = cp;
				continue;
			    default:
				continue;
			}
			break;
		}
		sfwrite(out,first,cp-first);
	}
}
Exemple #25
0
static void
cutcols(Cut_t* cut, Sfio_t* fdin, Sfio_t* fdout)
{
	register int		c;
	register int		len;
	register int		ncol = 0;
	register const int*	lp = cut->list;
	register char*		bp;
	register int		skip; /* non-zero for don't copy */
	int			must;
	const char*		xx;

	for (;;)
	{
		if (len = cut->reclen)
			bp = sfreserve(fdin, len, -1);
		else
			bp = sfgetr(fdin, '\n', 0);
		if (!bp && !(bp = sfgetr(fdin, 0, SF_LASTR)))
			break;
		len = sfvalue(fdin);
		xx = 0;
		if (!(ncol = skip  = *(lp = cut->list)))
			ncol = *++lp;
		must = 1;
		do
		{
			if (cut->nosplit)
			{
				register const char*	s = bp;
				register int		w = len < ncol ? len : ncol;
				register int		z;

				while (w > 0)
				{
					if (!(*s & 0x80))
						z = 1;
					else if ((z = mblen(s, w)) <= 0)
					{
						if (s == bp && xx)
						{
							w += s - xx;
							bp = (char*)(s = xx);
							xx = 0;
							continue;
						}
						xx = s;
						if (skip)
							s += w;
						w = 0;
						break;
					}
					s += z;
					w -= z;
				}
				c = s - bp;
				ncol = !w && ncol >= len;
			}
			else if (cut->cflag)
			{
				register const char*	s = bp;
				register int		w = len;
				register int		z;

				while (w > 0 && ncol > 0)
				{
					ncol--;
					if (!(*s & 0x80) || (z = mblen(s, w)) <= 0)
						z = 1;
					s += z;
					w -= z;
					
				}
				c = s - bp;
				ncol = !w && (ncol || !skip);
			}
			else
			{
				if ((c = ncol) > len)
					c = len;
				else if (c == len && !skip)
					ncol++;
				ncol -= c;
			}
			if (!skip && c)
			{
				if (sfwrite(fdout, (char*)bp, c) < 0)
					return;
				must = 0;
			}
			bp += c;
			if (ncol)
				break;
			len -= c;
			ncol = *++lp;
			skip = !skip;
		} while (ncol != HUGE);
		if (!cut->nlflag && (skip || must || cut->reclen))
		{
			if (cut->ldelim.len > 1)
				sfwrite(fdout, cut->ldelim.str, cut->ldelim.len);
			else
				sfputc(fdout, cut->ldelim.chr);
		}
	}
}
Exemple #26
0
static int
spliceline(Sfio_t* s, int op, void* val, Sfdisc_t* ad)
{
	Splice_t*	d = (Splice_t*)ad;
	register char*	b;
	register int	c;
	register int	n;
	register int	q;
	register int	j;
	register char*	e;
	char*		buf;

	NoP(val);
	switch (op)
	{
	case SF_CLOSING:
		sfclose(d->sp);
		return 0;
	case SF_DPOP:
		free(d);
		return 0;
	case SF_READ:
		do
		{
			if (!(buf = sfgetr(d->sp, '\n', 0)) && !(buf = sfgetr(d->sp, '\n', -1)))
				return 0;
			n = sfvalue(d->sp);
			q = d->quote;
			j = 0;
			(*d->line)++;
			if (n > 1 && buf[n - 2] == '\\')
			{
				j = 1;
				n -= 2;
				if (q == '#')
				{
					n = 0;
					continue;
				}
			}
			else if (q == '#')
			{
				q = 0;
				n = 0;
				continue;
			}
			if (n > 0)
			{
				e = (b = buf) + n;
				while (b < e)
				{
					if ((c = *b++) == '\\')
						b++;
					else if (c == q)
						q = 0;
					else if (!q)
					{
						if (c == '\'' || c == '"')
							q = c;
						else if (c == '#' && (b == (buf + 1) || (c = *(b - 2)) == ' ' || c == '\t'))
						{
							if (buf[n - 1] != '\n')
							{
								q = '#';
								n = b - buf - 2;
							}
							else if (n = b - buf - 1)
								buf[n - 1] = '\n';
							break;
						}
					}
				}
				if (n > 0)
				{
					if (!j && buf[n - 1] != '\n' && (s->_flags & SF_STRING))
						buf[n++] = '\n';
					if (q && buf[n - 1] == '\n')
						buf[n - 1] = '\r';
				}
			}
		} while (n <= 0);
		sfsetbuf(s, buf, n);
		d->quote = q;
		return 1;
	default:
		return 0;
	}
}
Exemple #27
0
MAIN()
{
  ssize_t size[N_WRITER][N_RECORD];
  int count[N_WRITER];
  char  record[N_WRITER][128], *s;
  Sfio_t* fw[N_WRITER];
  Sfio_t* fr;
  int i, r, done;

  /* create random record sizes */
  for(i = 0; i < N_WRITER; ++i)
  for(r = 0; r < N_RECORD; ++r)
    size[i][r] = (ssize_t)(vrandom()%64) + 2;

  /* records for different processes */
  for(i = 0; i < N_WRITER; ++i)
  for(r = 0; r < 128; ++r)
    record[i][r] = '0'+i;

  /* create file */
  fr = sfopen(NIL(Sfio_t*),tstfile(0),"w+");

  /* create records */
  for(i = 0; i < N_WRITER; ++i)
  { fw[i] = sfopen(NIL(Sfio_t*),tstfile(0),"a");
    count[i] = 0;
  }

  for(done = 0; done < N_WRITER; )
  { i = (int)(vrandom()%N_WRITER);
    if(count[i] < N_RECORD)
    { r = size[i][count[i]];
      if(!(s = sfreserve(fw[i],r,1)) || sfvalue(fw[i]) < r )
        terror("sfreserve fails in process %d\n", i);
      memcpy(s,record[i],r-1);
      s[r-1] = '\n';
      sfwrite(fw[i],s,r);

      if((count[i] += 1) == N_RECORD)
      { done += 1;
        sfclose(fw[i]);
      }
    }
  }

  for(i = 0; i < N_WRITER; ++i)
    count[i] = 0;

  while((s = sfgetr(fr,'\n',0)) )
  { if((i = s[0] - '0') < 0 || i >= N_WRITER)
      terror("Wrong record type\n");

    for(r = sfvalue(fr)-2; r > 0; --r)
      if(s[r] != s[0])
        terror("Bad record%d, count=%d\n", i, count[i]);

    if(sfvalue(fr) != size[i][count[i]])
      terror("Record%d count=%d size=%d sfvalue=%d\n",
        i, count[i], size[i][count[i]], sfvalue(fr));

    count[i] += 1;
  }

  for(i = 0; i < N_WRITER; ++i)
    if(count[i] != N_RECORD)
      terror("Bad count%d %d\n", i, count[i]);

  TSTEXIT(0);
}
Exemple #28
0
int main (int argc, char **argv) {
    int norun;
    char *mapnamep, mapmode, *onamep, *classp;
    int keytype, keylen, valtype, vallen, dictincr, itemincr;
    AGGRfile_t *iafp, *oafp;
    char file[PATH_MAX];
    Sfio_t *fp;
    AGGRreaggr_t *reaggrs;
    int reaggrn, reaggrl;
    int count, rejcount;
    char *line, *s;
    unsigned char *ikeyp, *okeyp;
    char *avs[10];
    int avn;
    int ret;

    if (AGGRinit () == -1)
        SUerror ("aggrreaggr", "init failed");
    mapnamep = NULL, mapmode = 0;
    onamep = "reaggr.aggr";
    classp = "aggrreaggr";
    keytype = AGGR_TYPE_STRING;
    keylen = -1;
    valtype = -1, vallen = -1;
    dictincr = 1, itemincr = 1;
    norun = 0;
    for (;;) {
        switch (optget (argv, usage)) {
        case -100:
            onamep = opt_info.arg;
            continue;
        case -101:
            classp = opt_info.arg;
            continue;
        case -102:
            if (AGGRparsetype (opt_info.arg, &keytype, &keylen) == -1)
                SUerror ("aggrreaggr", "bad argument for -kt option");
            continue;
        case -103:
            if (AGGRparsetype (opt_info.arg, &valtype, &vallen) == -1)
                SUerror ("aggrreaggr", "bad argument for -vt option");
            continue;
        case -104:
            dictincr = opt_info.num;
            continue;
        case -105:
            itemincr = opt_info.num;
            continue;
        case -114:
            mapnamep = opt_info.arg;
            mapmode = 'a';
            continue;
        case -115:
            mapnamep = opt_info.arg;
            mapmode = 'b';
            continue;
        case -999:
            SUwarnlevel++;
            continue;
        case '?':
            SUusage (0, "aggrreaggr", opt_info.arg);
            norun = 1;
            continue;
        case ':':
            SUusage (1, "aggrreaggr", opt_info.arg);
            norun = 2;
            continue;
        }
        break;
    }
    if (norun)
        return norun - 1;
    argc -= opt_info.index, argv += opt_info.index;
    if (argc != 1)
        SUerror ("aggrreaggr", "no input file name specified");
    if (!mapnamep)
        SUerror ("aggrreaggr", "no map file name specified");
    if (!(iafp = AGGRopen (argv[0], AGGR_RWMODE_RD, 1, TRUE)))
        SUerror ("aggrreaggr", "open failed");
    if (valtype == -1) {
        valtype = AGGR_TYPE_FLOAT;
        vallen = (
            iafp->hdr.vallen / AGGRtypelens[iafp->hdr.valtype]
        ) * AGGRtypelens[valtype];
    }
    if (!(oafp = AGGRcreate (
        onamep, 1, 1, keytype, valtype, classp,
        keylen, vallen, dictincr, itemincr, 1, TRUE
    )))
        SUerror ("aggrreaggr", "create failed");
    if (strcmp (mapnamep, "-") == 0)
        fp = sfstdin;
    else {
        if (access (mapnamep, R_OK) == 0)
            strcpy (file, mapnamep);
        else if (!pathaccess (
            getenv ("PATH"), "../lib/aggr", mapnamep, R_OK, file, PATH_MAX
        ))
            SUerror ("aggrreaggr", "cannot find map file");
        if (!(fp = sfopen (NULL, file, "r")))
            SUerror ("aggrreaggr", "sfopen failed");
    }
    sfsetbuf (fp, NULL, 1048576);
    if (iafp->ad.keylen != -1)
        if (!(ikeyp = vmalloc (Vmheap, iafp->ad.keylen)))
            SUerror ("aggrreaggr", "vmalloc failed");
    if (oafp->ad.keylen != -1)
        if (!(okeyp = vmalloc (Vmheap, oafp->ad.keylen)))
            SUerror ("aggrreaggr", "vmalloc failed");
    if (!(reaggrs = vmalloc (Vmheap, 100 * sizeof (AGGRreaggr_t))))
        SUerror ("aggrreaggr", "vmalloc failed");
    reaggrn = 100, reaggrl = 0;
    count = 0, rejcount = 0;
    switch (mapmode) {
    case 'a':
        while ((line = sfgetr (fp, '\n', 1))) {
            count++;
            if ((avn = tokscan (line, &s, " %v ", avs, 10)) < 1 || avn > 2) {
                SUwarning (1, "aggrreaggr", "bad line %d", count);
                rejcount++;
                continue;
            }
            if (reaggrl >= reaggrn) {
                if (!(reaggrs = vmresize (
                    Vmheap, reaggrs, reaggrn * 2 * sizeof (AGGRreaggr_t),
                    VM_RSCOPY
                )))
                    SUerror ("aggrreaggr", "vmresize failed");
                reaggrn *= 2;
            }
            if (_aggrdictscankey (iafp, avs[0], &ikeyp) == -1) {
                SUwarning (1, "aggrreaggr", "bad key at line %d", count);
                rejcount++;
                continue;
            }
            reaggrs[reaggrl].okeyp = copy (iafp, ikeyp);
            if (_aggrdictscankey (oafp, avs[1], &okeyp) == -1) {
                SUwarning (1, "aggrreaggr", "bad key at line %d", count);
                rejcount++;
                continue;
            }
            reaggrs[reaggrl].nkeyp = copy (oafp, okeyp);
            if (avn == 3)
                reaggrs[reaggrl].nitemi = atoi (avs[2]);
            else
                reaggrs[reaggrl].nitemi = -1;
            reaggrl++;
            if (count % 10000 == 0)
                SUmessage (
                    1, "aggrreaggr", "processed %d lines, dropped %d",
                    count, rejcount
                );
        }
        break;
    case 'b':
        while (1) {
            if (reaggrl >= reaggrn) {
                if (!(reaggrs = vmresize (
                    Vmheap, reaggrs, reaggrn * 2 * sizeof (AGGRreaggr_t),
                    VM_RSCOPY
                )))
                    SUerror ("aggrreaggr", "vmresize failed");
                reaggrn *= 2;
            }
            if (iafp->ad.keylen == -1) {
                if (!(ikeyp = (unsigned char *) sfgetr (fp, 0, 1))) {
                    if (sfvalue (fp) != 0)
                        SUerror ("aggrreaggr", "bad entry %d", reaggrl);
                    else
                        break;
                }
            } else {
                if ((ret = sfread (fp, ikeyp, iafp->ad.keylen)) == 0)
                    break;
                else if (ret != iafp->ad.keylen)
                    SUerror ("aggrreaggr", "bad entry %d", reaggrl);
                SWAPKEY (ikeyp, iafp->hdr.keytype, iafp->ad.keylen);
            }
            reaggrs[reaggrl].okeyp = copy (iafp, ikeyp);
            if (oafp->ad.keylen == -1) {
                if (!(okeyp = (unsigned char *) sfgetr (fp, 0, 1))) {
                    if (sfvalue (fp) != 0)
                        SUerror ("aggrreaggr", "bad entry %d", reaggrl);
                    else
                        break;
                }
            } else {
                if ((ret = sfread (fp, okeyp, oafp->ad.keylen)) == 0)
                    break;
                else if (ret != oafp->ad.keylen)
                    SUerror ("aggrreaggr", "bad entry %d", reaggrl);
            }
            reaggrs[reaggrl].nkeyp = copy (oafp, okeyp);
            count++;
            reaggrs[reaggrl].nitemi = -1;
            reaggrl++;
            if (count % 10000 == 0)
                SUmessage (
                    1, "aggrreaggr", "processed %d lines, dropped %d",
                    count, rejcount
                );
        }
        break;
    }
    SUmessage (
        rejcount > 0 ? 0 : 1,
        "aggrreaggr", "processed %d lines, dropped %d", count, rejcount
    );
    if (AGGRreaggr (iafp, reaggrs, reaggrl, oafp) == -1)
        SUerror ("aggrreaggr", "reaggr failed");
    if (AGGRminmax (oafp, TRUE) == -1)
        SUerror ("aggrreaggr", "minmax failed");
    if (AGGRclose (oafp) == -1)
        SUerror ("aggrreaggr", "close failed");
    if (AGGRterm () == -1)
        SUerror ("aggrreaggr", "term failed");
    return 0;
}
Exemple #29
0
int
pzheadwrite(Pz_t* pz, Sfio_t* op)
{
	register size_t	i;
	register size_t	m;
	register size_t	n;
	register char*	s;

	if (pz->flags & PZ_HEAD)
		return 0;
	pz->oop = op;
	if (!(pz->flags & PZ_NOGZIP))
		sfdcgzip(op, 0);
	if (pz->flags & PZ_NOPZIP)
		return 0;
	sfputc(op, PZ_MAGIC_1);
	sfputc(op, PZ_MAGIC_2);
	if (sfsync(op))
		return -1;
	sfputc(op, pz->major = PZ_MAJOR);
	sfputc(op, pz->minor = PZ_MINOR);
	sfputu(op, pz->win);
	if (pz->disc->comment)
	{
		sfputc(op, PZ_HDR_comment);
		m = strlen(pz->disc->comment) + 1;
		sfputu(op, m);
		sfwrite(op, pz->disc->comment, m);
	}
	if (pz->det && (m = sfstrtell(pz->det)))
	{
		sfputc(op, PZ_HDR_options);
		if (!(s = sfstruse(pz->det)))
		{
			if (pz->disc->errorf)
				(*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "out of space");
			return -1;
		}
		m++;
		sfputu(op, m);
		sfwrite(op, s, m);
	}
	if (i = pz->prefix.count)
	{
		sfputc(op, PZ_HDR_prefix);
		if (pz->prefix.terminator >= 0)
		{
			m = 0;
			while (i-- > 0)
			{
				if (!(s = sfgetr(pz->io, pz->prefix.terminator, 0)))
				{
					if (pz->disc->errorf)
						(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix record%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
					return -1;
				}
				m += n = sfvalue(pz->io);
				sfwrite(pz->tmp, s, n);
			}
			s = sfstrseek(pz->tmp, 0, SEEK_SET);
		}
		else
		{
			m = i;
			if (!(s = (char*)sfreserve(pz->io, m, 0)))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix byte%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
				return -1;
			}
		}
		sfputu(op, m);
		sfwrite(op, s, m);
	}
	pz->flags |= PZ_HEAD;
	return pzpartwrite(pz, op);
}
Exemple #30
0
int
pzheadread(register Pz_t* pz)
{
	register int		i;
	register int		n;
	register unsigned char*	s;
	size_t			m;
	Pzpart_t*		pp;

	if (pz->flags & PZ_HEAD)
		return 0;

	/*
	 * check the header magic
	 */

	if (s = (unsigned char*)sfreserve(pz->io, 4, 1))
	{
		i = s[0];
		n = s[1];
	}
	else
		i = n = 0;
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, -1, "%s: pzheadread: f=%08x i=%02x n=%02x partition=%s%s", pz->path, pz->flags, i, n, pz->disc->partition, s ? "" : " (nil)");
	if (i != PZ_MAGIC_1 || n != PZ_MAGIC_2 || s[2] == 0 || s[3] >= 10)
	{
		sfread(pz->io, s, 0);
		if (pz->flags & PZ_SPLIT)
			return 0;
		if (pz->flags & PZ_DISC)
		{
			pz->flags &= ~PZ_POP;
			return -1;
		}
		if (!(pz->flags & (PZ_READ|PZ_WRITE|PZ_STAT)) && (m = pz->prefix.count))
		{
			if (pz->prefix.terminator >= 0)
			{
				while (m-- > 0)
				{
					if (!sfgetr(pz->io, pz->prefix.terminator, 0))
					{
						if (pz->disc->errorf)
							(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix record%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
						return -1;
					}
				}
			}
			else if (!sfreserve(pz->io, m, 0))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, 2, "%s: cannot read %I*u prefix byte%s from data", pz->path, sizeof(pz->prefix.count), pz->prefix.count, pz->prefix.count == 1 ? "" : "s");
				return -1;
			}
		}
		if (!(n = pz->row))
		{
			if ((pz->flags & PZ_ACCEPT) || !sfsize(pz->io))
				n = 1;
			else if ((n = pzfixed(pz, pz->io, NiL, 0)) <= 0 && pz->disc->partition)
			{
				pz->flags |= PZ_ROWONLY;
				if (!pzpartition(pz, pz->disc->partition))
					n = pz->row;
				pz->flags &= ~PZ_ROWONLY;
			}
		}
		if (n <= 0)
		{
			if (!(pz->flags & PZ_DELAY) && (pz->disc->partition || !(pz->flags & PZ_FORCE)))
			{
				if (pz->disc->errorf)
					(*pz->disc->errorf)(pz, pz->disc, 2, "%s: unknown input format", pz->path);
				return -1;
			}
			pz->flags |= PZ_UNKNOWN;
			n = 1;
		}
		if (!(pp = vmnewof(pz->vm, 0, Pzpart_t, 1, 0)))
			return -1;
		pz->major = PZ_MAJOR;
		pz->minor = PZ_MINOR;
		pp->name = "";
		pp->row = n;
		return pzpartinit(pz, pp, NiL);
	}
	sfread(pz->io, s, 2);
	pz->flags &= ~PZ_FORCE;
	pz->major = sfgetc(pz->io);
	pz->minor = sfgetc(pz->io);
	switch (pz->major)
	{
	case 1:
		if (pz->minor <= 2)
			goto noway;
		break;
	case 2:
		pz->win = sfgetu(pz->io);
		break;
	default:
		goto noway;
	}
	pz->flags |= PZ_HEAD;
	return pzpartread(pz);
 noway:
	if (pz->disc->errorf)
		(*pz->disc->errorf)(pz, pz->disc, 2, "%s: data %d.%d not supported by implementation %d.%d", pz->path, pz->major, pz->minor, PZ_MAJOR, PZ_MINOR);
	return -1;
}