Mercurial > urweb
comparison src/c/urweb.c @ 1369:1a78ca089bd0
Expose buffer type for other C libraries; replace minusSeconds with addSeconds
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sun, 26 Dec 2010 15:52:56 -0500 |
parents | 8301ee4ab58c |
children | 44a12a321150 |
comparison
equal
deleted
inserted
replaced
1368:b2bc8bcd546f | 1369:1a78ca089bd0 |
---|---|
53 } | 53 } |
54 | 54 |
55 | 55 |
56 // Buffers | 56 // Buffers |
57 | 57 |
58 typedef struct { | 58 void uw_buffer_init(size_t max, uw_buffer *b, size_t s) { |
59 size_t max; | |
60 char *start, *front, *back; | |
61 } buf; | |
62 | |
63 static void buf_init(size_t max, buf *b, size_t s) { | |
64 b->max = max; | 59 b->max = max; |
65 b->front = b->start = malloc(s); | 60 b->front = b->start = malloc(s); |
66 b->back = b->front + s; | 61 b->back = b->front + s; |
67 } | 62 } |
68 | 63 |
69 static void buf_free(buf *b) { | 64 void uw_buffer_free(uw_buffer *b) { |
70 free(b->start); | 65 free(b->start); |
71 } | 66 } |
72 | 67 |
73 static void buf_reset(buf *b) { | 68 void uw_buffer_reset(uw_buffer *b) { |
74 b->front = b->start; | 69 b->front = b->start; |
75 } | 70 } |
76 | 71 |
77 static int buf_check(buf *b, size_t extra) { | 72 int uw_buffer_check(uw_buffer *b, size_t extra) { |
78 if (b->back - b->front < extra) { | 73 if (b->back - b->front < extra) { |
79 size_t desired = b->front - b->start + extra, next; | 74 size_t desired = b->front - b->start + extra, next; |
80 char *new_heap; | 75 char *new_heap; |
81 | 76 |
82 next = b->back - b->start; | 77 next = b->back - b->start; |
100 return 0; | 95 return 0; |
101 } | 96 } |
102 | 97 |
103 __attribute__((noreturn)) void uw_error(uw_context, failure_kind, const char *, ...); | 98 __attribute__((noreturn)) void uw_error(uw_context, failure_kind, const char *, ...); |
104 | 99 |
105 static void ctx_buf_check(uw_context ctx, const char *kind, buf *b, size_t extra) { | 100 static void ctx_uw_buffer_check(uw_context ctx, const char *kind, uw_buffer *b, size_t extra) { |
106 if (buf_check(b, extra)) | 101 if (uw_buffer_check(b, extra)) |
107 uw_error(ctx, FATAL, "Memory limit exceeded (%s)", kind); | 102 uw_error(ctx, FATAL, "Memory limit exceeded (%s)", kind); |
108 } | 103 } |
109 | 104 |
110 static size_t buf_used(buf *b) { | 105 size_t uw_buffer_used(uw_buffer *b) { |
111 return b->front - b->start; | 106 return b->front - b->start; |
112 } | 107 } |
113 | 108 |
114 static size_t buf_avail(buf *b) { | 109 size_t uw_buffer_avail(uw_buffer *b) { |
115 return b->back - b->start; | 110 return b->back - b->start; |
116 } | 111 } |
117 | 112 |
118 static int buf_append(buf *b, const char *s, size_t len) { | 113 int uw_buffer_append(uw_buffer *b, const char *s, size_t len) { |
119 if (buf_check(b, len+1)) | 114 if (uw_buffer_check(b, len+1)) |
120 return 1; | 115 return 1; |
121 | 116 |
122 memcpy(b->front, s, len); | 117 memcpy(b->front, s, len); |
123 b->front += len; | 118 b->front += len; |
124 *b->front = 0; | 119 *b->front = 0; |
125 | 120 |
126 return 0; | 121 return 0; |
127 } | 122 } |
128 | 123 |
129 static void ctx_buf_append(uw_context ctx, const char *kind, buf *b, const char *s, size_t len) { | 124 static void ctx_uw_buffer_append(uw_context ctx, const char *kind, uw_buffer *b, const char *s, size_t len) { |
130 ctx_buf_check(ctx, kind, b, len+1); | 125 ctx_uw_buffer_check(ctx, kind, b, len+1); |
131 | 126 |
132 memcpy(b->front, s, len); | 127 memcpy(b->front, s, len); |
133 b->front += len; | 128 b->front += len; |
134 *b->front = 0; | 129 *b->front = 0; |
135 } | 130 } |
143 unsigned id; | 138 unsigned id; |
144 usage mode; | 139 usage mode; |
145 int pass; | 140 int pass; |
146 struct client *next; | 141 struct client *next; |
147 pthread_mutex_t lock, pull_lock; | 142 pthread_mutex_t lock, pull_lock; |
148 buf msgs; | 143 uw_buffer msgs; |
149 int sock; | 144 int sock; |
150 int (*send)(int sockfd, const void *buf, ssize_t len); | 145 int (*send)(int sockfd, const void *buf, ssize_t len); |
151 int (*close)(int fd); | 146 int (*close)(int fd); |
152 time_t last_contact; | 147 time_t last_contact; |
153 unsigned n_channels; | 148 unsigned n_channels; |
186 clients = realloc(clients, sizeof(client) * n_clients); | 181 clients = realloc(clients, sizeof(client) * n_clients); |
187 c = malloc(sizeof(client)); | 182 c = malloc(sizeof(client)); |
188 c->id = n_clients-1; | 183 c->id = n_clients-1; |
189 pthread_mutex_init(&c->lock, NULL); | 184 pthread_mutex_init(&c->lock, NULL); |
190 pthread_mutex_init(&c->pull_lock, NULL); | 185 pthread_mutex_init(&c->pull_lock, NULL); |
191 buf_init(uw_messages_max, &c->msgs, 0); | 186 uw_buffer_init(uw_messages_max, &c->msgs, 0); |
192 clients[n_clients-1] = c; | 187 clients[n_clients-1] = c; |
193 } | 188 } |
194 | 189 |
195 pthread_mutex_lock(&c->lock); | 190 pthread_mutex_lock(&c->lock); |
196 c->mode = USED; | 191 c->mode = USED; |
197 c->pass = rand(); | 192 c->pass = rand(); |
198 c->sock = -1; | 193 c->sock = -1; |
199 c->last_contact = time(NULL); | 194 c->last_contact = time(NULL); |
200 buf_reset(&c->msgs); | 195 uw_buffer_reset(&c->msgs); |
201 c->n_channels = 0; | 196 c->n_channels = 0; |
202 c->refcount = 0; | 197 c->refcount = 0; |
203 c->data = uw_init_client_data(); | 198 c->data = uw_init_client_data(); |
204 pthread_mutex_unlock(&c->lock); | 199 pthread_mutex_unlock(&c->lock); |
205 | 200 |
284 c->sock = -1; | 279 c->sock = -1; |
285 } | 280 } |
286 | 281 |
287 c->last_contact = time(NULL); | 282 c->last_contact = time(NULL); |
288 | 283 |
289 if (buf_used(&c->msgs) > 0) { | 284 if (uw_buffer_used(&c->msgs) > 0) { |
290 send(sock, on_success, strlen(on_success)); | 285 send(sock, on_success, strlen(on_success)); |
291 send(sock, begin_msgs, sizeof(begin_msgs) - 1); | 286 send(sock, begin_msgs, sizeof(begin_msgs) - 1); |
292 send(sock, c->msgs.start, buf_used(&c->msgs)); | 287 send(sock, c->msgs.start, uw_buffer_used(&c->msgs)); |
293 buf_reset(&c->msgs); | 288 uw_buffer_reset(&c->msgs); |
294 close(sock); | 289 close(sock); |
295 } | 290 } |
296 else { | 291 else { |
297 c->sock = sock; | 292 c->sock = sock; |
298 c->send = send; | 293 c->send = send; |
313 static uw_Basis_channel new_channel(client *c) { | 308 static uw_Basis_channel new_channel(client *c) { |
314 uw_Basis_channel ch = {c->id, c->n_channels++}; | 309 uw_Basis_channel ch = {c->id, c->n_channels++}; |
315 return ch; | 310 return ch; |
316 } | 311 } |
317 | 312 |
318 static void client_send(client *c, buf *msg) { | 313 static void client_send(client *c, uw_buffer *msg) { |
319 pthread_mutex_lock(&c->lock); | 314 pthread_mutex_lock(&c->lock); |
320 | 315 |
321 if (c->sock != -1) { | 316 if (c->sock != -1) { |
322 c->send(c->sock, on_success, strlen(on_success)); | 317 c->send(c->sock, on_success, strlen(on_success)); |
323 c->send(c->sock, begin_msgs, sizeof(begin_msgs) - 1); | 318 c->send(c->sock, begin_msgs, sizeof(begin_msgs) - 1); |
324 c->send(c->sock, msg->start, buf_used(msg)); | 319 c->send(c->sock, msg->start, uw_buffer_used(msg)); |
325 c->close(c->sock); | 320 c->close(c->sock); |
326 c->sock = -1; | 321 c->sock = -1; |
327 } else if (buf_append(&c->msgs, msg->start, buf_used(msg))) | 322 } else if (uw_buffer_append(&c->msgs, msg->start, uw_buffer_used(msg))) |
328 fprintf(stderr, "Client message buffer size exceeded"); | 323 fprintf(stderr, "Client message buffer size exceeded"); |
329 | 324 |
330 pthread_mutex_unlock(&c->lock); | 325 pthread_mutex_unlock(&c->lock); |
331 } | 326 } |
332 | 327 |
363 void *arg; | 358 void *arg; |
364 } cleanup; | 359 } cleanup; |
365 | 360 |
366 typedef struct { | 361 typedef struct { |
367 unsigned client; | 362 unsigned client; |
368 buf msgs; | 363 uw_buffer msgs; |
369 } delta; | 364 } delta; |
370 | 365 |
371 typedef enum { | 366 typedef enum { |
372 UNSET, NORMAL, FIL, SUBFORM, SUBFORMS, ENTRY | 367 UNSET, NORMAL, FIL, SUBFORM, SUBFORMS, ENTRY |
373 } input_kind; | 368 } input_kind; |
405 uw_app *app; | 400 uw_app *app; |
406 | 401 |
407 char *(*get_header)(void *, const char *); | 402 char *(*get_header)(void *, const char *); |
408 void *get_header_data; | 403 void *get_header_data; |
409 | 404 |
410 buf outHeaders, page, heap, script; | 405 uw_buffer outHeaders, page, heap, script; |
411 int returning_indirectly; | 406 int returning_indirectly; |
412 input *inputs, *subinputs, *cur_container; | 407 input *inputs, *subinputs, *cur_container; |
413 size_t sz_inputs, n_subinputs, used_subinputs; | 408 size_t sz_inputs, n_subinputs, used_subinputs; |
414 | 409 |
415 int source_count; | 410 int source_count; |
463 ctx->app = NULL; | 458 ctx->app = NULL; |
464 | 459 |
465 ctx->get_header = NULL; | 460 ctx->get_header = NULL; |
466 ctx->get_header_data = NULL; | 461 ctx->get_header_data = NULL; |
467 | 462 |
468 buf_init(uw_headers_max, &ctx->outHeaders, 0); | 463 uw_buffer_init(uw_headers_max, &ctx->outHeaders, 0); |
469 buf_init(uw_page_max, &ctx->page, 0); | 464 uw_buffer_init(uw_page_max, &ctx->page, 0); |
470 ctx->returning_indirectly = 0; | 465 ctx->returning_indirectly = 0; |
471 buf_init(uw_heap_max, &ctx->heap, uw_min_heap); | 466 uw_buffer_init(uw_heap_max, &ctx->heap, uw_min_heap); |
472 buf_init(uw_script_max, &ctx->script, 1); | 467 uw_buffer_init(uw_script_max, &ctx->script, 1); |
473 ctx->script.start[0] = 0; | 468 ctx->script.start[0] = 0; |
474 | 469 |
475 ctx->inputs = malloc(0); | 470 ctx->inputs = malloc(0); |
476 ctx->cur_container = NULL; | 471 ctx->cur_container = NULL; |
477 ctx->subinputs = malloc(0); | 472 ctx->subinputs = malloc(0); |
550 } | 545 } |
551 | 546 |
552 void uw_free(uw_context ctx) { | 547 void uw_free(uw_context ctx) { |
553 size_t i; | 548 size_t i; |
554 | 549 |
555 buf_free(&ctx->outHeaders); | 550 uw_buffer_free(&ctx->outHeaders); |
556 buf_free(&ctx->script); | 551 uw_buffer_free(&ctx->script); |
557 buf_free(&ctx->page); | 552 uw_buffer_free(&ctx->page); |
558 buf_free(&ctx->heap); | 553 uw_buffer_free(&ctx->heap); |
559 free(ctx->inputs); | 554 free(ctx->inputs); |
560 free(ctx->subinputs); | 555 free(ctx->subinputs); |
561 free(ctx->cleanup); | 556 free(ctx->cleanup); |
562 free(ctx->transactionals); | 557 free(ctx->transactionals); |
563 uw_free_client_data(ctx->client_data); | 558 uw_free_client_data(ctx->client_data); |
564 | 559 |
565 for (i = 0; i < ctx->n_deltas; ++i) | 560 for (i = 0; i < ctx->n_deltas; ++i) |
566 buf_free(&ctx->deltas[i].msgs); | 561 uw_buffer_free(&ctx->deltas[i].msgs); |
567 free(ctx->deltas); | 562 free(ctx->deltas); |
568 | 563 |
569 for (i = 0; i < ctx->n_globals; ++i) | 564 for (i = 0; i < ctx->n_globals; ++i) |
570 if (ctx->globals[i].free) | 565 if (ctx->globals[i].free) |
571 ctx->globals[i].free(ctx->globals[i].data); | 566 ctx->globals[i].free(ctx->globals[i].data); |
573 | 568 |
574 free(ctx); | 569 free(ctx); |
575 } | 570 } |
576 | 571 |
577 void uw_reset_keep_error_message(uw_context ctx) { | 572 void uw_reset_keep_error_message(uw_context ctx) { |
578 buf_reset(&ctx->outHeaders); | 573 uw_buffer_reset(&ctx->outHeaders); |
579 buf_reset(&ctx->script); | 574 uw_buffer_reset(&ctx->script); |
580 ctx->script.start[0] = 0; | 575 ctx->script.start[0] = 0; |
581 buf_reset(&ctx->page); | 576 uw_buffer_reset(&ctx->page); |
582 ctx->returning_indirectly = 0; | 577 ctx->returning_indirectly = 0; |
583 buf_reset(&ctx->heap); | 578 uw_buffer_reset(&ctx->heap); |
584 ctx->regions = NULL; | 579 ctx->regions = NULL; |
585 ctx->cleanup_front = ctx->cleanup; | 580 ctx->cleanup_front = ctx->cleanup; |
586 ctx->source_count = 0; | 581 ctx->source_count = 0; |
587 ctx->used_deltas = 0; | 582 ctx->used_deltas = 0; |
588 ctx->client = NULL; | 583 ctx->client = NULL; |
1155 void uw_set_needs_sig(uw_context ctx, int n) { | 1150 void uw_set_needs_sig(uw_context ctx, int n) { |
1156 ctx->needs_sig = n; | 1151 ctx->needs_sig = n; |
1157 } | 1152 } |
1158 | 1153 |
1159 | 1154 |
1160 static void buf_check_ctx(uw_context ctx, const char *kind, buf *b, size_t extra, const char *desc) { | 1155 static void uw_buffer_check_ctx(uw_context ctx, const char *kind, uw_buffer *b, size_t extra, const char *desc) { |
1161 if (b->back - b->front < extra) { | 1156 if (b->back - b->front < extra) { |
1162 size_t desired = b->front - b->start + extra, next; | 1157 size_t desired = b->front - b->start + extra, next; |
1163 char *new_heap; | 1158 char *new_heap; |
1164 | 1159 |
1165 next = b->back - b->start; | 1160 next = b->back - b->start; |
1186 b->start = new_heap; | 1181 b->start = new_heap; |
1187 } | 1182 } |
1188 } | 1183 } |
1189 | 1184 |
1190 void uw_check_heap(uw_context ctx, size_t extra) { | 1185 void uw_check_heap(uw_context ctx, size_t extra) { |
1191 buf_check_ctx(ctx, "heap", &ctx->heap, extra, "heap chunk"); | 1186 uw_buffer_check_ctx(ctx, "heap", &ctx->heap, extra, "heap chunk"); |
1192 } | 1187 } |
1193 | 1188 |
1194 char *uw_heap_front(uw_context ctx) { | 1189 char *uw_heap_front(uw_context ctx) { |
1195 return ctx->heap.front; | 1190 return ctx->heap.front; |
1196 } | 1191 } |
1229 ctx->heap.front = (char *) r; | 1224 ctx->heap.front = (char *) r; |
1230 ctx->regions = r->next; | 1225 ctx->regions = r->next; |
1231 } | 1226 } |
1232 | 1227 |
1233 void uw_memstats(uw_context ctx) { | 1228 void uw_memstats(uw_context ctx) { |
1234 printf("Headers: %lu/%lu\n", (unsigned long)buf_used(&ctx->outHeaders), (unsigned long)buf_avail(&ctx->outHeaders)); | 1229 printf("Headers: %lu/%lu\n", (unsigned long)uw_buffer_used(&ctx->outHeaders), (unsigned long)uw_buffer_avail(&ctx->outHeaders)); |
1235 printf("Script: %lu/%lu\n", (unsigned long)buf_used(&ctx->script), (unsigned long)buf_avail(&ctx->script)); | 1230 printf("Script: %lu/%lu\n", (unsigned long)uw_buffer_used(&ctx->script), (unsigned long)uw_buffer_avail(&ctx->script)); |
1236 printf("Page: %lu/%lu\n", (unsigned long)buf_used(&ctx->page), (unsigned long)buf_avail(&ctx->page)); | 1231 printf("Page: %lu/%lu\n", (unsigned long)uw_buffer_used(&ctx->page), (unsigned long)uw_buffer_avail(&ctx->page)); |
1237 printf("Heap: %lu/%lu\n", (unsigned long)buf_used(&ctx->heap), (unsigned long)buf_avail(&ctx->heap)); | 1232 printf("Heap: %lu/%lu\n", (unsigned long)uw_buffer_used(&ctx->heap), (unsigned long)uw_buffer_avail(&ctx->heap)); |
1238 } | 1233 } |
1239 | 1234 |
1240 int uw_send(uw_context ctx, int sock) { | 1235 int uw_send(uw_context ctx, int sock) { |
1241 int n = uw_really_send(sock, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); | 1236 int n = uw_really_send(sock, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); |
1242 | 1237 |
1278 | 1273 |
1279 return output(data, ctx->page.start, ctx->page.front - ctx->page.start); | 1274 return output(data, ctx->page.start, ctx->page.front - ctx->page.start); |
1280 } | 1275 } |
1281 | 1276 |
1282 static void uw_check_headers(uw_context ctx, size_t extra) { | 1277 static void uw_check_headers(uw_context ctx, size_t extra) { |
1283 ctx_buf_check(ctx, "headers", &ctx->outHeaders, extra); | 1278 ctx_uw_buffer_check(ctx, "headers", &ctx->outHeaders, extra); |
1284 } | 1279 } |
1285 | 1280 |
1286 void uw_write_header(uw_context ctx, uw_Basis_string s) { | 1281 void uw_write_header(uw_context ctx, uw_Basis_string s) { |
1287 int len = strlen(s); | 1282 int len = strlen(s); |
1288 | 1283 |
1290 strcpy(ctx->outHeaders.front, s); | 1285 strcpy(ctx->outHeaders.front, s); |
1291 ctx->outHeaders.front += len; | 1286 ctx->outHeaders.front += len; |
1292 } | 1287 } |
1293 | 1288 |
1294 void uw_clear_headers(uw_context ctx) { | 1289 void uw_clear_headers(uw_context ctx) { |
1295 buf_reset(&ctx->outHeaders); | 1290 uw_buffer_reset(&ctx->outHeaders); |
1296 } | 1291 } |
1297 | 1292 |
1298 static void uw_check_script(uw_context ctx, size_t extra) { | 1293 static void uw_check_script(uw_context ctx, size_t extra) { |
1299 ctx_buf_check(ctx, "script", &ctx->script, extra); | 1294 ctx_uw_buffer_check(ctx, "script", &ctx->script, extra); |
1300 } | 1295 } |
1301 | 1296 |
1302 void uw_write_script(uw_context ctx, uw_Basis_string s) { | 1297 void uw_write_script(uw_context ctx, uw_Basis_string s) { |
1303 int len = strlen(s); | 1298 int len = strlen(s); |
1304 | 1299 |
1511 | 1506 |
1512 return uw_unit_v; | 1507 return uw_unit_v; |
1513 } | 1508 } |
1514 | 1509 |
1515 static void uw_check(uw_context ctx, size_t extra) { | 1510 static void uw_check(uw_context ctx, size_t extra) { |
1516 ctx_buf_check(ctx, "page", &ctx->page, extra); | 1511 ctx_uw_buffer_check(ctx, "page", &ctx->page, extra); |
1517 } | 1512 } |
1518 | 1513 |
1519 static void uw_writec_unsafe(uw_context ctx, char c) { | 1514 static void uw_writec_unsafe(uw_context ctx, char c) { |
1520 *(ctx->page.front)++ = c; | 1515 *(ctx->page.front)++ = c; |
1521 } | 1516 } |
3001 if (ctx->used_deltas >= ctx->n_deltas) { | 2996 if (ctx->used_deltas >= ctx->n_deltas) { |
3002 if (ctx->n_deltas + 1 > uw_deltas_max) | 2997 if (ctx->n_deltas + 1 > uw_deltas_max) |
3003 uw_error(ctx, FATAL, "Exceeded limit on number of deltas"); | 2998 uw_error(ctx, FATAL, "Exceeded limit on number of deltas"); |
3004 | 2999 |
3005 ctx->deltas = realloc(ctx->deltas, sizeof(delta) * ++ctx->n_deltas); | 3000 ctx->deltas = realloc(ctx->deltas, sizeof(delta) * ++ctx->n_deltas); |
3006 buf_init(uw_messages_max, &ctx->deltas[ctx->n_deltas-1].msgs, 0); | 3001 uw_buffer_init(uw_messages_max, &ctx->deltas[ctx->n_deltas-1].msgs, 0); |
3007 } | 3002 } |
3008 | 3003 |
3009 d = &ctx->deltas[ctx->used_deltas++]; | 3004 d = &ctx->deltas[ctx->used_deltas++]; |
3010 d->client = client; | 3005 d->client = client; |
3011 buf_reset(&d->msgs); | 3006 uw_buffer_reset(&d->msgs); |
3012 return d; | 3007 return d; |
3013 } | 3008 } |
3014 | 3009 |
3015 uw_Basis_channel uw_Basis_new_channel(uw_context ctx, uw_unit u) { | 3010 uw_Basis_channel uw_Basis_new_channel(uw_context ctx, uw_unit u) { |
3016 if (ctx->client == NULL) | 3011 if (ctx->client == NULL) |
3027 | 3022 |
3028 len = strlen(msg); | 3023 len = strlen(msg); |
3029 | 3024 |
3030 sprintf(pre, "%u\n%n", chn.chn, &preLen); | 3025 sprintf(pre, "%u\n%n", chn.chn, &preLen); |
3031 | 3026 |
3032 ctx_buf_append(ctx, "messages", &d->msgs, pre, preLen); | 3027 ctx_uw_buffer_append(ctx, "messages", &d->msgs, pre, preLen); |
3033 ctx_buf_append(ctx, "messages", &d->msgs, msg, len); | 3028 ctx_uw_buffer_append(ctx, "messages", &d->msgs, msg, len); |
3034 ctx_buf_append(ctx, "messages", &d->msgs, "\n", 1); | 3029 ctx_uw_buffer_append(ctx, "messages", &d->msgs, "\n", 1); |
3035 | 3030 |
3036 return uw_unit_v; | 3031 return uw_unit_v; |
3037 } | 3032 } |
3038 | 3033 |
3039 int uw_rollback(uw_context ctx, int will_retry) { | 3034 int uw_rollback(uw_context ctx, int will_retry) { |
3110 | 3105 |
3111 // Splice script data into appropriate part of page | 3106 // Splice script data into appropriate part of page |
3112 if (ctx->returning_indirectly || ctx->script_header[0] == 0) { | 3107 if (ctx->returning_indirectly || ctx->script_header[0] == 0) { |
3113 char *start = strstr(ctx->page.start, "<sc>"); | 3108 char *start = strstr(ctx->page.start, "<sc>"); |
3114 if (start) { | 3109 if (start) { |
3115 memmove(start, start + 4, buf_used(&ctx->page) - (start - ctx->page.start) - 4); | 3110 memmove(start, start + 4, uw_buffer_used(&ctx->page) - (start - ctx->page.start) - 4); |
3116 ctx->page.front -= 4; | 3111 ctx->page.front -= 4; |
3117 } | 3112 } |
3118 } else if (buf_used(&ctx->script) == 0) { | 3113 } else if (uw_buffer_used(&ctx->script) == 0) { |
3119 size_t len = strlen(ctx->script_header); | 3114 size_t len = strlen(ctx->script_header); |
3120 char *start = strstr(ctx->page.start, "<sc>"); | 3115 char *start = strstr(ctx->page.start, "<sc>"); |
3121 if (start) { | 3116 if (start) { |
3122 ctx_buf_check(ctx, "page", &ctx->page, buf_used(&ctx->page) - 4 + len); | 3117 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->page) - 4 + len); |
3123 start = strstr(ctx->page.start, "<sc>"); | 3118 start = strstr(ctx->page.start, "<sc>"); |
3124 memmove(start + len, start + 4, buf_used(&ctx->page) - (start - ctx->page.start) - 3); | 3119 memmove(start + len, start + 4, uw_buffer_used(&ctx->page) - (start - ctx->page.start) - 3); |
3125 ctx->page.front += len - 4; | 3120 ctx->page.front += len - 4; |
3126 memcpy(start, ctx->script_header, len); | 3121 memcpy(start, ctx->script_header, len); |
3127 } | 3122 } |
3128 } else { | 3123 } else { |
3129 size_t lenH = strlen(ctx->script_header), len = buf_used(&ctx->script); | 3124 size_t lenH = strlen(ctx->script_header), len = uw_buffer_used(&ctx->script); |
3130 size_t lenP = lenH + 40 + len; | 3125 size_t lenP = lenH + 40 + len; |
3131 char *start = strstr(ctx->page.start, "<sc>"); | 3126 char *start = strstr(ctx->page.start, "<sc>"); |
3132 if (start) { | 3127 if (start) { |
3133 ctx_buf_check(ctx, "page", &ctx->page, buf_used(&ctx->page) - 4 + lenP); | 3128 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->page) - 4 + lenP); |
3134 start = strstr(ctx->page.start, "<sc>"); | 3129 start = strstr(ctx->page.start, "<sc>"); |
3135 memmove(start + lenP, start + 4, buf_used(&ctx->page) - (start - ctx->page.start) - 3); | 3130 memmove(start + lenP, start + 4, uw_buffer_used(&ctx->page) - (start - ctx->page.start) - 3); |
3136 ctx->page.front += lenP - 4; | 3131 ctx->page.front += lenP - 4; |
3137 memcpy(start, ctx->script_header, lenH); | 3132 memcpy(start, ctx->script_header, lenH); |
3138 memcpy(start + lenH, "<script type=\"text/javascript\">", 31); | 3133 memcpy(start + lenH, "<script type=\"text/javascript\">", 31); |
3139 memcpy(start + lenH + 31, ctx->script.start, len); | 3134 memcpy(start + lenH + 31, ctx->script.start, len); |
3140 memcpy(start + lenH + 31 + len, "</script>", 9); | 3135 memcpy(start + lenH + 31 + len, "</script>", 9); |
3336 __attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, uw_Basis_string mimeType) { | 3331 __attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, uw_Basis_string mimeType) { |
3337 cleanup *cl; | 3332 cleanup *cl; |
3338 int len; | 3333 int len; |
3339 | 3334 |
3340 ctx->returning_indirectly = 1; | 3335 ctx->returning_indirectly = 1; |
3341 buf_reset(&ctx->outHeaders); | 3336 uw_buffer_reset(&ctx->outHeaders); |
3342 buf_reset(&ctx->page); | 3337 uw_buffer_reset(&ctx->page); |
3343 | 3338 |
3344 uw_write_header(ctx, on_success); | 3339 uw_write_header(ctx, on_success); |
3345 uw_write_header(ctx, "Content-Type: "); | 3340 uw_write_header(ctx, "Content-Type: "); |
3346 uw_write_header(ctx, mimeType); | 3341 uw_write_header(ctx, mimeType); |
3347 uw_write_header(ctx, "\r\nContent-Length: "); | 3342 uw_write_header(ctx, "\r\nContent-Length: "); |
3348 ctx_buf_check(ctx, "headers", &ctx->outHeaders, INTS_MAX); | 3343 ctx_uw_buffer_check(ctx, "headers", &ctx->outHeaders, INTS_MAX); |
3349 sprintf(ctx->outHeaders.front, "%lu%n", (unsigned long)b.size, &len); | 3344 sprintf(ctx->outHeaders.front, "%lu%n", (unsigned long)b.size, &len); |
3350 ctx->outHeaders.front += len; | 3345 ctx->outHeaders.front += len; |
3351 uw_write_header(ctx, "\r\n"); | 3346 uw_write_header(ctx, "\r\n"); |
3352 | 3347 |
3353 ctx_buf_append(ctx, "page", &ctx->page, b.data, b.size); | 3348 ctx_uw_buffer_append(ctx, "page", &ctx->page, b.data, b.size); |
3354 | 3349 |
3355 for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl) | 3350 for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl) |
3356 cl->func(cl->arg); | 3351 cl->func(cl->arg); |
3357 | 3352 |
3358 ctx->cleanup_front = ctx->cleanup; | 3353 ctx->cleanup_front = ctx->cleanup; |
3363 __attribute__((noreturn)) void uw_redirect(uw_context ctx, uw_Basis_string url) { | 3358 __attribute__((noreturn)) void uw_redirect(uw_context ctx, uw_Basis_string url) { |
3364 cleanup *cl; | 3359 cleanup *cl; |
3365 char *s; | 3360 char *s; |
3366 | 3361 |
3367 ctx->returning_indirectly = 1; | 3362 ctx->returning_indirectly = 1; |
3368 buf_reset(&ctx->page); | 3363 uw_buffer_reset(&ctx->page); |
3369 ctx_buf_check(ctx, "page", &ctx->page, buf_used(&ctx->outHeaders)+1); | 3364 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->outHeaders)+1); |
3370 memcpy(ctx->page.start, ctx->outHeaders.start, buf_used(&ctx->outHeaders)); | 3365 memcpy(ctx->page.start, ctx->outHeaders.start, uw_buffer_used(&ctx->outHeaders)); |
3371 ctx->page.start[buf_used(&ctx->outHeaders)] = 0; | 3366 ctx->page.start[uw_buffer_used(&ctx->outHeaders)] = 0; |
3372 buf_reset(&ctx->outHeaders); | 3367 uw_buffer_reset(&ctx->outHeaders); |
3373 | 3368 |
3374 uw_write_header(ctx, on_redirect); | 3369 uw_write_header(ctx, on_redirect); |
3375 | 3370 |
3376 s = strchr(ctx->page.start, '\n'); | 3371 s = strchr(ctx->page.start, '\n'); |
3377 if (s) { | 3372 if (s) { |
3457 uw_Basis_time uw_Basis_now(uw_context ctx) { | 3452 uw_Basis_time uw_Basis_now(uw_context ctx) { |
3458 uw_Basis_time r = { time(NULL) }; | 3453 uw_Basis_time r = { time(NULL) }; |
3459 return r; | 3454 return r; |
3460 } | 3455 } |
3461 | 3456 |
3462 uw_Basis_time uw_Basis_minusSeconds(uw_context ctx, uw_Basis_time tm, uw_Basis_int n) { | 3457 uw_Basis_time uw_Basis_addSeconds(uw_context ctx, uw_Basis_time tm, uw_Basis_int n) { |
3463 tm.seconds -= n; | 3458 tm.seconds += n; |
3464 return tm; | 3459 return tm; |
3465 } | 3460 } |
3466 | 3461 |
3467 void *uw_get_global(uw_context ctx, char *name) { | 3462 void *uw_get_global(uw_context ctx, char *name) { |
3468 int i; | 3463 int i; |