int rinoo_dns_name_get(t_buffer_iterator *iterator, t_buffer *name) { char *label; unsigned char size; unsigned short tmp; t_buffer_iterator tmp_iter; while (!buffer_iterator_end(iterator)) { size = *(unsigned char *)(buffer_iterator_ptr(iterator)); if (size == 0) { /* Move iterator position */ buffer_iterator_getchar(iterator, NULL); buffer_addnull(name); return 0; } else if (DNS_QUERY_NAME_IS_COMPRESSED(size)) { if (buffer_iterator_gethushort(iterator, &tmp) != 0) { return -1; } buffer_iterator_set(&tmp_iter, iterator->buffer); if (buffer_iterator_position_set(&tmp_iter, DNS_QUERY_NAME_GET_OFFSET(tmp)) != 0) { return -1; } if (rinoo_dns_name_get(&tmp_iter, name) != 0) { return -1; } /* Only end of domain can be compressed */ return 0; } else { buffer_iterator_getchar(iterator, NULL); label = buffer_iterator_ptr(iterator); if (buffer_iterator_position_inc(iterator, size) != 0) { return -1; } if (buffer_size(name) > 0) { buffer_addstr(name, "."); } buffer_add(name, label, size); } } buffer_addnull(name); return 0; }
/** * Calls a HTTP route. * * @param http Pointer to a HTTP context * @param route Pointer to the route to call */ static void rinoohttp_easy_route_call(t_rinoohttp *http, t_rinoohttp_route *route) { t_buffer body; t_buffer *uri; http->response.code = route->code; switch (route->type) { case RINOO_HTTP_ROUTE_STATIC: strtobuffer(&body, route->content); rinoohttp_response_send(http, &body); break; case RINOO_HTTP_ROUTE_FUNC: if (route->func(http, route) != 0) { http->response.code = 500; strtobuffer(&body, RINOO_HTTP_ERROR_500); rinoohttp_response_send(http, &body); } break; case RINOO_HTTP_ROUTE_FILE: if (rinoohttp_send_file(http, route->file) != 0) { http->response.code = 404; strtobuffer(&body, RINOO_HTTP_ERROR_404); rinoohttp_response_send(http, &body); } break; case RINOO_HTTP_ROUTE_DIR: uri = buffer_create(NULL); buffer_addstr(uri, route->path); buffer_addstr(uri, "/"); buffer_add(uri, buffer_ptr(&http->request.uri), buffer_size(&http->request.uri)); buffer_addnull(uri); if (rinoohttp_send_file(http, buffer_ptr(uri)) != 0) { http->response.code = 404; strtobuffer(&body, RINOO_HTTP_ERROR_404); rinoohttp_response_send(http, &body); } buffer_destroy(uri); break; case RINOO_HTTP_ROUTE_REDIRECT: rinoohttp_header_set(&http->response.headers, "Location", route->location); rinoohttp_response_send(http, NULL); break; } }
int rinoo_fs_browse(const char *path, t_fs_entry **last_entry) { DIR *dirfd; t_fs_entry *curentry; struct dirent *result; t_fs_directory *directory; if (last_entry == NULL) { return -1; } curentry = *last_entry; if (curentry == NULL) { curentry = rinoo_fs_entry(path); if (curentry == NULL) { return -1; } dirfd = opendir(path); if (dirfd == NULL) { goto browse_error; } if (rinoo_fs_stack_push(curentry, dirfd, path) != 0) { closedir(dirfd); goto browse_error; } } directory = rinoo_fs_stack_head(curentry); if (directory == NULL) { goto browse_error; } for (result = NULL; result == NULL && directory != NULL;) { if (readdir_r(directory->fd, curentry->entry, &result) != 0) { goto browse_error; } if (result == NULL) { closedir(directory->fd); rinoo_fs_stack_pop(curentry); directory = rinoo_fs_stack_head(curentry); result = NULL; continue; } if (curentry->entry->d_name[0] == '.' && (curentry->entry->d_name[1] == 0 || curentry->entry->d_name[1] == '.')) { result = NULL; continue; } buffer_erase(curentry->path, 0); buffer_addstr(curentry->path, directory->path); if (((char *) buffer_ptr(curentry->path))[curentry->path->size - 1] != '/') { buffer_addstr(curentry->path, "/"); } buffer_addstr(curentry->path, curentry->entry->d_name); buffer_addnull(curentry->path); if (stat(buffer_ptr(curentry->path), &curentry->stat) != 0) { /* Try next entry */ result = NULL; continue; } if (S_ISDIR(curentry->stat.st_mode)) { dirfd = opendir(buffer_ptr(curentry->path)); if (dirfd == NULL) { /* Try next entry */ result = NULL; continue; } if (rinoo_fs_stack_push(curentry, dirfd, buffer_ptr(curentry->path)) != 0) { goto browse_error; } } } if (result == NULL && directory == NULL) { /* End of browsing */ rinoo_fs_entry_destroy(curentry); *last_entry = NULL; return 0; } *last_entry = curentry; return 0; browse_error: if (curentry != NULL) { rinoo_fs_entry_destroy(curentry); } return -1; }