annotate dpi/file.c @ 0:6ee11bf9e3ea

Initial revision
author jcid
date Sun, 07 Oct 2007 00:36:34 +0200
parents
children d9e7b35430de
rev   line source
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
2 * File: file.c :)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
3 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
4 * Copyright (C) 2000 - 2004 Jorge Arellano Cid <jcid@dillo.org>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
5 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
6 * This program is free software; you can redistribute it and/or modify
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
7 * it under the terms of the GNU General Public License as published by
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
8 * the Free Software Foundation; either version 3 of the License, or
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
9 * (at your option) any later version.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
10 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
11
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
12 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
13 * Directory scanning is no longer streamed, but it gets sorted instead!
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
14 * Directory entries on top, files next.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
15 * With new HTML layout.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
16 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
17
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
18 #include <pthread.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
19
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
20 #include <ctype.h> /* for tolower */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
21 #include <errno.h> /* for errno */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
22 #include <stdio.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
23 #include <stdlib.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
24 #include <string.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
25 #include <unistd.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
26 #include <sys/socket.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
27 #include <sys/stat.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
28 #include <sys/types.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
29 #include <sys/time.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
30 #include <sys/un.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
31 #include <dirent.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
32 #include <fcntl.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
33 #include <time.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
34 #include <signal.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
35
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
36 #include "../dpip/dpip.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
37 #include "dpiutil.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
38 #include "d_size.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
39
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
40 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
41 * Debugging macros
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
42 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
43 #define _MSG(...)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
44 #define MSG(...) printf("[file dpi]: " __VA_ARGS__)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
45
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
46
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
47 #define MAXNAMESIZE 30
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
48 #define HIDE_DOTFILES TRUE
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
49
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
50 enum {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
51 FILE_OK,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
52 FILE_NOT_FOUND,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
53 FILE_NO_ACCESS
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
54 };
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
55
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
56 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
57 char *full_path;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
58 const char *filename;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
59 off_t size;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
60 mode_t mode;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
61 time_t mtime;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
62 } FileInfo;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
63
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
64 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
65 char *dirname;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
66 Dlist *flist; /* List of files and subdirectories (for sorting) */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
67 } DilloDir;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
68
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
69 typedef struct {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
70 SockHandler *sh;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
71 int status;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
72 int old_style;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
73 pthread_t thrID;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
74 int done;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
75 } ClientInfo;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
76
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
77 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
78 * Forward references
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
79 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
80 static const char *File_content_type(const char *filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
81 static int File_get_file(ClientInfo *Client,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
82 const char *filename,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
83 struct stat *sb,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
84 const char *orig_url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
85 static int File_get_dir(ClientInfo *Client,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
86 const char *DirName,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
87 const char *orig_url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
88
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
89 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
90 * Global variables
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
91 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
92 static volatile int DPIBYE = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
93 static volatile int ThreadRunning = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
94 static int OLD_STYLE = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
95 /* A list for the clients we are serving */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
96 static Dlist *Clients;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
97 /* a mutex for operations on clients */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
98 static pthread_mutex_t ClMut;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
99
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
100 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
101 * Close a file descriptor, but handling EINTR
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
102 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
103 static void File_close(int fd)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
104 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
105 while (close(fd) < 0 && errno == EINTR)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
106 ;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
107 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
108
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
109 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
110 * Detects 'Content-Type' when the server does not supply one.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
111 * It uses the magic(5) logic from file(1). Currently, it
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
112 * only checks the few mime types that Dillo supports.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
113 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
114 * 'Data' is a pointer to the first bytes of the raw data.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
115 * (this is based on a_Misc_get_content_type_from_data())
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
116 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
117 static const char *File_get_content_type_from_data(void *Data, size_t Size)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
118 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
119 static const char *Types[] = {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
120 "application/octet-stream",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
121 "text/html", "text/plain",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
122 "image/gif", "image/png", "image/jpeg",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
123 };
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
124 int Type = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
125 char *p = Data;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
126 size_t i, non_ascci;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
127
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
128 _MSG("File_get_content_type_from_data:: Size = %d\n", Size);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
129
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
130 /* HTML try */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
131 for (i = 0; i < Size && isspace(p[i]); ++i);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
132 if ((Size - i >= 5 && !dStrncasecmp(p+i, "<html", 5)) ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
133 (Size - i >= 5 && !dStrncasecmp(p+i, "<head", 5)) ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
134 (Size - i >= 6 && !dStrncasecmp(p+i, "<title", 6)) ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
135 (Size - i >= 14 && !dStrncasecmp(p+i, "<!doctype html", 14)) ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
136 /* this line is workaround for FTP through the Squid proxy */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
137 (Size - i >= 17 && !dStrncasecmp(p+i, "<!-- HTML listing", 17))) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
138
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
139 Type = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
140
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
141 /* Images */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
142 } else if (Size >= 4 && !dStrncasecmp(p, "GIF8", 4)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
143 Type = 3;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
144 } else if (Size >= 4 && !dStrncasecmp(p, "\x89PNG", 4)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
145 Type = 4;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
146 } else if (Size >= 2 && !dStrncasecmp(p, "\xff\xd8", 2)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
147 /* JPEG has the first 2 bytes set to 0xffd8 in BigEndian - looking
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
148 * at the character representation should be machine independent. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
149 Type = 5;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
150
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
151 /* Text */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
152 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
153 /* We'll assume "text/plain" if the set of chars above 127 is <= 10
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
154 * in a 256-bytes sample. Better heuristics are welcomed! :-) */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
155 non_ascci = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
156 Size = MIN (Size, 256);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
157 for (i = 0; i < Size; i++)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
158 if ((uchar_t) p[i] > 127)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
159 ++non_ascci;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
160 if (Size == 256) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
161 Type = (non_ascci > 10) ? 0 : 2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
162 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
163 Type = (non_ascci > 0) ? 0 : 2;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
164 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
165 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
166
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
167 return (Types[Type]);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
168 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
169
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
170 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
171 * Compare two FileInfo pointers
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
172 * This function is used for sorting directories
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
173 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
174 static int File_comp(const FileInfo *f1, const FileInfo *f2)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
175 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
176 if (S_ISDIR(f1->mode)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
177 if (S_ISDIR(f2->mode)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
178 return strcmp(f1->filename, f2->filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
179 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
180 return -1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
181 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
182 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
183 if (S_ISDIR(f2->mode)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
184 return 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
185 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
186 return strcmp(f1->filename, f2->filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
187 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
188 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
189 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
190
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
191 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
192 * Allocate a DilloDir structure, set safe values in it and sort the entries.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
193 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
194 static DilloDir *File_dillodir_new(char *dirname)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
195 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
196 struct stat sb;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
197 struct dirent *de;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
198 DIR *dir;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
199 DilloDir *Ddir;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
200 FileInfo *finfo;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
201 char *fname;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
202 int dirname_len;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
203
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
204 if (!(dir = opendir(dirname)))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
205 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
206
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
207 Ddir = dNew(DilloDir, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
208 Ddir->dirname = dStrdup(dirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
209 Ddir->flist = dList_new(512);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
210
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
211 dirname_len = strlen(Ddir->dirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
212
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
213 /* Scan every name and sort them */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
214 while ((de = readdir(dir)) != 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
215 if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
216 continue; /* skip "." and ".." */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
217
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
218 if (HIDE_DOTFILES) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
219 /* Don't add hidden files or backup files to the list */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
220 if (de->d_name[0] == '.' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
221 de->d_name[0] == '#' ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
222 (de->d_name[0] != '\0' &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
223 de->d_name[strlen(de->d_name) - 1] == '~'))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
224 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
225 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
226
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
227 fname = dStrconcat(Ddir->dirname, de->d_name, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
228 if (stat(fname, &sb) == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
229 dFree(fname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
230 continue; /* ignore files we can't stat */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
231 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
232
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
233 finfo = dNew(FileInfo, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
234 finfo->full_path = fname;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
235 finfo->filename = fname + dirname_len;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
236 finfo->size = sb.st_size;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
237 finfo->mode = sb.st_mode;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
238 finfo->mtime = sb.st_mtime;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
239
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
240 dList_append(Ddir->flist, finfo);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
241 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
242
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
243 closedir(dir);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
244
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
245 /* sort the entries */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
246 dList_sort(Ddir->flist, (dCompareFunc)File_comp);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
247
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
248 return Ddir;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
249 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
250
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
251 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
252 * Deallocate a DilloDir structure.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
253 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
254 static void File_dillodir_free(DilloDir *Ddir)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
255 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
256 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
257 FileInfo *finfo;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
258
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
259 for (i = 0; i < dList_length(Ddir->flist); ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
260 finfo = dList_nth_data(Ddir->flist, i);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
261 dFree(finfo->full_path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
262 dFree(finfo);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
263 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
264
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
265 dList_free(Ddir->flist);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
266 dFree(Ddir->dirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
267 dFree(Ddir);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
268 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
269
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
270 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
271 * Output the string for parent directory
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
272 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
273 static void File_print_parent_dir(ClientInfo *Client, const char *dirname)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
274 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
275 if (strcmp(dirname, "/") != 0) { /* Not the root dir */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
276 char *p, *parent, *HUparent, *Uparent;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
277
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
278 parent = dStrdup(dirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
279 /* cut trailing slash */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
280 parent[strlen(parent) - 1] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
281 /* make 'parent' have the parent dir path */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
282 if ((p = strrchr(parent, '/')))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
283 *(p + 1) = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
284
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
285 Uparent = Escape_uri_str(parent, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
286 HUparent = Escape_html_str(Uparent);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
287 sock_handler_printf(Client->sh, 0,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
288 "<a href='file:%s'>Parent directory</a>", HUparent);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
289 dFree(HUparent);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
290 dFree(Uparent);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
291 dFree(parent);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
292 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
293 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
294
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
295 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
296 * Given a timestamp, output an HTML-formatted date string.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
297 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
298 static void File_print_mtime(ClientInfo *Client, time_t mtime)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
299 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
300 char *ds = ctime(&mtime);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
301
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
302 /* Month, day and {hour or year} */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
303 if (Client->old_style) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
304 sock_handler_printf(Client->sh, 0, " %.3s %.2s", ds + 4, ds + 8);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
305 if (time(NULL) - mtime > 15811200) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
306 sock_handler_printf(Client->sh, 0, " %.4s", ds + 20);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
307 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
308 sock_handler_printf(Client->sh, 0, " %.5s", ds + 11);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
309 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
310 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
311 sock_handler_printf(Client->sh, 0,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
312 "<td>%.3s&nbsp;%.2s&nbsp;%.5s", ds + 4, ds + 8,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
313 /* (more than 6 months old) ? year : hour; */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
314 (time(NULL) - mtime > 15811200) ? ds + 20 : ds + 11);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
315 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
316 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
317
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
318 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
319 * Return a HTML-line from file info.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
320 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
321 static void File_info2html(ClientInfo *Client,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
322 FileInfo *finfo, const char *dirname, int n)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
323 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
324 int size;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
325 char *sizeunits;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
326 char namebuf[MAXNAMESIZE + 1];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
327 char *Uref, *HUref, *Hname;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
328 const char *ref, *filecont, *name = finfo->filename;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
329
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
330 if (finfo->size <= 9999) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
331 size = finfo->size;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
332 sizeunits = "bytes";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
333 } else if (finfo->size / 1024 <= 9999) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
334 size = finfo->size / 1024 + (finfo->size % 1024 >= 1024 / 2);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
335 sizeunits = "Kb";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
336 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
337 size = finfo->size / 1048576 + (finfo->size % 1048576 >= 1048576 / 2);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
338 sizeunits = "Mb";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
339 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
340
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
341 /* we could note if it's a symlink... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
342 if S_ISDIR (finfo->mode) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
343 filecont = "Directory";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
344 } else if (finfo->mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
345 filecont = "Executable";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
346 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
347 filecont = File_content_type(finfo->full_path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
348 if (!filecont || !strcmp(filecont, "application/octet-stream"))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
349 filecont = "unknown";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
350 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
351
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
352 ref = name;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
353
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
354 if (strlen(name) > MAXNAMESIZE) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
355 memcpy(namebuf, name, MAXNAMESIZE - 3);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
356 strcpy(namebuf + (MAXNAMESIZE - 3), "...");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
357 name = namebuf;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
358 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
359
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
360 /* escape problematic filenames */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
361 Uref = Escape_uri_str(ref, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
362 HUref = Escape_html_str(Uref);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
363 Hname = Escape_html_str(name);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
364
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
365 if (Client->old_style) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
366 char *dots = ".. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. ..";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
367 int ndots = MAXNAMESIZE - strlen(name);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
368 sock_handler_printf(Client->sh, 0,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
369 "%s<a href='%s'>%s</a>"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
370 " %s"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
371 " %-11s%4d %-5s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
372 S_ISDIR (finfo->mode) ? ">" : " ", HUref, Hname,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
373 dots + 50 - (ndots > 0 ? ndots : 0),
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
374 filecont, size, sizeunits);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
375
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
376 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
377 sock_handler_printf(Client->sh, 0,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
378 "<tr align=center %s><td>%s<td align=left><a href='%s'>%s</a>"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
379 "<td>%s<td>%d&nbsp;%s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
380 (n & 1) ? "bgcolor=#dcdcdc" : "",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
381 S_ISDIR (finfo->mode) ? ">" : " ", HUref, Hname,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
382 filecont, size, sizeunits);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
383 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
384 File_print_mtime(Client, finfo->mtime);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
385 sock_handler_write_str(Client->sh, 0, "\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
386
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
387 dFree(Hname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
388 dFree(HUref);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
389 dFree(Uref);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
390 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
391
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
392 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
393 * Read a local directory and translate it to html.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
394 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
395 static void File_transfer_dir(ClientInfo *Client,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
396 DilloDir *Ddir, const char *orig_url)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
397 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
398 int n;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
399 char *d_cmd, *Hdirname, *Udirname, *HUdirname;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
400
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
401 /* Send DPI header */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
402 d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", orig_url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
403 sock_handler_write_str(Client->sh, 1, d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
404 dFree(d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
405
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
406 /* Send page title */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
407 Udirname = Escape_uri_str(Ddir->dirname, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
408 HUdirname = Escape_html_str(Udirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
409 Hdirname = Escape_html_str(Ddir->dirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
410
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
411 sock_handler_printf(Client->sh, 0,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
412 "Content-Type: text/html\n\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
413 "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
414 "<HTML>\n<HEAD>\n <BASE href='file:%s'>\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
415 " <TITLE>file:%s</TITLE>\n</HEAD>\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
416 "<BODY><H1>Directory listing of %s</H1>\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
417 HUdirname, Hdirname, Hdirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
418 dFree(Hdirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
419 dFree(HUdirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
420 dFree(Udirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
421
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
422 if (Client->old_style) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
423 sock_handler_write_str(Client->sh, 0, "<pre>\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
424 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
425
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
426 /* Output the parent directory */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
427 File_print_parent_dir(Client, Ddir->dirname);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
428
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
429 /* HTML style toggle */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
430 sock_handler_write_str(Client->sh, 0,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
431 "&nbsp;&nbsp;<a href='dpi:/file/toggle'>%</a>\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
432
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
433 if (dList_length(Ddir->flist)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
434 if (Client->old_style) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
435 sock_handler_write_str(Client->sh, 0, "\n\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
436 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
437 sock_handler_write_str(Client->sh, 0,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
438 "<br><br>\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
439 "<table border=0 cellpadding=1 cellspacing=0"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
440 " bgcolor=#E0E0E0 width=100%>\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
441 "<tr align=center>\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
442 "<td>\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
443 "<td width=60%><b>Filename</b>"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
444 "<td><b>Type</b>"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
445 "<td><b>Size</b>"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
446 "<td><b>Modified&nbsp;at</b>\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
447 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
448 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
449 sock_handler_write_str(Client->sh, 0, "<br><br>Directory is empty...");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
450 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
451
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
452 /* Output entries */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
453 for (n = 0; n < dList_length(Ddir->flist); ++n) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
454 File_info2html(Client, dList_nth_data(Ddir->flist,n),Ddir->dirname,n+1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
455 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
456
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
457 if (dList_length(Ddir->flist)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
458 if (Client->old_style) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
459 sock_handler_write_str(Client->sh, 0, "</pre>\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
460 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
461 sock_handler_write_str(Client->sh, 0, "</table>\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
462 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
463 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
464
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
465 sock_handler_write_str(Client->sh, 0, "</BODY></HTML>\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
466 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
467
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
468 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
469 * Return a content type based on the extension of the filename.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
470 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
471 static const char *File_ext(const char *filename)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
472 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
473 char *e;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
474
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
475 if (!(e = strrchr(filename, '.')))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
476 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
477
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
478 e++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
479
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
480 if (!dStrcasecmp(e, "gif")) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
481 return "image/gif";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
482 } else if (!dStrcasecmp(e, "jpg") ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
483 !dStrcasecmp(e, "jpeg")) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
484 return "image/jpeg";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
485 } else if (!dStrcasecmp(e, "png")) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
486 return "image/png";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
487 } else if (!dStrcasecmp(e, "html") ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
488 !dStrcasecmp(e, "htm") ||
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
489 !dStrcasecmp(e, "shtml")) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
490 return "text/html";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
491 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
492 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
493 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
494 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
495
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
496 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
497 * Based on the extension, return the content_type for the file.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
498 * (if there's no extension, analyze the data and try to figure it out)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
499 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
500 static const char *File_content_type(const char *filename)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
501 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
502 int fd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
503 struct stat sb;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
504 const char *ct;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
505 char buf[256];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
506 ssize_t buf_size;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
507
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
508 if (!(ct = File_ext(filename))) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
509 /* everything failed, let's analyze the data... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
510 if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) != -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
511 if ((buf_size = read(fd, buf, 256)) == 256 ) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
512 ct = File_get_content_type_from_data(buf, (size_t)buf_size);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
513
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
514 } else if (stat(filename, &sb) != -1 &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
515 buf_size > 0 && buf_size == sb.st_size) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
516 ct = File_get_content_type_from_data(buf, (size_t)buf_size);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
517 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
518 File_close(fd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
519 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
520 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
521
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
522 return ct;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
523 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
524
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
525 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
526 * Try to stat the file and determine if it's readable.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
527 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
528 static void File_get(ClientInfo *Client, const char *filename,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
529 const char *orig_url)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
530 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
531 int res;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
532 struct stat sb;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
533 char *d_cmd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
534 Dstr *ds = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
535
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
536 if (stat(filename, &sb) != 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
537 /* stat failed, prepare a file-not-found error. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
538 res = FILE_NOT_FOUND;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
539 } else if (S_ISDIR(sb.st_mode)) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
540 /* set up for reading directory */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
541 res = File_get_dir(Client, filename, orig_url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
542 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
543 /* set up for reading a file */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
544 res = File_get_file(Client, filename, &sb, orig_url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
545 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
546
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
547 if (res == FILE_NOT_FOUND) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
548 ds = dStr_sized_new(128);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
549 dStr_sprintf(ds, "%s Not Found: %s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
550 S_ISDIR(sb.st_mode) ? "Directory" : "File", filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
551 } else if (res == FILE_NO_ACCESS) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
552 ds = dStr_sized_new(128);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
553 dStr_sprintf(ds, "Access denied to %s: %s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
554 S_ISDIR(sb.st_mode) ? "Directory" : "File", filename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
555 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
556 if (ds) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
557 d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s","send_status_message",ds->str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
558 sock_handler_write_str(Client->sh, 1, d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
559 dFree(d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
560 dStr_free(ds, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
561 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
562 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
563
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
564 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
565 *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
566 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
567 static int File_get_dir(ClientInfo *Client,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
568 const char *DirName, const char *orig_url)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
569 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
570 Dstr *ds_dirname;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
571 DilloDir *Ddir;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
572
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
573 /* Let's make sure this directory url has a trailing slash */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
574 ds_dirname = dStr_new(DirName);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
575 if (ds_dirname->str[ds_dirname->len - 1] != '/')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
576 dStr_append(ds_dirname, "/");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
577
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
578 /* Let's get a structure ready for transfer */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
579 Ddir = File_dillodir_new(ds_dirname->str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
580 dStr_free(ds_dirname, TRUE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
581 if (Ddir) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
582 File_transfer_dir(Client, Ddir, orig_url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
583 File_dillodir_free(Ddir);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
584 return FILE_OK;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
585 } else
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
586 return FILE_NO_ACCESS;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
587 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
588
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
589 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
590 * Send the MIME content/type and then send the file itself.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
591 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
592 static int File_get_file(ClientInfo *Client,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
593 const char *filename,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
594 struct stat *sb,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
595 const char *orig_url)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
596 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
597 #define LBUF 16*1024
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
598
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
599 const char *ct;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
600 char buf[LBUF], *d_cmd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
601 int fd, st;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
602
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
603 if ((fd = open(filename, O_RDONLY | O_NONBLOCK)) < 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
604 return FILE_NO_ACCESS;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
605
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
606 /* Content-Type info is based on filename extension. If there's no
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
607 * known extension, then we do data sniffing. If this doesn't lead
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
608 * to a conclusion, "application/octet-stream" is sent.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
609 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
610 if (!(ct = File_content_type(filename)))
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
611 ct = "application/octet-stream";
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
612
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
613 /* Send DPI command */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
614 d_cmd = a_Dpip_build_cmd("cmd=%s url=%s", "start_send_page", orig_url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
615 sock_handler_write_str(Client->sh, 1, d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
616 dFree(d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
617
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
618 /* Send HTTP stream */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
619 sock_handler_printf(Client->sh, 0,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
620 "Content-Type: %s\n"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
621 "Content-length: %ld\n\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
622 ct, sb->st_size);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
623
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
624 /* Send raw file contents */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
625 do {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
626 if ((st = read(fd, buf, LBUF)) > 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
627 if (sock_handler_write(Client->sh, 0, buf, (size_t)st) != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
628 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
629 } else if (st < 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
630 perror("[read]");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
631 if (errno == EINTR || errno == EAGAIN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
632 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
633 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
634 } while (st > 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
635
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
636 /* todo: It may be better to send an error report to dillo instead of
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
637 * calling exit() */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
638 if (st == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
639 MSG("ERROR while reading from file \"%s\", error was \"%s\"\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
640 filename, strerror(errno));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
641 exit(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
642 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
643
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
644 File_close(fd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
645 return FILE_OK;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
646 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
647
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
648 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
649 * Given an hex octet (e3, 2F, 20), return the corresponding
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
650 * character if the octet is valid, and -1 otherwise
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
651 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
652 static int File_parse_hex_octet(const char *s)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
653 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
654 int hex_value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
655 char *tail, hex[3];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
656
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
657 if ((hex[0] = s[0]) && (hex[1] = s[1])) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
658 hex[2] = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
659 hex_value = strtol(hex, &tail, 16);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
660 if (tail - hex == 2)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
661 return hex_value;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
662 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
663
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
664 return -1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
665 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
666
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
667 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
668 * Make a file URL into a human (and machine) readable path.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
669 * The idea is to always have a path that starts with only one slash.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
670 * Embedded slashes are ignored.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
671 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
672 static char *File_normalize_path(const char *orig)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
673 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
674 char *str = (char *) orig, *basename = NULL, *ret = NULL, *p;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
675
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
676 /* Make sure the string starts with "file:/" */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
677 if (strncmp(str, "file:/", 5) != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
678 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
679 str += 5;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
680
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
681 /* Skip "localhost" */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
682 if (dStrncasecmp(str, "//localhost/", 12) == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
683 str += 11;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
684
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
685 /* Skip packed slashes, and leave just one */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
686 while (str[0] == '/' && str[1] == '/')
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
687 str++;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
688
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
689 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
690 int i, val;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
691 Dstr *ds = dStr_sized_new(32);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
692 dStr_sprintf(ds, "%s%s%s",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
693 basename ? basename : "",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
694 basename ? "/" : "",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
695 str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
696 dFree(basename);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
697
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
698 /* Parse possible hexadecimal octets in the URI path */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
699 for (i = 0; ds->str[i]; ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
700 if (ds->str[i] == '%' &&
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
701 (val = File_parse_hex_octet(ds->str + i+1)) != -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
702 ds->str[i] = val;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
703 dStr_erase(ds, i+1, 2);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
704 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
705 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
706 /* Remove the fragment if not a part of the filename */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
707 if ((p = strrchr(ds->str, '#')) != NULL && access(ds->str, F_OK) != 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
708 dStr_truncate(ds, p - ds->str);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
709 ret = ds->str;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
710 dStr_free(ds, 0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
711 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
712
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
713 return ret;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
714 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
715
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
716 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
717 * Set the style flag and ask for a reload, so it shows inmediatly.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
718 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
719 static void File_toggle_html_style(ClientInfo *Client)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
720 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
721 char *d_cmd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
722
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
723 OLD_STYLE = !OLD_STYLE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
724 d_cmd = a_Dpip_build_cmd("cmd=%s", "reload_request");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
725 sock_handler_write_str(Client->sh, 1, d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
726 dFree(d_cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
727 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
728
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
729 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
730 * Perform any necessary cleanups upon abnormal termination
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
731 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
732 static void termination_handler(int signum)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
733 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
734 exit(signum);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
735 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
736
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
737
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
738 /* Client handling ----------------------------------------------------------*/
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
739
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
740 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
741 * Add a new client to the list.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
742 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
743 static ClientInfo *File_add_client(int sock_fd)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
744 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
745 ClientInfo *NewClient;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
746
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
747 NewClient = dNew(ClientInfo, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
748 NewClient->sh = sock_handler_new(sock_fd, sock_fd, 8*1024);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
749 NewClient->status = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
750 NewClient->done = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
751 NewClient->old_style = OLD_STYLE;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
752 pthread_mutex_lock(&ClMut);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
753 dList_append(Clients, NewClient);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
754 pthread_mutex_unlock(&ClMut);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
755 return NewClient;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
756 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
757
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
758 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
759 * Get client record by number
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
760 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
761 static void *File_get_client_n(uint_t n)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
762 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
763 void *client;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
764
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
765 pthread_mutex_lock(&ClMut);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
766 client = dList_nth_data(Clients, n);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
767 pthread_mutex_unlock(&ClMut);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
768
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
769 return client;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
770 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
771
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
772 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
773 * Remove a client from the list.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
774 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
775 static void File_remove_client_n(uint_t n)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
776 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
777 ClientInfo *Client;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
778
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
779 pthread_mutex_lock(&ClMut);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
780 Client = dList_nth_data(Clients, n);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
781 dList_remove(Clients, (void *)Client);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
782 pthread_mutex_unlock(&ClMut);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
783
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
784 _MSG("Closing Socket Handler\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
785 sock_handler_close(Client->sh);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
786 sock_handler_free(Client->sh);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
787 dFree(Client);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
788 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
789
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
790 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
791 * Return the number of clients.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
792 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
793 static int File_num_clients(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
794 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
795 uint_t n;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
796
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
797 pthread_mutex_lock(&ClMut);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
798 n = dList_length(Clients);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
799 pthread_mutex_unlock(&ClMut);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
800
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
801 return n;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
802 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
803
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
804 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
805 * Serve this client.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
806 * (this function runs on its own thread)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
807 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
808 static void *File_serve_client(void *data)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
809 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
810 char *dpip_tag, *cmd = NULL, *url = NULL, *path;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
811 ClientInfo *Client = data;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
812
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
813 /* Read the dpi command */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
814 dpip_tag = sock_handler_read(Client->sh);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
815 MSG("dpip_tag={%s}\n", dpip_tag);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
816
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
817 if (dpip_tag) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
818 cmd = a_Dpip_get_attr(dpip_tag, strlen(dpip_tag), "cmd");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
819 if (cmd) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
820 if (strcmp(cmd, "DpiBye") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
821 DPIBYE = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
822 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
823 url = a_Dpip_get_attr(dpip_tag, strlen(dpip_tag), "url");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
824 if (!url)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
825 MSG("file.dpi:: Failed to parse 'url'\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
826 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
827 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
828 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
829 dFree(cmd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
830 dFree(dpip_tag);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
831
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
832 if (!DPIBYE && url) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
833 _MSG("url = '%s'\n", url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
834
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
835 path = File_normalize_path(url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
836 if (path) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
837 _MSG("path = '%s'\n", path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
838 File_get(Client, path, url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
839 } else if (strcmp(url, "dpi:/file/toggle") == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
840 File_toggle_html_style(Client);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
841 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
842 MSG("ERROR: URL path was %s\n", url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
843 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
844 dFree(path);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
845 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
846 dFree(url);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
847
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
848 /* flag the the transfer finished */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
849 Client->done = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
850
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
851 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
852 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
853
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
854 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
855 * Serve the client queue.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
856 * (this function runs on its own thread)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
857 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
858 static void *File_serve_clients(void *client)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
859 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
860 /* switch to detached state */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
861 pthread_detach(pthread_self());
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
862
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
863 while (File_num_clients()) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
864 client = File_get_client_n((uint_t)0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
865 File_serve_client(client);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
866 File_remove_client_n((uint_t)0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
867 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
868 ThreadRunning = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
869
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
870 return NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
871 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
872
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
873 /* --------------------------------------------------------------------------*/
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
874
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
875 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
876 * Check a fd for activity, with a max timeout.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
877 * return value: 0 if timeout, 1 if input available, -1 if error.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
878 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
879 int File_check_fd(int filedes, unsigned int seconds)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
880 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
881 int st;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
882 fd_set set;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
883 struct timeval timeout;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
884
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
885 /* Initialize the file descriptor set. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
886 FD_ZERO (&set);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
887 FD_SET (filedes, &set);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
888
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
889 /* Initialize the timeout data structure. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
890 timeout.tv_sec = seconds;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
891 timeout.tv_usec = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
892
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
893 do {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
894 st = select(FD_SETSIZE, &set, NULL, NULL, &timeout);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
895 } while (st == -1 && errno == EINTR);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
896
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
897 return st;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
898 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
899
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
900
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
901 int main(void)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
902 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
903 ClientInfo *NewClient;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
904 struct sockaddr_un spun;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
905 int temp_sock_descriptor;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
906 socklen_t address_size;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
907 int c_st, st = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
908 uint_t i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
909
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
910 /* Arrange the cleanup function for abnormal terminations */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
911 if (signal (SIGINT, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
912 signal (SIGINT, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
913 if (signal (SIGHUP, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
914 signal (SIGHUP, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
915 if (signal (SIGTERM, termination_handler) == SIG_IGN)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
916 signal (SIGTERM, SIG_IGN);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
917
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
918 MSG("(v.1) accepting connections...\n");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
919
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
920 /* initialize mutex */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
921 pthread_mutex_init(&ClMut, NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
922
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
923 /* initialize Clients list */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
924 Clients = dList_new(512);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
925
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
926 /* some OSes may need this... */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
927 address_size = sizeof(struct sockaddr_un);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
928
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
929 /* start the service loop */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
930 while (!DPIBYE) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
931 /* wait for a connection */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
932 do {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
933 c_st = File_check_fd(STDIN_FILENO, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
934 } while (c_st == 0 && !DPIBYE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
935 if (c_st < 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
936 perror("[select]");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
937 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
938 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
939 if (DPIBYE)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
940 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
941
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
942 temp_sock_descriptor =
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
943 accept(STDIN_FILENO, (struct sockaddr *)&spun, &address_size);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
944
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
945 if (temp_sock_descriptor == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
946 perror("[accept]");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
947 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
948 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
949
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
950 /* Create and initialize a new client */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
951 NewClient = File_add_client(temp_sock_descriptor);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
952
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
953 if (!ThreadRunning) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
954 ThreadRunning = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
955 /* Serve the client from a thread (avoids deadlocks) */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
956 if (pthread_create(&NewClient->thrID, NULL,
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
957 File_serve_clients, NewClient) != 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
958 perror("[pthread_create]");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
959 ThreadRunning = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
960 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
961 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
962 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
963 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
964
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
965 /* todo: handle a running thread better. */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
966 for (i = 0; i < 5 && ThreadRunning; ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
967 MSG("sleep i=%u", i);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
968 sleep(i);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
969 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
970
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
971 if (DPIBYE)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
972 st = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
973 return st;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
974 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
975