formatted source code

This commit is contained in:
Felix Wallin 2010-08-16 17:20:12 +08:00 committed by FacialTurd
parent c86c224265
commit 6bd48d059f
6 changed files with 9311 additions and 7659 deletions

6
font.h Executable file → Normal file

File diff suppressed because one or more lines are too long

418
http.c Executable file → Normal file
View File

@ -72,7 +72,8 @@ static struct sockaddr_in http_proxy;
static char *mystrdup(char *s) static char *mystrdup(char *s)
{ {
char *x; char *x;
if(s) { if(s)
{
x = malloc(strlen(s)+1); x = malloc(strlen(s)+1);
strcpy(x, s); strcpy(x, s);
return x; return x;
@ -95,7 +96,8 @@ static int splituri(char *uri, char **host, char **path)
y = mystrdup("/"); y = mystrdup("/");
strncpy(x, p, q-p); strncpy(x, p, q-p);
x[q-p] = 0; x[q-p] = 0;
if(q==p || x[q-p-1]==':') { if(q==p || x[q-p-1]==':')
{
free(x); free(x);
free(y); free(y);
return 1; return 1;
@ -128,7 +130,8 @@ static char *getport(char *host)
static int resolve(char *dns, char *srv, struct sockaddr_in *addr) static int resolve(char *dns, char *srv, struct sockaddr_in *addr)
{ {
struct addrinfo hnt, *res = 0; struct addrinfo hnt, *res = 0;
if(http_use_proxy) { if(http_use_proxy)
{
memcpy(addr, &http_proxy, sizeof(struct sockaddr_in)); memcpy(addr, &http_proxy, sizeof(struct sockaddr_in));
return 0; return 0;
} }
@ -137,8 +140,10 @@ static int resolve(char *dns, char *srv, struct sockaddr_in *addr)
hnt.ai_socktype = SOCK_STREAM; hnt.ai_socktype = SOCK_STREAM;
if(getaddrinfo(dns, srv, &hnt, &res)) if(getaddrinfo(dns, srv, &hnt, &res))
return 1; return 1;
if(res) { if(res)
if(res->ai_family != AF_INET) { {
if(res->ai_family != AF_INET)
{
freeaddrinfo(res); freeaddrinfo(res);
return 1; return 1;
} }
@ -160,7 +165,8 @@ void http_init(char *proxy)
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
http_up = 1; http_up = 1;
#endif #endif
if(proxy) { if(proxy)
{
host = getserv(proxy); host = getserv(proxy);
port = getport(proxy); port = getport(proxy);
if(resolve(host, port, &http_proxy)) if(resolve(host, port, &http_proxy))
@ -189,7 +195,8 @@ void http_done(void)
#define HTS_XMIT 4 #define HTS_XMIT 4
#define HTS_RECV 5 #define HTS_RECV 5
#define HTS_DONE 6 #define HTS_DONE 6
struct http_ctx { struct http_ctx
{
int state; int state;
time_t last; time_t last;
int keep; int keep;
@ -213,53 +220,62 @@ struct http_ctx {
void *http_async_req_start(void *ctx, char *uri, char *data, int dlen, int keep) void *http_async_req_start(void *ctx, char *uri, char *data, int dlen, int keep)
{ {
struct http_ctx *cx = ctx; struct http_ctx *cx = ctx;
if(!ctx) { if(!ctx)
{
ctx = calloc(1, sizeof(struct http_ctx)); ctx = calloc(1, sizeof(struct http_ctx));
cx = ctx; cx = ctx;
cx->fd = PERROR; cx->fd = PERROR;
} }
if(!cx->hbuf) { if(!cx->hbuf)
{
cx->hbuf = malloc(256); cx->hbuf = malloc(256);
cx->hlen = 256; cx->hlen = 256;
} }
if(!http_up) { if(!http_up)
{
cx->ret = 604; cx->ret = 604;
cx->state = HTS_DONE; cx->state = HTS_DONE;
return ctx; return ctx;
} }
if(cx->state!=HTS_STRT && cx->state!=HTS_IDLE) { if(cx->state!=HTS_STRT && cx->state!=HTS_IDLE)
{
fprintf(stderr, "HTTP: unclean request restart state.\n"); fprintf(stderr, "HTTP: unclean request restart state.\n");
exit(1); exit(1);
} }
cx->keep = keep; cx->keep = keep;
cx->ret = 600; cx->ret = 600;
if(splituri(uri, &cx->host, &cx->path)) { if(splituri(uri, &cx->host, &cx->path))
{
cx->ret = 601; cx->ret = 601;
cx->state = HTS_DONE; cx->state = HTS_DONE;
return ctx; return ctx;
} }
if(http_use_proxy) { if(http_use_proxy)
{
free(cx->path); free(cx->path);
cx->path = mystrdup(uri); cx->path = mystrdup(uri);
} }
if(cx->fdhost && strcmp(cx->host, cx->fdhost)) { if(cx->fdhost && strcmp(cx->host, cx->fdhost))
{
free(cx->fdhost); free(cx->fdhost);
cx->fdhost = NULL; cx->fdhost = NULL;
PCLOSE(cx->fd); PCLOSE(cx->fd);
cx->fd = PERROR; cx->fd = PERROR;
cx->state = HTS_STRT; cx->state = HTS_STRT;
} }
if(data) { if(data)
{
if(!dlen) if(!dlen)
dlen = strlen(data); dlen = strlen(data);
cx->txd = malloc(dlen); cx->txd = malloc(dlen);
memcpy(cx->txd, data, dlen); memcpy(cx->txd, data, dlen);
cx->txdl = dlen; cx->txdl = dlen;
} else }
else
cx->txdl = 0; cx->txdl = 0;
cx->contlen = 0; cx->contlen = 0;
@ -286,7 +302,8 @@ void http_async_add_header(void *ctx, char *name, char *data)
static void process_header(struct http_ctx *cx, char *str) static void process_header(struct http_ctx *cx, char *str)
{ {
char *p; char *p;
if(cx->chunkhdr) { if(cx->chunkhdr)
{
p = strchr(str, ';'); p = strchr(str, ';');
if(p) if(p)
*p = 0; *p = 0;
@ -295,16 +312,19 @@ static void process_header(struct http_ctx *cx, char *str)
if(!cx->rxtogo) if(!cx->rxtogo)
cx->chunked = 0; cx->chunked = 0;
} }
if(!str[0]) { if(!str[0])
{
cx->rxtogo = cx->contlen; cx->rxtogo = cx->contlen;
cx->chunkhdr = cx->chunked; cx->chunkhdr = cx->chunked;
if(!cx->contlen && !cx->chunked && cx->ret!=100) if(!cx->contlen && !cx->chunked && cx->ret!=100)
cx->state = HTS_DONE; cx->state = HTS_DONE;
return; return;
} }
if(!strncmp(str, "HTTP/", 5)) { if(!strncmp(str, "HTTP/", 5))
{
p = strchr(str, ' '); p = strchr(str, ' ');
if(!p) { if(!p)
{
cx->ret = 603; cx->ret = 603;
cx->state = HTS_DONE; cx->state = HTS_DONE;
return; return;
@ -313,15 +333,18 @@ static void process_header(struct http_ctx *cx, char *str)
cx->ret = atoi(p); cx->ret = atoi(p);
return; return;
} }
if(!strncmp(str, "Content-Length: ", 16)) { if(!strncmp(str, "Content-Length: ", 16))
{
cx->contlen = atoi(str+16); cx->contlen = atoi(str+16);
return; return;
} }
if(!strcmp(str, "Transfer-Encoding: chunked")) { if(!strcmp(str, "Transfer-Encoding: chunked"))
{
cx->chunked = 1; cx->chunked = 1;
return; return;
} }
if(!strcmp(str, "Connection: close")) { if(!strcmp(str, "Connection: close"))
{
cx->cclose = 1; cx->cclose = 1;
return; return;
} }
@ -329,14 +352,17 @@ static void process_header(struct http_ctx *cx, char *str)
static void process_byte(struct http_ctx *cx, char ch) static void process_byte(struct http_ctx *cx, char ch)
{ {
if(cx->rxtogo) { if(cx->rxtogo)
{
cx->rxtogo--; cx->rxtogo--;
if(!cx->rbuf) { if(!cx->rbuf)
{
cx->rbuf = malloc(256); cx->rbuf = malloc(256);
cx->rlen = 256; cx->rlen = 256;
} }
if(cx->rptr >= cx->rlen-1) { if(cx->rptr >= cx->rlen-1)
{
cx->rlen *= 2; cx->rlen *= 2;
cx->rbuf = realloc(cx->rbuf, cx->rlen); cx->rbuf = realloc(cx->rbuf, cx->rlen);
} }
@ -344,13 +370,19 @@ static void process_byte(struct http_ctx *cx, char ch)
if(!cx->rxtogo && !cx->chunked) if(!cx->rxtogo && !cx->chunked)
cx->state = HTS_DONE; cx->state = HTS_DONE;
} else { }
if(ch == '\n') { else
{
if(ch == '\n')
{
cx->hbuf[cx->hptr] = 0; cx->hbuf[cx->hptr] = 0;
process_header(cx, cx->hbuf); process_header(cx, cx->hbuf);
cx->hptr = 0; cx->hptr = 0;
} else if(ch != '\r') { }
if(cx->hptr >= cx->hlen-1) { else if(ch != '\r')
{
if(cx->hptr >= cx->hlen-1)
{
cx->hlen *= 2; cx->hlen *= 2;
cx->hbuf = realloc(cx->hbuf, cx->hlen); cx->hbuf = realloc(cx->hbuf, cx->hlen);
} }
@ -369,11 +401,13 @@ int http_async_req_status(void *ctx)
unsigned long tmp2; unsigned long tmp2;
#endif #endif
switch(cx->state) { switch(cx->state)
{
case HTS_STRT: case HTS_STRT:
dns = getserv(cx->host); dns = getserv(cx->host);
srv = getport(cx->host); srv = getport(cx->host);
if(resolve(dns, srv, &cx->addr)) { if(resolve(dns, srv, &cx->addr))
{
free(dns); free(dns);
free(srv); free(srv);
cx->state = HTS_DONE; cx->state = HTS_DONE;
@ -389,7 +423,8 @@ int http_async_req_status(void *ctx)
cx->last = now; cx->last = now;
return 0; return 0;
case HTS_CONN: case HTS_CONN:
if(cx->fd == PERROR) { if(cx->fd == PERROR)
{
cx->fd = socket(AF_INET, SOCK_STREAM, 0); cx->fd = socket(AF_INET, SOCK_STREAM, 0);
if(cx->fd == PERROR) if(cx->fd == PERROR)
goto fail; goto fail;
@ -426,7 +461,8 @@ int http_async_req_status(void *ctx)
goto timeout; goto timeout;
return 0; return 0;
case HTS_IDLE: case HTS_IDLE:
if(cx->txdl) { if(cx->txdl)
{
// generate POST // generate POST
cx->tbuf = malloc(strlen(cx->host) + strlen(cx->path) + 121 + cx->txdl + cx->thlen); cx->tbuf = malloc(strlen(cx->host) + strlen(cx->path) + 121 + cx->txdl + cx->thlen);
cx->tptr = 0; cx->tptr = 0;
@ -435,7 +471,8 @@ int http_async_req_status(void *ctx)
cx->tlen += sprintf(cx->tbuf+cx->tlen, "Host: %s\n", cx->host); cx->tlen += sprintf(cx->tbuf+cx->tlen, "Host: %s\n", cx->host);
if(!cx->keep) if(!cx->keep)
cx->tlen += sprintf(cx->tbuf+cx->tlen, "Connection: close\n"); cx->tlen += sprintf(cx->tbuf+cx->tlen, "Connection: close\n");
if(cx->thdr) { if(cx->thdr)
{
memcpy(cx->tbuf+cx->tlen, cx->thdr, cx->thlen); memcpy(cx->tbuf+cx->tlen, cx->thdr, cx->thlen);
cx->tlen += cx->thlen; cx->tlen += cx->thlen;
free(cx->thdr); free(cx->thdr);
@ -454,14 +491,17 @@ int http_async_req_status(void *ctx)
free(cx->txd); free(cx->txd);
cx->txd = NULL; cx->txd = NULL;
cx->txdl = 0; cx->txdl = 0;
} else { }
else
{
// generate GET // generate GET
cx->tbuf = malloc(strlen(cx->host) + strlen(cx->path) + 89 + cx->thlen); cx->tbuf = malloc(strlen(cx->host) + strlen(cx->path) + 89 + cx->thlen);
cx->tptr = 0; cx->tptr = 0;
cx->tlen = 0; cx->tlen = 0;
cx->tlen += sprintf(cx->tbuf+cx->tlen, "GET %s HTTP/1.1\n", cx->path); cx->tlen += sprintf(cx->tbuf+cx->tlen, "GET %s HTTP/1.1\n", cx->path);
cx->tlen += sprintf(cx->tbuf+cx->tlen, "Host: %s\n", cx->host); cx->tlen += sprintf(cx->tbuf+cx->tlen, "Host: %s\n", cx->host);
if(cx->thdr) { if(cx->thdr)
{
memcpy(cx->tbuf+cx->tlen, cx->thdr, cx->thlen); memcpy(cx->tbuf+cx->tlen, cx->thdr, cx->thlen);
cx->tlen += cx->thlen; cx->tlen += cx->thlen;
free(cx->thdr); free(cx->thdr);
@ -484,9 +524,11 @@ int http_async_req_status(void *ctx)
tmp = send(cx->fd, cx->tbuf+cx->tptr, cx->tlen-cx->tptr, 0); tmp = send(cx->fd, cx->tbuf+cx->tptr, cx->tlen-cx->tptr, 0);
if(tmp==PERROR && PERRNO!=PEAGAIN && PERRNO!=PEINTR) if(tmp==PERROR && PERRNO!=PEAGAIN && PERRNO!=PEINTR)
goto fail; goto fail;
if(tmp!=PERROR) { if(tmp!=PERROR)
{
cx->tptr += tmp; cx->tptr += tmp;
if(cx->tptr == cx->tlen) { if(cx->tptr == cx->tlen)
{
cx->tptr = 0; cx->tptr = 0;
cx->tlen = 0; cx->tlen = 0;
if(cx->tbuf) if(cx->tbuf)
@ -502,8 +544,10 @@ int http_async_req_status(void *ctx)
tmp = recv(cx->fd, buf, CHUNK, 0); tmp = recv(cx->fd, buf, CHUNK, 0);
if(tmp==PERROR && PERRNO!=PEAGAIN && PERRNO!=PEINTR) if(tmp==PERROR && PERRNO!=PEAGAIN && PERRNO!=PEINTR)
goto fail; goto fail;
if(tmp!=PERROR) { if(tmp!=PERROR)
for(i=0;i<tmp;i++) { {
for(i=0; i<tmp; i++)
{
process_byte(cx, buf[i]); process_byte(cx, buf[i]);
if(cx->state == HTS_DONE) if(cx->state == HTS_DONE)
return 1; return 1;
@ -537,24 +581,29 @@ char *http_async_req_stop(void *ctx, int *ret, int *len)
if(cx->state != HTS_DONE) if(cx->state != HTS_DONE)
while(!http_async_req_status(ctx)) ; while(!http_async_req_status(ctx)) ;
if(cx->host) { if(cx->host)
{
free(cx->host); free(cx->host);
cx->host = NULL; cx->host = NULL;
} }
if(cx->path) { if(cx->path)
{
free(cx->path); free(cx->path);
cx->path = NULL; cx->path = NULL;
} }
if(cx->txd) { if(cx->txd)
{
free(cx->txd); free(cx->txd);
cx->txd = NULL; cx->txd = NULL;
cx->txdl = 0; cx->txdl = 0;
} }
if(cx->hbuf) { if(cx->hbuf)
{
free(cx->hbuf); free(cx->hbuf);
cx->hbuf = NULL; cx->hbuf = NULL;
} }
if(cx->thdr) { if(cx->thdr)
{
free(cx->thdr); free(cx->thdr);
cx->thdr = NULL; cx->thdr = NULL;
cx->thlen = 0; cx->thlen = 0;
@ -574,15 +623,18 @@ char *http_async_req_stop(void *ctx, int *ret, int *len)
if(!cx->keep) if(!cx->keep)
http_async_req_close(ctx); http_async_req_close(ctx);
else if(cx->cclose) { else if(cx->cclose)
{
PCLOSE(cx->fd); PCLOSE(cx->fd);
cx->fd = PERROR; cx->fd = PERROR;
if(cx->fdhost) { if(cx->fdhost)
{
free(cx->fdhost); free(cx->fdhost);
cx->fdhost = NULL; cx->fdhost = NULL;
} }
cx->state = HTS_STRT; cx->state = HTS_STRT;
} else }
else
cx->state = HTS_IDLE; cx->state = HTS_IDLE;
return rxd; return rxd;
@ -601,7 +653,8 @@ void http_async_req_close(void *ctx)
{ {
struct http_ctx *cx = ctx; struct http_ctx *cx = ctx;
void *tmp; void *tmp;
if(cx->host) { if(cx->host)
{
cx->keep = 1; cx->keep = 1;
tmp = http_async_req_stop(ctx, NULL, NULL); tmp = http_async_req_stop(ctx, NULL, NULL);
if(tmp) if(tmp)
@ -616,7 +669,8 @@ void http_async_req_close(void *ctx)
char *http_simple_get(char *uri, int *ret, int *len) char *http_simple_get(char *uri, int *ret, int *len)
{ {
void *ctx = http_async_req_start(NULL, uri, NULL, 0, 0); void *ctx = http_async_req_start(NULL, uri, NULL, 0, 0);
if(!ctx) { if(!ctx)
{
if(ret) if(ret)
*ret = 600; *ret = 600;
if(len) if(len)
@ -634,9 +688,11 @@ void http_auth_headers(void *ctx, char *user, char *pass)
unsigned int m; unsigned int m;
struct md5_context md5; struct md5_context md5;
if(user) { if(user)
{
http_async_add_header(ctx, "X-Auth-User", user); http_async_add_header(ctx, "X-Auth-User", user);
if(pass) { if(pass)
{
md5_init(&md5); md5_init(&md5);
md5_update(&md5, (unsigned char *)user, strlen(user)); md5_update(&md5, (unsigned char *)user, strlen(user));
md5_update(&md5, (unsigned char *)"-", 1); md5_update(&md5, (unsigned char *)"-", 1);
@ -645,7 +701,8 @@ void http_auth_headers(void *ctx, char *user, char *pass)
md5_update(&md5, (unsigned char *)pass, strlen(pass)); md5_update(&md5, (unsigned char *)pass, strlen(pass));
md5_final(hash, &md5); md5_final(hash, &md5);
tmp = malloc(33); tmp = malloc(33);
for(i=0;i<16;i++) { for(i=0; i<16; i++)
{
tmp[i*2] = hex[hash[i]>>4]; tmp[i*2] = hex[hash[i]>>4];
tmp[i*2+1] = hex[hash[i]&15]; tmp[i*2+1] = hex[hash[i]&15];
} }
@ -659,7 +716,8 @@ char *http_auth_get(char *uri, char *user, char *pass, int *ret, int *len)
{ {
void *ctx = http_async_req_start(NULL, uri, NULL, 0, 0); void *ctx = http_async_req_start(NULL, uri, NULL, 0, 0);
if(!ctx) { if(!ctx)
{
if(ret) if(ret)
*ret = 600; *ret = 600;
if(len) if(len)
@ -672,7 +730,8 @@ char *http_auth_get(char *uri, char *user, char *pass, int *ret, int *len)
char *http_simple_post(char *uri, char *data, int dlen, int *ret, int *len) char *http_simple_post(char *uri, char *data, int dlen, int *ret, int *len)
{ {
void *ctx = http_async_req_start(NULL, uri, data, dlen, 0); void *ctx = http_async_req_start(NULL, uri, data, dlen, 0);
if(!ctx) { if(!ctx)
{
if(ret) if(ret)
*ret = 600; *ret = 600;
if(len) if(len)
@ -684,71 +743,131 @@ char *http_simple_post(char *uri, char *data, int dlen, int *ret, int *len)
char *http_ret_text(int ret) char *http_ret_text(int ret)
{ {
switch(ret) { switch(ret)
case 100: return "Continue"; {
case 101: return "Switching Protocols"; case 100:
case 102: return "Processing"; return "Continue";
case 101:
return "Switching Protocols";
case 102:
return "Processing";
case 200: return "OK"; case 200:
case 201: return "Created"; return "OK";
case 202: return "Accepted"; case 201:
case 203: return "Non-Authoritative Information"; return "Created";
case 204: return "No Content"; case 202:
case 205: return "Reset Content"; return "Accepted";
case 206: return "Partial Content"; case 203:
case 207: return "Multi-Status"; return "Non-Authoritative Information";
case 204:
return "No Content";
case 205:
return "Reset Content";
case 206:
return "Partial Content";
case 207:
return "Multi-Status";
case 300: return "Multiple Choices"; case 300:
case 301: return "Moved Permanently"; return "Multiple Choices";
case 302: return "Found"; case 301:
case 303: return "See Other"; return "Moved Permanently";
case 304: return "Not Modified"; case 302:
case 305: return "Use Proxy"; return "Found";
case 306: return "Switch Proxy"; case 303:
case 307: return "Temporary Redirect"; return "See Other";
case 304:
return "Not Modified";
case 305:
return "Use Proxy";
case 306:
return "Switch Proxy";
case 307:
return "Temporary Redirect";
case 400: return "Bad Request"; case 400:
case 401: return "Unauthorized"; return "Bad Request";
case 402: return "Payment Required"; case 401:
case 403: return "Forbidden"; return "Unauthorized";
case 404: return "Not Found"; case 402:
case 405: return "Method Not Allowed"; return "Payment Required";
case 406: return "Not Acceptable"; case 403:
case 407: return "Proxy Authentication Required"; return "Forbidden";
case 408: return "Request Timeout"; case 404:
case 409: return "Conflict"; return "Not Found";
case 410: return "Gone"; case 405:
case 411: return "Length Required"; return "Method Not Allowed";
case 412: return "Precondition Failed"; case 406:
case 413: return "Request Entity Too Large"; return "Not Acceptable";
case 414: return "Request URI Too Long"; case 407:
case 415: return "Unsupported Media Type"; return "Proxy Authentication Required";
case 416: return "Requested Range Not Satisfiable"; case 408:
case 417: return "Expectation Failed"; return "Request Timeout";
case 422: return "Unprocessable Entity"; case 409:
case 423: return "Locked"; return "Conflict";
case 424: return "Failed Dependency"; case 410:
case 425: return "Unordered Collection"; return "Gone";
case 426: return "Upgrade Required"; case 411:
return "Length Required";
case 412:
return "Precondition Failed";
case 413:
return "Request Entity Too Large";
case 414:
return "Request URI Too Long";
case 415:
return "Unsupported Media Type";
case 416:
return "Requested Range Not Satisfiable";
case 417:
return "Expectation Failed";
case 422:
return "Unprocessable Entity";
case 423:
return "Locked";
case 424:
return "Failed Dependency";
case 425:
return "Unordered Collection";
case 426:
return "Upgrade Required";
case 500: return "Internal Server Error"; case 500:
case 501: return "Not Implemented"; return "Internal Server Error";
case 502: return "Bad Gateway"; case 501:
case 503: return "Service Unavailable"; return "Not Implemented";
case 504: return "Gateway Timeout"; case 502:
case 505: return "HTTP Version Not Supported"; return "Bad Gateway";
case 506: return "Variant Also Negotiates"; case 503:
case 507: return "Insufficient Storage"; return "Service Unavailable";
case 509: return "Bandwidth Limit Exceeded"; case 504:
case 510: return "Not Extended"; return "Gateway Timeout";
case 505:
return "HTTP Version Not Supported";
case 506:
return "Variant Also Negotiates";
case 507:
return "Insufficient Storage";
case 509:
return "Bandwidth Limit Exceeded";
case 510:
return "Not Extended";
case 600: return "Internal Client Error"; case 600:
case 601: return "Unsupported Protocol"; return "Internal Client Error";
case 602: return "Server Not Found"; case 601:
case 603: return "Malformed Response"; return "Unsupported Protocol";
case 604: return "Network Not Available"; case 602:
case 605: return "Request Timed Out"; return "Server Not Found";
default: return "Unknown Status Code"; case 603:
return "Malformed Response";
case 604:
return "Network Not Available";
case 605:
return "Request Timed Out";
default:
return "Unknown Status Code";
} }
} }
char *http_multipart_post(char *uri, char **names, char **parts, int *plens, char *user, char *pass, int *ret, int *len) char *http_multipart_post(char *uri, char **names, char **parts, int *plens, char *user, char *pass, int *ret, int *len)
@ -764,22 +883,26 @@ char *http_multipart_post(char *uri, char **names, char **parts, int *plens, cha
//struct md5_context md52; //struct md5_context md52;
int own_plen = 0; int own_plen = 0;
if(names) { if(names)
if(!plens) { {
if(!plens)
{
own_plen = 1; own_plen = 1;
for(i=0;names[i];i++) ; for(i=0; names[i]; i++) ;
plens = calloc(i, sizeof(int)); plens = calloc(i, sizeof(int));
for(i=0;names[i];i++) for(i=0; names[i]; i++)
plens[i] = strlen(parts[i]); plens[i] = strlen(parts[i]);
} }
retry: retry:
if(blen >= 31) if(blen >= 31)
goto fail; goto fail;
memset(map, 0, 62*sizeof(int)); memset(map, 0, 62*sizeof(int));
for(i=0;names[i];i++) { for(i=0; names[i]; i++)
for(j=0;j<plens[i]-blen;j++) {
if(!blen || !memcmp(parts[i]+j, boundary, blen)) { for(j=0; j<plens[i]-blen; j++)
if(!blen || !memcmp(parts[i]+j, boundary, blen))
{
ch = parts[i][j+blen]; ch = parts[i][j+blen];
if(ch>='0' && ch<='9') if(ch>='0' && ch<='9')
map[ch-'0']++; map[ch-'0']++;
@ -791,8 +914,9 @@ char *http_multipart_post(char *uri, char **names, char **parts, int *plens, cha
} }
m = ~0; m = ~0;
j = 61; j = 61;
for(i=0;i<62;i++) for(i=0; i<62; i++)
if(map[i]<m) { if(map[i]<m)
{
m = map[i]; m = map[i];
j = i; j = i;
} }
@ -807,15 +931,17 @@ char *http_multipart_post(char *uri, char **names, char **parts, int *plens, cha
goto retry; goto retry;
boundary[blen] = 0; boundary[blen] = 0;
for(i=0;names[i];i++) for(i=0; names[i]; i++)
dlen += blen+strlen(names[i])+plens[i]+128; dlen += blen+strlen(names[i])+plens[i]+128;
dlen += blen+8; dlen += blen+8;
data = malloc(dlen); data = malloc(dlen);
dlen = 0; dlen = 0;
for(i=0;names[i];i++) { for(i=0; names[i]; i++)
{
dlen += sprintf(data+dlen, "--%s\r\n", boundary); dlen += sprintf(data+dlen, "--%s\r\n", boundary);
dlen += sprintf(data+dlen, "Content-transfer-encoding: binary\r\n"); dlen += sprintf(data+dlen, "Content-transfer-encoding: binary\r\n");
if(strchr(names[i], ':')) { if(strchr(names[i], ':'))
{
tmp = mystrdup(names[i]); tmp = mystrdup(names[i]);
p = strchr(tmp, ':'); p = strchr(tmp, ':');
*p = 0; *p = 0;
@ -823,7 +949,8 @@ char *http_multipart_post(char *uri, char **names, char **parts, int *plens, cha
free(tmp); free(tmp);
p = strchr(names[i], ':'); p = strchr(names[i], ':');
dlen += sprintf(data+dlen, "filename=\"%s\"\r\n\r\n", p+1); dlen += sprintf(data+dlen, "filename=\"%s\"\r\n\r\n", p+1);
} else }
else
dlen += sprintf(data+dlen, "content-disposition: form-data; name=\"%s\"\r\n\r\n", names[i]); dlen += sprintf(data+dlen, "content-disposition: form-data; name=\"%s\"\r\n\r\n", names[i]);
memcpy(data+dlen, parts[i], plens[i]); memcpy(data+dlen, parts[i], plens[i]);
dlen += plens[i]; dlen += plens[i];
@ -836,15 +963,19 @@ char *http_multipart_post(char *uri, char **names, char **parts, int *plens, cha
if(!ctx) if(!ctx)
goto fail; goto fail;
if(user) { if(user)
{
http_async_add_header(ctx, "X-Auth-User", user); http_async_add_header(ctx, "X-Auth-User", user);
if(pass) { if(pass)
{
md5_init(&md5); md5_init(&md5);
md5_update(&md5, (unsigned char *)user, strlen(user)); md5_update(&md5, (unsigned char *)user, strlen(user));
md5_update(&md5, (unsigned char *)"-", 1); md5_update(&md5, (unsigned char *)"-", 1);
m = 0; m = 0;
if(names) { if(names)
for(i=0;names[i];i++) { {
for(i=0; names[i]; i++)
{
//md5_update(&md5, (unsigned char *)parts[i], plens[i]); //WHY? //md5_update(&md5, (unsigned char *)parts[i], plens[i]); //WHY?
//md5_update(&md5, (unsigned char *)"-", 1); //md5_update(&md5, (unsigned char *)"-", 1);
p = strchr(names[i], ':'); p = strchr(names[i], ':');
@ -856,16 +987,21 @@ char *http_multipart_post(char *uri, char **names, char **parts, int *plens, cha
tmp = malloc(m); tmp = malloc(m);
m = 0; m = 0;
for(i=0;names[i];i++) { for(i=0; names[i]; i++)
{
p = strchr(names[i], ':'); p = strchr(names[i], ':');
if(m) { if(m)
{
tmp[m] = ' '; tmp[m] = ' ';
m ++; m ++;
} }
if(p) { if(p)
{
memcpy(tmp+m, names[i], p-names[i]); memcpy(tmp+m, names[i], p-names[i]);
m += p - names[i]; m += p - names[i];
} else { }
else
{
strcpy(tmp+m, names[i]); strcpy(tmp+m, names[i]);
m += strlen(names[i]); m += strlen(names[i]);
} }
@ -878,7 +1014,8 @@ char *http_multipart_post(char *uri, char **names, char **parts, int *plens, cha
md5_update(&md5, (unsigned char *)pass, strlen(pass)); md5_update(&md5, (unsigned char *)pass, strlen(pass));
md5_final(hash, &md5); md5_final(hash, &md5);
tmp = malloc(33); tmp = malloc(33);
for(i=0;i<16;i++) { for(i=0; i<16; i++)
{
tmp[i*2] = hex[hash[i]>>4]; tmp[i*2] = hex[hash[i]>>4];
tmp[i*2+1] = hex[hash[i]&15]; tmp[i*2+1] = hex[hash[i]&15];
} }
@ -888,7 +1025,8 @@ char *http_multipart_post(char *uri, char **names, char **parts, int *plens, cha
} }
} }
if(data) { if(data)
{
tmp = malloc(32+strlen((char *)boundary)); tmp = malloc(32+strlen((char *)boundary));
sprintf(tmp, "multipart/form-data, boundary=%s", boundary); sprintf(tmp, "multipart/form-data, boundary=%s", boundary);
http_async_add_header(ctx, "Content-type", tmp); http_async_add_header(ctx, "Content-type", tmp);

19
md5.c Executable file → Normal file
View File

@ -40,11 +40,13 @@ void md5_update(struct md5_context *ctx, unsigned char const *buf, unsigned len)
// use leading data to top up the buffer // use leading data to top up the buffer
if(t) { if(t)
{
unsigned char *p = ctx->in + t; unsigned char *p = ctx->in + t;
t = 64-t; t = 64-t;
if (len < t) { if (len < t)
{
memcpy(p, buf, len); memcpy(p, buf, len);
return; return;
} }
@ -56,7 +58,8 @@ void md5_update(struct md5_context *ctx, unsigned char const *buf, unsigned len)
// following 64-byte chunks // following 64-byte chunks
while(len >= 64) { while(len >= 64)
{
memcpy(ctx->in, buf, 64); memcpy(ctx->in, buf, 64);
md5_transform(ctx->buf, ctx->in); md5_transform(ctx->buf, ctx->in);
buf += 64; buf += 64;
@ -84,12 +87,15 @@ void md5_final(unsigned char digest[16], struct md5_context *ctx)
count = 64 - 1 - count; count = 64 - 1 - count;
// Pad out to 56 mod 64 // Pad out to 56 mod 64
if(count < 8) { if(count < 8)
{
// we need to finish a whole block before padding // we need to finish a whole block before padding
memset(p, 0, count); memset(p, 0, count);
md5_transform(ctx->buf, ctx->in); md5_transform(ctx->buf, ctx->in);
memset(ctx->in, 0, 56); memset(ctx->in, 0, 56);
} else { }
else
{
// just pad to 56 bytes // just pad to 56 bytes
memset(p, 0, count-8); memset(p, 0, count-8);
} }
@ -216,7 +222,8 @@ void md5_ascii(char *result, unsigned char const *buf, unsigned len)
md5_update(&md5, buf, len); md5_update(&md5, buf, len);
md5_final(hash, &md5); md5_final(hash, &md5);
for(i=0;i<16;i++) { for(i=0; i<16; i++)
{
result[i*2] = hex[(hash[i]>>4)&0xF]; result[i*2] = hex[(hash[i]>>4)&0xF];
result[i*2+1] = hex[hash[i]&0x0F]; result[i*2+1] = hex[hash[i]&0x0F];
} }

3
md5.h Executable file → Normal file
View File

@ -1,7 +1,8 @@
#ifndef MD5_H #ifndef MD5_H
#define MD5_H #define MD5_H
struct md5_context { struct md5_context
{
unsigned buf[4]; unsigned buf[4];
unsigned bits[2]; unsigned bits[2];
unsigned char in[64]; unsigned char in[64];

4109
powder.c Executable file → Normal file

File diff suppressed because it is too large Load Diff

39
update.c Executable file → Normal file
View File

@ -43,14 +43,17 @@ static char *exe_name(void)
{ {
#if defined WIN32 #if defined WIN32
char *name= (char *)malloc(64), max=64, res; char *name= (char *)malloc(64), max=64, res;
while((res = (char)GetModuleFileName(NULL, name, max)) >= max) { while((res = (char)GetModuleFileName(NULL, name, max)) >= max)
{
#elif defined MACOSX #elif defined MACOSX
char *fn=malloc(64),*name=malloc(PATH_MAX), max=64, res; char *fn=malloc(64),*name=malloc(PATH_MAX), max=64, res;
if(_NSGetExecutablePath(fn, &max) != 0) { if(_NSGetExecutablePath(fn, &max) != 0)
{
fn = realloc(fn, max); fn = realloc(fn, max);
_NSGetExecutablePath(fn, &max); _NSGetExecutablePath(fn, &max);
} }
if(realpath(fn, name) == NULL) { if(realpath(fn, name) == NULL)
{
free(fn); free(fn);
free(name); free(name);
return NULL; return NULL;
@ -60,7 +63,8 @@ static char *exe_name(void)
char fn[64], *name=malloc(64), max=64, res; char fn[64], *name=malloc(64), max=64, res;
sprintf(fn, "/proc/self/exe"); sprintf(fn, "/proc/self/exe");
memset(name, 0, max); memset(name, 0, max);
while((res = readlink(fn, name, max)) >= max-1) { while((res = readlink(fn, name, max)) >= max-1)
{
#endif #endif
#ifndef MACOSX #ifndef MACOSX
max *= 2; max *= 2;
@ -68,7 +72,8 @@ static char *exe_name(void)
memset(name, 0, max); memset(name, 0, max);
} }
#endif #endif
if(res <= 0) { if(res <= 0)
{
free(name); free(name);
return NULL; return NULL;
} }
@ -101,14 +106,16 @@ int update_start(char *data, int len)
f = fopen(self, "wb"); f = fopen(self, "wb");
if(!f) if(!f)
goto fail; goto fail;
if(fwrite(data, 1, len, f) != len) { if(fwrite(data, 1, len, f) != len)
{
fclose(f); fclose(f);
DeleteFile(self); DeleteFile(self);
goto fail; goto fail;
} }
fclose(f); fclose(f);
if((int)ShellExecute(NULL, "open", self, NULL, NULL, SW_SHOWNORMAL) <= 32) { if((int)ShellExecute(NULL, "open", self, NULL, NULL, SW_SHOWNORMAL) <= 32)
{
DeleteFile(self); DeleteFile(self);
goto fail; goto fail;
} }
@ -122,19 +129,22 @@ int update_start(char *data, int len)
f = fopen(temp, "w"); f = fopen(temp, "w");
if(!f) if(!f)
goto fail; goto fail;
if(fwrite(data, 1, len, f) != len) { if(fwrite(data, 1, len, f) != len)
{
fclose(f); fclose(f);
unlink(temp); unlink(temp);
goto fail; goto fail;
} }
fclose(f); fclose(f);
if(chmod(temp, 0755)) { if(chmod(temp, 0755))
{
unlink(temp); unlink(temp);
goto fail; goto fail;
} }
if(rename(temp, self)) { if(rename(temp, self))
{
unlink(temp); unlink(temp);
goto fail; goto fail;
} }
@ -161,16 +171,19 @@ int update_finish(void)
p += 4; p += 4;
strcpy(p, "_update.exe"); strcpy(p, "_update.exe");
while(!DeleteFile(temp)) { while(!DeleteFile(temp))
{
err = GetLastError(); err = GetLastError();
if(err == ERROR_FILE_NOT_FOUND) { if(err == ERROR_FILE_NOT_FOUND)
{
// just as well, then // just as well, then
free(temp); free(temp);
return 0; return 0;
} }
Sleep(500); Sleep(500);
timeout--; timeout--;
if(timeout <= 0) { if(timeout <= 0)
{
free(temp); free(temp);
return 1; return 1;
} }