/* * File: file.c :) * * Copyright (C) 2000-2007 Jorge Arellano Cid * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. */ /* * Directory scanning is no longer streamed, but it gets sorted instead! * Directory entries on top, files next. * With new HTML layout. */ #include /* for isspace */ #include /* for errno */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "../dpip/dpip.h" #include "dpiutil.h" #include "d_size.h" /* * Debugging macros */ #define _MSG(...) #define MSG(...) printf("[file dpi]: " __VA_ARGS__) #define _MSG_RAW(...) #define MSG_RAW(...) printf(__VA_ARGS__) #define MAXNAMESIZE 30 #define HIDE_DOTFILES TRUE /* * Communication flags */ #define FILE_AUTH_OK 1 /* Authentication done */ #define FILE_READ 2 /* Waiting data */ #define FILE_WRITE 4 /* Sending data */ #define FILE_DONE 8 /* Operation done */ #define FILE_ERR 16 /* Operation error */ typedef enum { st_start = 10, st_dpip, st_http, st_content, st_done, st_err } FileState; typedef struct { char *full_path; const char *filename; off_t size; mode_t mode; time_t mtime; } FileInfo; typedef struct { char *dirname; Dlist *flist; /* List of files and subdirectories (for sorting) */ } DilloDir; typedef struct { Dsh *sh; char *orig_url; char *filename; int file_fd; off_t file_sz; DilloDir *d_dir; FileState state; int err_code; int flags; int old_style; } ClientInfo; /* * Forward references */ static const char *File_content_type(const char *filename); /* * Global variables */ static int DPIBYE = 0; static int OLD_STYLE = 0; /* A list for the clients we are serving */ static Dlist *Clients; /* Set of filedescriptors we're working on */ fd_set read_set, write_set; /* * Close a file descriptor, but handling EINTR */ static void File_close(int fd) { while (fd >= 0 && close(fd) < 0 && errno == EINTR) ; } /* * Detects 'Content-Type' when the server does not supply one. * It uses the magic(5) logic from file(1). Currently, it * only checks the few mime types that Dillo supports. * * 'Data' is a pointer to the first bytes of the raw data. * (this is based on a_Misc_get_content_type_from_data()) */ static const char *File_get_content_type_from_data(void *Data, size_t Size) { static const char *Types[] = { "application/octet-stream", "text/html", "text/plain", "image/gif", "image/png", "image/jpeg", }; int Type = 0; char *p = Data; size_t i, non_ascci; _MSG("File_get_content_type_from_data:: Size = %d\n", Size); /* HTML try */ for (i = 0; i < Size && dIsspace(p[i]); ++i); if ((Size - i >= 5 && !dStrnAsciiCasecmp(p+i, "= 5 && !dStrnAsciiCasecmp(p+i, "= 6 && !dStrnAsciiCasecmp(p+i, "= 14 && !dStrnAsciiCasecmp(p+i, "= 17 && !dStrnAsciiCasecmp(p+i, "