FileRecord *Dir_find_file(bstring path, bstring default_type) { FileRecord *fr = calloc(sizeof(FileRecord), 1); const char *p = bdata(path); check_mem(fr); // We set the number of users here. If we cache it, we can add one later fr->users = 1; int rc = stat(p, &fr->sb); check(rc == 0, "File stat failed: %s", bdata(path)); if(S_ISDIR(fr->sb.st_mode)) { fr->full_path = path; fr->is_dir = 1; return fr; } fr->fd = open(p, O_RDONLY); check(fr->fd >= 0, "Failed to open file but stat worked: %s", bdata(path)); fr->loaded = time(NULL); fr->last_mod = bStrfTime(RFC_822_TIME, gmtime(&fr->sb.st_mtime)); check(fr->last_mod, "Failed to format last modified time."); // TODO: get this from a configuration fr->content_type = MIME_match_ext(path, default_type); check(fr->content_type, "Should always get a content type back."); // we own this now, not the caller fr->full_path = path; time_t now = time(NULL); fr->date = bStrfTime(RFC_822_TIME, gmtime(&now)); fr->etag = bformat("%x-%x", fr->sb.st_mtime, fr->sb.st_size); fr->header = bformat(RESPONSE_FORMAT, bdata(fr->date), bdata(fr->content_type), fr->sb.st_size, bdata(fr->last_mod), bdata(fr->etag)); check(fr->header != NULL, "Failed to create response header."); return fr; error: FileRecord_destroy(fr); return NULL; }
void fprintf_with_timestamp(FILE *log_file, const char *format, ...) { va_list args; time_t now = time(NULL); bstring time_stamp = bStrfTime("%a, %d %b %Y %H:%M:%S GMT", gmtime(&now)); va_start(args, format); fprintf(log_file, "%s ", time_stamp->data); vfprintf(log_file, format, args); bdestroy(time_stamp); va_end(args); }