static void do_file_response ( struct HTTPRequest *req, /* HTTP request */ FILE *out, /* output fd */ char *docroot /* docroot path */ ) { struct FileInfo *info = NULL; dbg( "req=%p, out=%p, docroot=%p\n", req, out, docroot ); info = get_fileinfo( docroot, req->path ); if( 0 == info->ok ) { free_fileinfo( info ); not_found( req, out ); return ; } output_common_header_fields( req, out, "200 OK" ); fprintf( out, "Content-Length: %ld\r\n", info->size ); fprintf( out, "Content-Type: %s\r\n", guess_content_type( info ) ); fprintf( out, "\r\n" ); outputBodyFields( info, req, out ); fflush( out ); free_fileinfo( info ); }
static void do_file_response(struct HTTPRequest *req, FILE *out, char *docroot) { struct FileInfo *info; info = get_fileinfo(docroot, req->path); if (!info->ok) { free_fileinfo(info); not_found(req, out); return; } output_common_header_fields(req, out, "200 OK"); fprintf(out, "Content-Length: %ld\r\n", info->size); fprintf(out, "Content-Type: %s\r\n", guess_content_type(info)); fprintf(out, "\r\n"); if (strcmp(req->method, "HEAD") != 0) { int fd; char buf[BLOCK_BUF_SIZE]; ssize_t n; fd = open(info->path, O_RDONLY); if (fd < 0) { log_exit("failed to open %s: %s", info->path, strerror(errno)); } while (1) { n = read(fd, buf, BLOCK_BUF_SIZE); if (n < 0) { log_exit("failed to read %s: %s", info->path, strerror(errno)); } if (n == 0) { break; } if (fwrite(buf, n, 1, out) < 1) { log_exit("failed to write to socket: %s", strerror(errno)); } } close(fd); } fflush(out); free_fileinfo(info); }
static int list_files(FILE *out, const char **files, int n_files, int flags) { struct fileinfo *fi; int i; int *dirs = NULL; size_t total_blocks = 0; int n_print = 0; int ret = 0; if(n_files == 0) return 0; if(n_files > 1) flags |= LS_SHOW_DIRNAME; fi = calloc(n_files, sizeof(*fi)); if (fi == NULL) { syslog(LOG_ERR, "out of memory"); return -1; } for(i = 0; i < n_files; i++) { if(lstat_file(files[i], &fi[i].st) < 0) { sec_fprintf2(out, "%s: %s\r\n", files[i], strerror(errno)); fi[i].filename = NULL; } else { int include_in_list = 1; total_blocks += block_convert(fi[i].st.st_blocks); if(S_ISDIR(fi[i].st.st_mode)) { if(dirs == NULL) dirs = calloc(n_files, sizeof(*dirs)); if(dirs == NULL) { syslog(LOG_ERR, "%s: %m", files[i]); ret = -1; goto out; } dirs[i] = 1; if((flags & LS_DIRS) == 0) include_in_list = 0; } if(include_in_list) { ret = make_fileinfo(out, files[i], &fi[i], flags); if (ret) goto out; n_print++; } } } switch(SORT_MODE(flags)) { case LS_SORT_NAME: qsort(fi, n_files, sizeof(*fi), (int (*)(const void*, const void*))compare_filename); break; case LS_SORT_MTIME: qsort(fi, n_files, sizeof(*fi), (int (*)(const void*, const void*))compare_mtime); break; case LS_SORT_SIZE: qsort(fi, n_files, sizeof(*fi), (int (*)(const void*, const void*))compare_size); break; } if(DISP_MODE(flags) == LS_DISP_LONG) { int max_inode = 0; int max_bsize = 0; int max_n_link = 0; int max_user = 0; int max_group = 0; int max_size = 0; int max_major = 0; int max_minor = 0; int max_date = 0; for(i = 0; i < n_files; i++) { if(fi[i].filename == NULL) continue; if(fi[i].inode > max_inode) max_inode = fi[i].inode; if(fi[i].bsize > max_bsize) max_bsize = fi[i].bsize; if(fi[i].n_link > max_n_link) max_n_link = fi[i].n_link; if(strlen(fi[i].user) > max_user) max_user = strlen(fi[i].user); if(strlen(fi[i].group) > max_group) max_group = strlen(fi[i].group); if(fi[i].major != NULL && strlen(fi[i].major) > max_major) max_major = strlen(fi[i].major); if(fi[i].minor != NULL && strlen(fi[i].minor) > max_minor) max_minor = strlen(fi[i].minor); if(fi[i].size != NULL && strlen(fi[i].size) > max_size) max_size = strlen(fi[i].size); if(strlen(fi[i].date) > max_date) max_date = strlen(fi[i].date); } if(max_size < max_major + max_minor + 2) max_size = max_major + max_minor + 2; else if(max_size - max_minor - 2 > max_major) max_major = max_size - max_minor - 2; max_inode = find_log10(max_inode); max_bsize = find_log10(max_bsize); max_n_link = find_log10(max_n_link); if(n_print > 0) sec_fprintf2(out, "total %lu\r\n", (unsigned long)total_blocks); if(flags & LS_SORT_REVERSE) for(i = n_files - 1; i >= 0; i--) print_file(out, flags, &fi[i], max_inode, max_bsize, max_n_link, max_user, max_group, max_size, max_major, max_minor, max_date); else for(i = 0; i < n_files; i++) print_file(out, flags, &fi[i], max_inode, max_bsize, max_n_link, max_user, max_group, max_size, max_major, max_minor, max_date); } else if(DISP_MODE(flags) == LS_DISP_COLUMN || DISP_MODE(flags) == LS_DISP_CROSS) { int max_len = 0; int size_len = 0; int num_files = n_files; int columns; int j; for(i = 0; i < n_files; i++) { if(fi[i].filename == NULL) { num_files--; continue; } if(strlen(fi[i].filename) > max_len) max_len = strlen(fi[i].filename); if(find_log10(fi[i].bsize) > size_len) size_len = find_log10(fi[i].bsize); } if(num_files == 0) goto next; if(flags & LS_SIZE) { columns = 80 / (size_len + 1 + max_len + 1); max_len = 80 / columns - size_len - 1; } else { columns = 80 / (max_len + 1); /* get space between columns */ max_len = 80 / columns; } if(flags & LS_SIZE) sec_fprintf2(out, "total %lu\r\n", (unsigned long)total_blocks); if(DISP_MODE(flags) == LS_DISP_CROSS) { for(i = 0, j = 0; i < n_files; i++) { if(fi[i].filename == NULL) continue; if(flags & LS_SIZE) sec_fprintf2(out, "%*u %-*s", size_len, fi[i].bsize, max_len, fi[i].filename); else sec_fprintf2(out, "%-*s", max_len, fi[i].filename); j++; if(j == columns) { sec_fprintf2(out, "\r\n"); j = 0; } } if(j > 0) sec_fprintf2(out, "\r\n"); } else { int skip = (num_files + columns - 1) / columns; j = 0; for(i = 0; i < skip; i++) { for(j = i; j < n_files;) { while(j < n_files && fi[j].filename == NULL) j++; if(flags & LS_SIZE) sec_fprintf2(out, "%*u %-*s", size_len, fi[j].bsize, max_len, fi[j].filename); else sec_fprintf2(out, "%-*s", max_len, fi[j].filename); j += skip; } sec_fprintf2(out, "\r\n"); } } } else { for(i = 0; i < n_files; i++) { if(fi[i].filename == NULL) continue; sec_fprintf2(out, "%s\r\n", fi[i].filename); } } next: if(((flags & LS_DIRS) == 0 || (flags & LS_RECURSIVE)) && dirs != NULL) { for(i = 0; i < n_files; i++) { if(dirs[i]) { const char *p = strrchr(files[i], '/'); if(p == NULL) p = files[i]; else p++; if(!(flags & LS_DIR_FLAG) || !IS_DOT_DOTDOT(p)) { if((flags & LS_SHOW_DIRNAME)) { if ((flags & LS_EXTRA_BLANK)) sec_fprintf2(out, "\r\n"); sec_fprintf2(out, "%s:\r\n", files[i]); } list_dir(out, files[i], flags | LS_DIRS | LS_EXTRA_BLANK); } } } } out: for(i = 0; i < n_files; i++) free_fileinfo(&fi[i]); free(fi); if(dirs != NULL) free(dirs); return ret; }