X-Git-Url: http://git.rohieb.name/openwrt.git/blobdiff_plain/e417063c23716f0dd35f98f1990bb8dad7b963f4..8c59fddb365bcd9a8ab6ce8ecc0c27b8026c0fd4:/package/uhttpd/src/uhttpd-utils.c diff --git a/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c index 60badf26d..3821eb54c 100644 --- a/package/uhttpd/src/uhttpd-utils.c +++ b/package/uhttpd/src/uhttpd-utils.c @@ -59,6 +59,21 @@ int sa_port(void *sa) return ntohs(((struct sockaddr_in6 *)sa)->sin6_port); } +int sa_rfc1918(void *sa) +{ + struct sockaddr_in *v4 = (struct sockaddr_in *)sa; + unsigned long a = htonl(v4->sin_addr.s_addr); + + if( v4->sin_family == AF_INET ) + { + return ((a >= 0x0A000000) && (a <= 0x0AFFFFFF)) || + ((a >= 0xAC100000) && (a <= 0xAC1FFFFF)) || + ((a >= 0xC0A80000) && (a <= 0xC0A8FFFF)); + } + + return 0; +} + /* Simple strstr() like function that takes len arguments for both haystack and needle. */ char *strfind(char *haystack, int hslen, const char *needle, int ndlen) { @@ -97,6 +112,7 @@ int select_intr(int n, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) /* unblock SIGCHLD */ sigemptyset(&ssn); sigaddset(&ssn, SIGCHLD); + sigaddset(&ssn, SIGPIPE); sigprocmask(SIG_UNBLOCK, &ssn, &sso); rv = select(n, r, w, e, t); @@ -178,8 +194,6 @@ int uh_tcp_recv(struct client *cl, char *buf, int len) return sz; } -#define ensure(x) \ - do { if( x < 0 ) return -1; } while(0) int uh_http_sendhf(struct client *cl, int code, const char *summary, const char *fmt, ...) { @@ -196,14 +210,14 @@ int uh_http_sendhf(struct client *cl, int code, const char *summary, const char code, summary ); - ensure(uh_tcp_send(cl, buffer, len)); + ensure_ret(uh_tcp_send(cl, buffer, len)); va_start(ap, fmt); len = vsnprintf(buffer, sizeof(buffer), fmt, ap); va_end(ap); - ensure(uh_http_sendc(cl, buffer, len)); - ensure(uh_http_sendc(cl, NULL, 0)); + ensure_ret(uh_http_sendc(cl, buffer, len)); + ensure_ret(uh_http_sendc(cl, NULL, 0)); return 0; } @@ -220,13 +234,13 @@ int uh_http_sendc(struct client *cl, const char *data, int len) if( len > 0 ) { clen = snprintf(chunk, sizeof(chunk), "%X\r\n", len); - ensure(uh_tcp_send(cl, chunk, clen)); - ensure(uh_tcp_send(cl, data, len)); - ensure(uh_tcp_send(cl, "\r\n", 2)); + ensure_ret(uh_tcp_send(cl, chunk, clen)); + ensure_ret(uh_tcp_send(cl, data, len)); + ensure_ret(uh_tcp_send(cl, "\r\n", 2)); } else { - ensure(uh_tcp_send(cl, "0\r\n\r\n", 5)); + ensure_ret(uh_tcp_send(cl, "0\r\n\r\n", 5)); } return 0; @@ -244,9 +258,9 @@ int uh_http_sendf( va_end(ap); if( (req != NULL) && (req->version > 1.0) ) - ensure(uh_http_sendc(cl, buffer, len)); + ensure_ret(uh_http_sendc(cl, buffer, len)); else if( len > 0 ) - ensure(uh_tcp_send(cl, buffer, len)); + ensure_ret(uh_tcp_send(cl, buffer, len)); return 0; } @@ -258,9 +272,9 @@ int uh_http_send( len = strlen(buf); if( (req != NULL) && (req->version > 1.0) ) - ensure(uh_http_sendc(cl, buf, len)); + ensure_ret(uh_http_sendc(cl, buf, len)); else if( len > 0 ) - ensure(uh_tcp_send(cl, buf, len)); + ensure_ret(uh_tcp_send(cl, buf, len)); return 0; } @@ -590,8 +604,7 @@ struct path_info * uh_path_lookup(struct client *cl, const char *url) } -static char uh_realms[UH_LIMIT_AUTHREALMS * sizeof(struct auth_realm)] = { 0 }; -static int uh_realm_count = 0; +static struct auth_realm *uh_realms = NULL; struct auth_realm * uh_auth_add(char *path, char *user, char *pass) { @@ -599,11 +612,8 @@ struct auth_realm * uh_auth_add(char *path, char *user, char *pass) struct passwd *pwd; struct spwd *spwd; - if( uh_realm_count < UH_LIMIT_AUTHREALMS ) + if((new = (struct auth_realm *)malloc(sizeof(struct auth_realm))) != NULL) { - new = (struct auth_realm *) - &uh_realms[uh_realm_count * sizeof(struct auth_realm)]; - memset(new, 0, sizeof(struct auth_realm)); memcpy(new->path, path, @@ -628,7 +638,7 @@ struct auth_realm * uh_auth_add(char *path, char *user, char *pass) ) { memcpy(new->pass, pwd->pw_passwd, min(strlen(pwd->pw_passwd), sizeof(new->pass) - 1)); - } + } } /* ordinary pwd */ @@ -640,9 +650,13 @@ struct auth_realm * uh_auth_add(char *path, char *user, char *pass) if( new->pass[0] ) { - uh_realm_count++; + new->next = uh_realms; + uh_realms = new; + return new; } + + free(new); } return NULL; @@ -662,11 +676,8 @@ int uh_auth_check( protected = 0; /* check whether at least one realm covers the requested url */ - for( i = 0; i < uh_realm_count; i++ ) + for( realm = uh_realms; realm; realm = realm->next ) { - realm = (struct auth_realm *) - &uh_realms[i * sizeof(struct auth_realm)]; - rlen = strlen(realm->path); if( (plen >= rlen) && !strncasecmp(pi->name, realm->path, rlen) ) @@ -706,11 +717,8 @@ int uh_auth_check( if( user && pass ) { /* find matching realm */ - for( i = 0, realm = NULL; i < uh_realm_count; i++ ) + for( realm = uh_realms; realm; realm = realm->next ) { - realm = (struct auth_realm *) - &uh_realms[i * sizeof(struct auth_realm)]; - rlen = strlen(realm->path); if( (plen >= rlen) && @@ -720,8 +728,6 @@ int uh_auth_check( req->realm = realm; break; } - - realm = NULL; } /* found a realm matching the username */ @@ -754,22 +760,17 @@ int uh_auth_check( } -static char uh_listeners[UH_LIMIT_LISTENERS * sizeof(struct listener)] = { 0 }; -static char uh_clients[UH_LIMIT_CLIENTS * sizeof(struct client)] = { 0 }; - -static int uh_listener_count = 0; -static int uh_client_count = 0; - +static struct listener *uh_listeners = NULL; +static struct client *uh_clients = NULL; struct listener * uh_listener_add(int sock, struct config *conf) { struct listener *new = NULL; socklen_t sl; - if( uh_listener_count < UH_LIMIT_LISTENERS ) + if( (new = (struct listener *)malloc(sizeof(struct listener))) != NULL ) { - new = (struct listener *) - &uh_listeners[uh_listener_count * sizeof(struct listener)]; + memset(new, 0, sizeof(struct listener)); new->socket = sock; new->conf = conf; @@ -779,24 +780,22 @@ struct listener * uh_listener_add(int sock, struct config *conf) memset(&(new->addr), 0, sl); getsockname(sock, (struct sockaddr *) &(new->addr), &sl); - uh_listener_count++; + new->next = uh_listeners; + uh_listeners = new; + + return new; } - return new; + return NULL; } struct listener * uh_listener_lookup(int sock) { struct listener *cur = NULL; - int i; - - for( i = 0; i < uh_listener_count; i++ ) - { - cur = (struct listener *) &uh_listeners[i * sizeof(struct listener)]; + for( cur = uh_listeners; cur; cur = cur->next ) if( cur->socket == sock ) return cur; - } return NULL; } @@ -807,10 +806,9 @@ struct client * uh_client_add(int sock, struct listener *serv) struct client *new = NULL; socklen_t sl; - if( uh_client_count < UH_LIMIT_CLIENTS ) + if( (new = (struct client *)malloc(sizeof(struct client))) != NULL ) { - new = (struct client *) - &uh_clients[uh_client_count * sizeof(struct client)]; + memset(new, 0, sizeof(struct client)); new->socket = sock; new->server = serv; @@ -825,7 +823,8 @@ struct client * uh_client_add(int sock, struct listener *serv) memset(&(new->servaddr), 0, sl); getsockname(sock, (struct sockaddr *) &(new->servaddr), &sl); - uh_client_count++; + new->next = uh_clients; + uh_clients = new; } return new; @@ -834,30 +833,72 @@ struct client * uh_client_add(int sock, struct listener *serv) struct client * uh_client_lookup(int sock) { struct client *cur = NULL; - int i; - - for( i = 0; i < uh_client_count; i++ ) - { - cur = (struct client *) &uh_clients[i * sizeof(struct client)]; + for( cur = uh_clients; cur; cur = cur->next ) if( cur->socket == sock ) return cur; - } return NULL; } void uh_client_remove(int sock) { - struct client *del = uh_client_lookup(sock); + struct client *cur = NULL; + struct client *prv = NULL; - if( del ) + for( cur = uh_clients; cur; prv = cur, cur = cur->next ) { - memmove(del, del + 1, - sizeof(uh_clients) - (int)((char *)del - uh_clients) - sizeof(struct client)); + if( cur->socket == sock ) + { + if( prv ) + prv->next = cur->next; + else + uh_clients = cur->next; - uh_client_count--; + free(cur); + break; + } } } +#ifdef HAVE_CGI +static struct interpreter *uh_interpreters = NULL; + +struct interpreter * uh_interpreter_add(const char *extn, const char *path) +{ + struct interpreter *new = NULL; + + if( (new = (struct interpreter *) + malloc(sizeof(struct interpreter))) != NULL ) + { + memset(new, 0, sizeof(struct interpreter)); + + memcpy(new->extn, extn, min(strlen(extn), sizeof(new->extn)-1)); + memcpy(new->path, path, min(strlen(path), sizeof(new->path)-1)); + + new->next = uh_interpreters; + uh_interpreters = new; + + return new; + } + + return NULL; +} + +struct interpreter * uh_interpreter_lookup(const char *path) +{ + struct interpreter *cur = NULL; + const char *e; + + for( cur = uh_interpreters; cur; cur = cur->next ) + { + e = &path[max(strlen(path) - strlen(cur->extn), 0)]; + + if( !strcmp(e, cur->extn) ) + return cur; + } + + return NULL; +} +#endif