1 /* Shared protocol functions */
8 #include <sys/time.h> /* FreeBSD needs this before resource.h */
10 #include <sys/types.h> /* FreeBSD needs this before resource.h */
11 #ifdef HAVE_SYS_RESOURCE_H
12 #include <sys/resource.h>
20 #include "config/options.h"
21 #include "osdep/osdep.h"
22 #include "protocol/common.h"
23 #include "protocol/protocol.h"
24 #include "protocol/uri.h"
25 #include "util/conv.h"
26 #include "util/memory.h"
27 #include "util/string.h"
30 /* Close all non-terminal file descriptors. */
32 close_all_non_term_fd(void)
39 if (!getrlimit(RLIMIT_NOFILE
, &lim
))
42 for (n
= 3; n
< max
; n
++)
47 init_directory_listing(struct string
*page
, struct uri
*uri
)
49 struct string dirpath
= NULL_STRING
;
50 struct string decoded
= NULL_STRING
;
51 struct string location
= NULL_STRING
;
53 int local
= (uri
->protocol
== PROTOCOL_FILE
);
55 if (!init_string(page
)
56 || !init_string(&dirpath
)
57 || !init_string(&decoded
)
58 || !init_string(&location
)
59 || !add_uri_to_string(&dirpath
, uri
, URI_DATA
)
60 || !add_uri_to_string(&location
, uri
, URI_DIR_LOCATION
))
63 if (dirpath
.length
> 0
64 && !dir_sep(dirpath
.source
[dirpath
.length
- 1])
65 && !add_char_to_string(&dirpath
, local
? CHAR_DIR_SEP
: '/'))
68 /* Decode uri for displaying. */
69 if (!add_string_to_string(&decoded
, &dirpath
))
71 decode_uri_string(&decoded
);
73 if (!local
&& !add_char_to_string(&location
, '/'))
76 if (!add_to_string(page
, "<html>\n<head><title>"))
79 if (!local
&& !add_html_to_string(page
, location
.source
, location
.length
))
82 if (!add_html_to_string(page
, decoded
.source
, decoded
.length
)
83 || !add_to_string(page
, "</title>\n<base href=\"")
84 || !add_html_to_string(page
, location
.source
, location
.length
)
85 || !add_html_to_string(page
, dirpath
.source
, dirpath
.length
))
88 if (!add_to_string(page
, "\" />\n</head>\n<body>\n<h2>"))
91 /* Use module names? */
92 switch (uri
->protocol
) {
102 case PROTOCOL_GOPHER
:
112 if (!add_to_string(page
, info
)
113 || !add_to_string(page
, " directory "))
116 if (!local
&& !add_string_to_string(page
, &location
))
119 /* Make the directory path with links to each subdir. */
121 const unsigned char *slash
= dirpath
.source
;
122 const unsigned char *pslash
= slash
;
123 const unsigned char sep
= local
? CHAR_DIR_SEP
: '/';
125 while ((slash
= strchr(slash
, sep
)) != NULL
) {
126 done_string(&decoded
);
127 if (!init_string(&decoded
)
128 || !add_bytes_to_string(&decoded
, pslash
, slash
- pslash
))
130 decode_uri_string(&decoded
);
132 if (!add_to_string(page
, "<a href=\"")
133 || !add_html_to_string(page
, location
.source
, location
.length
)
134 || !add_html_to_string(page
, dirpath
.source
, slash
+ 1 - dirpath
.source
)
135 || !add_to_string(page
, "\">")
136 || !add_html_to_string(page
, decoded
.source
, decoded
.length
)
137 || !add_to_string(page
, "</a>")
138 || !add_html_to_string(page
, &sep
, 1))
145 if (!add_to_string(page
, "</h2>\n<pre>")) {
150 done_string(&dirpath
);
151 done_string(&decoded
);
152 done_string(&location
);
154 return page
->length
> 0 ? S_OK
: S_OUT_OF_MEM
;