⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cachemgr.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* substitute '\t' */    buf_copy = x = xstrdup(buf);    if ((p = strchr(x, '\n')))	*p = '\0';    while (x && strlen(x)) {	int column_span = 1;	const char *cell = xstrtok(&x, '\t');	while (x && *x == '\t') {	    column_span++;	    x++;	}	l += snprintf(html + l, sizeof(html) - l, "<%s colspan=%d align=\"%s\">%s</%s>",	    ttag, column_span,	    is_header ? "center" : is_number(cell) ? "right" : "left",	    cell, ttag);    }    xfree(buf_copy);    /* record ends */    l += snprintf(html + l, sizeof(html) - l, "</tr>\n");    next_is_header = is_header && strstr(buf, "\t\t");    table_line_num++;    return html;}static intread_reply(int s, cachemgr_request * req){    char buf[4 * 1024];    FILE *fp = fdopen(s, "r");    /* interpretation states */    enum {	isStatusLine, isHeaders, isBodyStart, isBody, isForward, isEof, isForwardEof, isSuccess, isError    } istate = isStatusLine;    int parse_menu = 0;    const char *action = req->action;    const char *statusStr = NULL;    int status = -1;    if (0 == strlen(req->action))	parse_menu = 1;    else if (0 == strcasecmp(req->action, "menu"))	parse_menu = 1;    if (fp == NULL) {	perror("fdopen");	return 1;    }    if (parse_menu)	action = "menu";    /* read reply interpreting one line at a time depending on state */    while (istate < isEof) {	if (!fgets(buf, sizeof(buf), fp))	    istate = istate == isForward ? isForwardEof : isEof;	switch (istate) {	case isStatusLine:	    /* get HTTP status */	    /* uncomment the following if you want to debug headers */	    /* fputs("\r\n\r\n", stdout); */	    status = parse_status_line(buf, &statusStr);	    istate = status == 200 ? isHeaders : isForward;	    /* if cache asks for authentication, we have to reset our info */	    if (status == 401 || status == 407) {		reset_auth(req);		status = 403;	/* Forbiden, see comments in case isForward: */	    }	    /* this is a way to pass HTTP status to the Web server */	    if (statusStr)		printf("Status: %d %s", status, statusStr);	/* statusStr has '\n' */	    break;	case isHeaders:	    /* forward header field */	    if (!strcmp(buf, "\r\n")) {		/* end of headers */		fputs("Content-Type: text/html\r\n", stdout);	/* add our type */		istate = isBodyStart;	    }	    if (strncasecmp(buf, "Content-Type:", 13))	/* filter out their type */		fputs(buf, stdout);	    break;	case isBodyStart:	    printf("<HTML><HEAD><TITLE>CacheMgr@%s: %s</TITLE></HEAD><BODY>\n",		req->hostname, action);	    if (parse_menu) {		printf("<H2><a href=\"%s\">Cache Manager</a> menu for %s:</H2>",		    menu_url(req, "authenticate"), req->hostname);		printf("<UL>\n");	    } else {		printf("<P><A HREF=\"%s\">%s</A>\n<HR>\n",		    menu_url(req, "menu"), "Cache Manager menu");		printf("<PRE>\n");	    }	    istate = isBody;	    /* yes, fall through, we do not want to loose the first line */	case isBody:	    /* interpret [and reformat] cache response */	    if (parse_menu)		fputs(munge_menu_line(buf, req), stdout);	    else		fputs(munge_other_line(buf, req), stdout);	    break;	case isForward:	    /* forward: no modifications allowed */	    /*	     * Note: we currently do not know any way to get browser.reply to	     * 401 to .cgi because web server filters out all auth info. Thus we	     * disable authentication headers for now.	     */	    if (!strncasecmp(buf, "WWW-Authenticate:", 17) || !strncasecmp(buf, "Proxy-Authenticate:", 19));	/* skip */	    else		fputs(buf, stdout);	    break;	case isEof:	    /* print trailers */	    if (parse_menu)		printf("</UL>\n");	    else		printf("</table></PRE>\n");	    print_trailer();	    istate = isSuccess;	    break;	case isForwardEof:	    /* indicate that we finished processing an "error" sequence */	    istate = isError;	    break;	default:	    printf("%s: internal bug: invalid state reached: %d", script_name, istate);	    istate = isError;	}    }    close(s);    return 0;}static intprocess_request(cachemgr_request * req){    const struct hostent *hp;    static struct sockaddr_in S;    int s;    int l;    static char buf[2 * 1024];    if (req == NULL) {	auth_html(CACHEMGR_HOSTNAME, CACHE_HTTP_PORT, "");	return 1;    }    if (req->hostname == NULL) {	req->hostname = xstrdup(CACHEMGR_HOSTNAME);    }    if (req->port == 0) {	req->port = CACHE_HTTP_PORT;    }    if (req->action == NULL) {	req->action = xstrdup("");    }    if (!strcmp(req->action, "authenticate")) {	auth_html(req->hostname, req->port, req->user_name);	return 0;    }    if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {	snprintf(buf, 1024, "socket: %s\n", xstrerror());	error_html(buf);	return 1;    }    memset(&S, '\0', sizeof(struct sockaddr_in));    S.sin_family = AF_INET;    if ((hp = gethostbyname(req->hostname)) != NULL)	xmemcpy(&S.sin_addr.s_addr, hp->h_addr, hp->h_length);    else if (safe_inet_addr(req->hostname, &S.sin_addr))	(void) 0;    else {	snprintf(buf, 1024, "Unknown host: %s\n", req->hostname);	error_html(buf);	return 1;    }    S.sin_port = htons(req->port);    if (connect(s, (struct sockaddr *) &S, sizeof(struct sockaddr_in)) < 0) {	snprintf(buf, 1024, "connect: %s\n", xstrerror());	error_html(buf);	return 1;    }    l = snprintf(buf, sizeof(buf),	"GET cache_object://%s/%s HTTP/1.0\r\n"	"Accept: */*\r\n"	"%s"			/* Authentication info or nothing */	"\r\n",	req->hostname,	req->action,	make_auth_header(req));    write(s, buf, l);    debug(1) fprintf(stderr, "wrote request: '%s'\n", buf);    return read_reply(s, req);}intmain(int argc, char *argv[]){    char *s;    cachemgr_request *req;    safe_inet_addr("255.255.255.255", &no_addr);    now = time(NULL);    if ((s = strrchr(argv[0], '/')))	progname = xstrdup(s + 1);    else	progname = xstrdup(argv[0]);    if ((s = getenv("SCRIPT_NAME")) != NULL)	script_name = xstrdup(s);    req = read_request();    return process_request(req);}static char *read_post_request(void){    char *s;    char *buf;    int len;    if ((s = getenv("REQUEST_METHOD")) == NULL)	return NULL;    if (0 != strcasecmp(s, "POST"))	return NULL;    if ((s = getenv("CONTENT_LENGTH")) == NULL)	return NULL;    if ((len = atoi(s)) <= 0)	return NULL;    buf = xmalloc(len + 1);    fread(buf, len, 1, stdin);    buf[len] = '\0';    return buf;}static char *read_get_request(void){    char *s;    if ((s = getenv("QUERY_STRING")) == NULL)	return NULL;    return xstrdup(s);}static cachemgr_request *read_request(void){    char *buf;    cachemgr_request *req;    char *s;    char *t;    char *q;    if ((buf = read_post_request()) != NULL)	(void) 0;    else if ((buf = read_get_request()) != NULL)	(void) 0;    else	return NULL;    if (strlen(buf) == 0)	return NULL;    req = xcalloc(1, sizeof(cachemgr_request));    for (s = strtok(buf, "&"); s != NULL; s = strtok(NULL, "&")) {	t = xstrdup(s);	if ((q = strchr(t, '=')) == NULL)	    continue;	*q++ = '\0';	if (0 == strcasecmp(t, "host") && strlen(q))	    req->hostname = xstrdup(q);	else if (0 == strcasecmp(t, "port") && strlen(q))	    req->port = atoi(q);	else if (0 == strcasecmp(t, "user_name") && strlen(q))	    req->user_name = xstrdup(q);	else if (0 == strcasecmp(t, "passwd") && strlen(q))	    req->passwd = xstrdup(q);	else if (0 == strcasecmp(t, "auth") && strlen(q))	    req->pub_auth = xstrdup(q), decode_pub_auth(req);	else if (0 == strcasecmp(t, "operation"))	    req->action = xstrdup(q);    }    make_pub_auth(req);    debug(1) fprintf(stderr, "cmgr: got req: host: '%s' port: %d uname: '%s' passwd: '%s' auth: '%s' oper: '%s'\n",	safe_str(req->hostname), req->port, safe_str(req->user_name), safe_str(req->passwd), safe_str(req->pub_auth), safe_str(req->action));    return req;}/* Routines to support authentication *//* * Encodes auth info into a "public" form.  * Currently no powerful encryption is used. */static voidmake_pub_auth(cachemgr_request * req){    static char buf[1024];    safe_free(req->pub_auth);    debug(3) fprintf(stderr, "cmgr: encoding for pub...\n");    if (!req->passwd || !strlen(req->passwd))	return;    /* host | time | user | passwd */    snprintf(buf, sizeof(buf), "%s|%d|%s|%s",	req->hostname,	(int) now,	req->user_name ? req->user_name : "",	req->passwd);    debug(3) fprintf(stderr, "cmgr: pre-encoded for pub: %s\n", buf);    debug(3) fprintf(stderr, "cmgr: encoded: '%s'\n", base64_encode(buf));    req->pub_auth = xstrdup(base64_encode(buf));}static voiddecode_pub_auth(cachemgr_request * req){    char *buf;    const char *host_name;    const char *time_str;    const char *user_name;    const char *passwd;    debug(2) fprintf(stderr, "cmgr: decoding pub: '%s'\n", safe_str(req->pub_auth));    safe_free(req->passwd);    if (!req->pub_auth || strlen(req->pub_auth) < 4 + strlen(safe_str(req->hostname)))	return;    buf = xstrdup(base64_decode(req->pub_auth));    debug(3) fprintf(stderr, "cmgr: length ok\n");    /* parse ( a lot of memory leaks, but that is cachemgr style :) */    if ((host_name = strtok(buf, "|")) == NULL)	return;    debug(3) fprintf(stderr, "cmgr: decoded host: '%s'\n", host_name);    if ((time_str = strtok(NULL, "|")) == NULL)	return;    debug(3) fprintf(stderr, "cmgr: decoded time: '%s' (now: %d)\n", time_str, (int) now);    if ((user_name = strtok(NULL, "|")) == NULL)	return;    debug(3) fprintf(stderr, "cmgr: decoded uname: '%s'\n", user_name);    if ((passwd = strtok(NULL, "|")) == NULL)	return;    debug(2) fprintf(stderr, "cmgr: decoded passwd: '%s'\n", passwd);    /* verify freshness and validity */    if (atoi(time_str) + passwd_ttl < now)	return;    if (strcasecmp(host_name, req->hostname))	return;    debug(1) fprintf(stderr, "cmgr: verified auth. info.\n");    /* ok, accept */    xfree(req->user_name);    req->user_name = xstrdup(user_name);    req->passwd = xstrdup(passwd);    xfree(buf);}static voidreset_auth(cachemgr_request * req){    safe_free(req->passwd);    safe_free(req->pub_auth);}static const char *make_auth_header(const cachemgr_request * req){    static char buf[1024];    off_t l = 0;    const char *str64;    if (!req->passwd)	return "";    snprintf(buf, sizeof(buf), "%s:%s",	req->user_name ? req->user_name : "",	req->passwd);    str64 = base64_encode(buf);    l += snprintf(buf, sizeof(buf), "Authorization: Basic %s\r\n", str64);    l += snprintf(&buf[l], sizeof(buf) - l,	"Proxy-Authorization: Basic %s\r\n", str64);    return buf;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -