예제 #1
0
파일: req.c 프로젝트: dolda2000/ashd
char *unquoteurl(char *in)
{
    struct charbuf buf;
    char *p;
    int c;
    
    bufinit(buf);
    p = in;
    while(*p) {
	if(*p == '%') {
	    if(!p[1] || !p[2])
		goto fail;
	    c = 0;
	    if((p[1] >= '0') && (p[1] <= '9'))          c |= (p[1] - '0') << 4;
	    else if((p[1] >= 'a') && (p[1] <= 'f'))     c |= (p[1] - 'a' + 10) << 4;
	    else if((p[1] >= 'A') && (p[1] <= 'F'))     c |= (p[1] - 'A' + 10) << 4;
	    else                                        goto fail;
	    if((p[2] >= '0') && (p[2] <= '9'))          c |= (p[2] - '0');
	    else if((p[2] >= 'a') && (p[2] <= 'f'))     c |= (p[2] - 'a' + 10);
	    else if((p[2] >= 'A') && (p[2] <= 'F'))     c |= (p[2] - 'A' + 10);
	    else                                        goto fail;
	    bufadd(buf, c);
	    p += 3;
	} else {
	    bufadd(buf, *(p++));
	}
    }
    bufadd(buf, 0);
    return(buf.b);
fail:
    buffree(buf);
    return(NULL);
}
예제 #2
0
static void speed_process (float * * data, int * samples)
{
    double pitch = aud_get_double (CFGSECT, "pitch");
    double speed = aud_get_double (CFGSECT, "speed");

    /* Remove audio that has already been played from the output buffer. */
    bufcut (& out, written);

    /* Copy the passed audio to the input buffer, scaled to adjust pitch. */
    bufadd (& in, * data, * samples / curchans, 1.0 / pitch);

    /* If we are ending, add silence to the end of the input signal. */
    if (ending)
        bufgrow (& in, in.len + width / 2);

    /* Calculate the spacing interval for input. */
    int instep = round (outstep * speed / pitch);

    /* Run the speed change algorithm. */
    int src = 0;
    int dst = 0;

    while (src + MAX (width, instep) <= in.len)
    {
        bufgrow (& out, dst + width);
        out.len = dst + width;

        for (int i = 0; i < width; i ++)
        for (int c = 0; c < curchans; c ++)
            OFFSET (out.mem, dst + i)[c] += OFFSET (in.mem, src + i)[c] * cosine[i];

        src += instep;
        dst += outstep;
    }

    /* Remove processed audio from the input buffer. */
    bufcut (& in, src);

    /* Trim silence from the beginning of the output buffer. */
    if (trim > 0)
    {
        int cut = MIN (trim, dst);
        bufcut (& out, cut);
        dst -= cut;
        trim -= cut;
    }

    /* If we are ending, return all of the output buffer except the silence that
     * we trim from the end of it. */
    if (ending)
        dst = out.len - width / 2;

    /* Return processed audio in the output buffer and mark it to be removed on
     * the next call. */
    * data = out.mem;
    * samples = dst * curchans;
    written = dst;
}
예제 #3
0
파일: callfcgi.c 프로젝트: dolda2000/ashd
static void outplex(struct muth *muth, va_list args)
{
    vavar(FILE *, sk);
    struct {
	struct ch {
	    FILE *s;
	    int id;
	} *b;
	size_t s, d;
    } outs;
    int i;
    struct ch ch;
    int type, rid;
    char *data;
    size_t dlen;
    
    bufinit(outs);
    while((ch.s = va_arg(args, FILE *)) != NULL) {
	ch.id = va_arg(args, int);
	bufadd(outs, ch);
    }
    data = NULL;
    while(1) {
	if(recvrec(sk, &type, &rid, &data, &dlen))
	    goto out;
	if(rid != 1)
	    goto out;
	for(i = 0; i < outs.d; i++) {
	    if(outs.b[i].id == type) {
		if(outs.b[i].s != NULL) {
		    if(dlen == 0) {
			fclose(outs.b[i].s);
			outs.b[i].s = NULL;
		    } else {
			if(fwrite(data, 1, dlen, outs.b[i].s) != dlen)
			    goto out;
		    }
		}
		break;
	    }
	}
	free(data);
	data = NULL;
    }

out:
    if(data != NULL)
	free(data);
    for(i = 0; i < outs.d; i++) {
	if(outs.b[i].s != NULL)
	    fclose(outs.b[i].s);
    }
    buffree(outs);
    fclose(sk);
}
예제 #4
0
파일: callfcgi.c 프로젝트: dolda2000/ashd
static void bufcatkv(struct charbuf *dst, char *key, char *val)
{
    size_t kl, vl;
    
    if((kl = strlen(key)) < 128) {
	bufadd(*dst, kl);
    } else {
	bufadd(*dst, ((kl & 0x7f000000) >> 24) | 0x80);
	bufadd(*dst, (kl & 0x00ff0000) >> 16);
	bufadd(*dst, (kl & 0x0000ff00) >> 8);
	bufadd(*dst, kl & 0x000000ff);
    }
    if((vl = strlen(val)) < 128) {
	bufadd(*dst, vl);
    } else {
	bufadd(*dst, ((vl & 0x7f000000) >> 24) | 0x80);
	bufadd(*dst, (vl & 0x00ff0000) >> 16);
	bufadd(*dst, (vl & 0x0000ff00) >> 8);
	bufadd(*dst, vl & 0x000000ff);
    }
    bufcat(*dst, key, kl);
    bufcat(*dst, val, vl);
}
예제 #5
0
파일: htparser.c 프로젝트: dolda2000/ashd
static char *connid(void)
{
    static struct charbuf cur;
    int i;
    char *ret;
    
    for(i = 0; i < cur.d; i++) {
	if((++cur.b[i]) > 'Z')
	    cur.b[i] = 'A';
	else
	    goto done;
    }
    bufadd(cur, 'A');
done:
    ret = memcpy(smalloc(cur.d + 1), cur.b, cur.d);
    ret[cur.d] = 0;
    return(ret);
}
예제 #6
0
파일: htparser.c 프로젝트: dolda2000/ashd
static struct hthead *parsereq(struct bufio *in)
{
    struct hthead *req;
    struct charbuf method, url, ver;
    int c;
    
