Improve response headers composer
[MonkeyD.git] / src / file.c
blobfed5a676bef9bb4d030e802e850c7f683717561e
1 /*-*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /* Monkey HTTP Daemon
4 * ------------------
5 * Copyright (C) 2001-2010, Eduardo Silva P. <edsiper@gmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 #include <stdio.h>
26 #include <stdlib.h>
28 #include "monkey.h"
29 #include "file.h"
30 #include "user.h"
31 #include "memory.h"
33 struct file_info *mk_file_get_info(char *path)
35 struct file_info *f_info;
36 struct stat f, target;
38 /* Stat right resource */
39 if (lstat(path, &f) == -1) {
40 return NULL;
43 f_info = mk_mem_malloc(sizeof(struct file_info));
44 f_info->is_link = MK_FILE_FALSE;
45 f_info->is_directory = MK_FILE_FALSE;
46 f_info->exec_access = MK_FILE_FALSE;
47 f_info->read_access = MK_FILE_FALSE;
49 if (S_ISLNK(f.st_mode)) {
50 f_info->is_link = MK_FILE_TRUE;
51 if (stat(path, &target) == -1) {
52 return NULL;
55 else {
56 target = f;
59 f_info->size = target.st_size;
60 f_info->last_modification = target.st_mtime;
62 if (S_ISDIR(target.st_mode)) {
63 f_info->is_directory = MK_FILE_TRUE;
66 /* Checking read access */
67 if ((target.st_mode & S_IRUSR && target.st_uid == euid) ||
68 (target.st_mode & S_IRGRP && target.st_gid == egid) ||
69 (target.st_mode & S_IROTH)) {
70 f_info->read_access = MK_FILE_TRUE;
73 /* Checking execution access */
74 if ((target.st_mode & S_IXUSR && target.st_uid == euid) ||
75 (target.st_mode & S_IXGRP && target.st_gid == egid) ||
76 (target.st_mode & S_IXOTH)) {
77 f_info->exec_access = MK_FILE_TRUE;
80 return f_info;
83 /* Read file content to a memory buffer,
84 * Use this function just for really SMALL files
86 char *mk_file_to_buffer(char *path)
88 FILE *fp;
89 char *buffer;
90 long bytes;
91 struct file_info *finfo;
93 if (!(finfo = mk_file_get_info(path))) {
94 return NULL;
97 if (!(fp = fopen(path, "r"))) {
98 return NULL;
101 buffer = calloc(finfo->size + 1, sizeof(char));
102 if (!buffer) {
103 fclose(fp);
104 return NULL;
107 bytes = fread(buffer, finfo->size, 1, fp);
109 if (bytes < 1) {
110 mk_mem_free(buffer);
111 fclose(fp);
112 return NULL;
115 fclose(fp);
116 return (char *) buffer;