    req = NULL;
    bufinit(method);
    bufinit(url);
    bufinit(ver);
    while(1) {
	c = biogetc(in);
	if(c == ' ') {
	    break;
	} else if((c == EOF) || (c < 32) || (c >= 128)) {
	    goto fail;
	} else {
	    bufadd(method, c);
	    if(method.d >= 128)
		goto fail;
	}
    }
    while(1) {
	c = biogetc(in);
	if(c == ' ') {
	    break;
	} else if((c == EOF) || (c < 32)) {
	    goto fail;
	} else {
	    bufadd(url, c);
	    if(url.d >= 65536)
		goto fail;
	}
    }
    while(1) {
	c = biogetc(in);
	if(c == 10) {
	    break;
	} else if(c == 13) {
	} else if((c == EOF) || (c < 32) || (c >= 128)) {
	    goto fail;
	} else {
	    bufadd(ver, c);
	    if(ver.d >= 128)
		goto fail;
	}
    }
    bufadd(method, 0);
    bufadd(url, 0);
    bufadd(ver, 0);
    req = mkreq(method.b, url.b, ver.b);
    if(parseheadersb(req, in))
	goto fail;
    trimx(req);
    goto out;
    
fail:
    if(req != NULL) {
	freehthead(req);
	req = NULL;
    }
out:
    buffree(method);
    buffree(url);
    buffree(ver);
    return(req);
}
예제 #7
0
파일: callcgi.c 프로젝트: dolda2000/ashd
int main(int argc, char **argv, char **envp)
{
    int c;
    char *file, *sp;
    struct charvbuf prog;
    int inpath, addfile, cd;
    int infd, outfd;
    FILE *in, *out;
    char **headers;
    pid_t child;
    int estat;
    
    environ = envp;
    signal(SIGPIPE, SIG_IGN);
    
    bufinit(prog);
    inpath = 0;
    addfile = 1;
    cd = 0;
    while((c = getopt(argc, argv, "cp:P:")) >= 0) {
	switch(c) {
	case 'c':
	    cd = 1;
	    break;
	case 'p':
	    bufadd(prog, optarg);
	    inpath = 1;
	    break;
	case 'P':
	    prog.d = 0;
	    bufadd(prog, optarg);
	    while(1) {
		if(optind >= argc) {
		    flog(LOG_ERR, "callcgi: unterminated argument list for -P");
		    exit(1);
		}
		if(!strcmp(argv[optind], ";")) {
		    optind++;
		    break;
		}
		bufadd(prog, argv[optind++]);
	    }
	    if(prog.d == 0) {
		flog(LOG_ERR, "callcgi: -P option needs at least a program name");
		exit(1);
	    }
	    inpath = 1;
	    addfile = 0;
	    break;
	default:
	    usage();
	    exit(1);
	}
    }
    
    if(argc - optind < 3) {
	usage();
	exit(1);
    }
    if(((file = getenv("REQ_X_ASH_FILE")) == NULL) && (prog.d == 0)) {
	flog(LOG_ERR, "callcgi: needs to be called with the X-Ash-File header");
	exit(1);
    }
    
    if(cd) {
	/* This behavior is encouraged by the CGI specification (RFC 3875, 7.2),
	 * but not strictly required, and I get the feeling it might break some
	 * relative paths here or there, so it's not the default for now. */
	if((sp = strrchr(file, '/')) != NULL) {
	    *sp = 0;
	    if(chdir(file)) {
		*sp = '/';
	    } else {
		file = sp + 1;
	    }
	}
    }
    
    if(prog.d == 0)
	bufadd(prog, file);
    if(addfile && (file != NULL))
	bufadd(prog, file);
    bufadd(prog, NULL);
    child = forkchild(inpath, prog.b, file, argv[optind], argv[optind + 1], argv[optind + 2], &infd, &outfd);
    in = fdopen(infd, "w");
    passdata(stdin, in);	/* Ignore errors, perhaps? */
    fclose(in);
    out = fdopen(outfd, "r");
    if((headers = parsecgiheaders(out)) == NULL) {
	flog(LOG_WARNING, "CGI handler returned invalid headers");
	exit(1);
    }
    sendstatus(headers, stdout);
    sendheaders(headers, stdout);
    printf("\n");
    if(passdata(out, stdout))
	kill(child, SIGINT);
    fclose(out);
    if(waitpid(child, &estat, 0) == child) {
	if(WCOREDUMP(estat))
	    flog(LOG_WARNING, "CGI handler `%s' dumped core", prog.b[0]);
	if(WIFEXITED(estat) && !WEXITSTATUS(estat))
	    return(0);
	else
	    return(1);
    }
    flog(LOG_WARNING, "could not wait for CGI handler: %s", strerror(errno));
    return(1);
}
예제 #8
0
파일: req.c 프로젝트: dolda2000/ashd
struct hthead *parseresponseb(struct bufio *in)
{
    struct hthead *req;
    int code;
    struct charbuf ver, msg;
    int c;
    
    req = NULL;
    bufinit(ver);
    bufinit(msg);
    code = 0;
    while(1) {
	c = biogetc(in);
	if(c == ' ') {
	    break;
	} else if((c == EOF) || (c < 32) || (c >= 128)) {
	    goto fail;
	} else {
	    bufadd(ver, c);
	    if(ver.d >= 128)
		goto fail;
	}
    }
    while(1) {
	c = biogetc(in);
	if(c == ' ') {
	    break;
	} else if((c == EOF) || (c < '0') || (c > '9')) {
	    goto fail;
	} else {
	    code = (code * 10) + (c - '0');
	    if(code >= 10000)
		goto fail;
	}
    }
    while(1) {
	c = biogetc(in);
	if(c == 10) {
	    break;
	} else if(c == 13) {
	} else if((c == EOF) || (c < 32)) {
	    goto fail;
	} else {
	    bufadd(msg, c);
	    if(msg.d >= 512)
		goto fail;
	}
    }
    bufadd(msg, 0);
    bufadd(ver, 0);
    req = mkresp(code, msg.b, ver.b);
    if(parseheadersb(req, in))
	goto fail;
    goto out;
    
fail:
    if(req != NULL) {
	freehthead(req);
	req = NULL;
    }
out:
    buffree(msg);
    buffree(ver);
    return(req);
}
예제 #9
0
파일: req.c 프로젝트: dolda2000/ashd
int parseheadersb(struct hthead *head, struct bufio *in)
{
    int c, state;
    struct charbuf name, val;
    size_t tsz;
    
    bufinit(name);
    bufinit(val);
    state = 0;
    tsz = 0;
    while(1) {
	c = biogetc(in);
	if(++tsz >= 65536)
	    goto fail;
    again:
	if(state == 0) {
	    if(c == '\r') {
	    } else if(c == '\n') {
		break;
	    } else if(c == EOF) {
		goto fail;
	    } else {
		state = 1;
		goto again;
	    }
	} else if(state == 1) {
	    if(c == ':') {
		trim(&name);
		bufadd(name, 0);
		state = 2;
	    } else if(c == '\r') {
	    } else if(c == '\n') {
		goto fail;
	    } else if(c == EOF) {
		goto fail;
	    } else {
		bufadd(name, c);
	    }
	} else if(state == 2) {
	    if(c == '\r') {
	    } else if(c == '\n') {
		trim(&val);
		bufadd(val, 0);
		headappheader(head, name.b, val.b);
		buffree(name);
		buffree(val);
		state = 0;
	    } else if(c == EOF) {
		goto fail;
	    } else {
		bufadd(val, c);
	    }
	}
    }
    return(0);
    
fail:
    buffree(name);
    buffree(val);
    return(-1);
}