1 /**********************************************************************
2 *
3 * rtems shttpd management
4 *
5 * FILE NAME : rtems_shttpd.c
6 *
7 * AUTHOR : Steven Johnson
8 *
9 * DESCRIPTION : Defines the interface functions to the shttp daemon
10 *
11 * REVISION : $Id: compat_rtems.c,v 1.2 2006/11/12 03:29:17 infidel Exp $
12 *
13 * COMMENTS :
14 *
15 **********************************************************************/
16
17 /**********************************************************************
18 * INCLUDED MODULES
19 **********************************************************************/
20 #include <rtems.h>
21 #include "defs.h"
22
23 #define MAX_WEB_BASE_PATH_LENGTH 256
24 #define MIN_SHTTPD_STACK (8*1024)
25
26 typedef struct RTEMS_HTTPD_ARGS {
27 rtems_shttpd_init init_callback;
28 rtems_shttpd_addpages addpages_callback;
29 char webroot[MAX_WEB_BASE_PATH_LENGTH];
30 } RTEMS_HTTPD_ARGS;
31
32 static int rtems_webserver_running = FALSE; //not running.
33
rtems_httpd_daemon(rtems_task_argument args)34 static rtems_task rtems_httpd_daemon(rtems_task_argument args )
35 {
36 RTEMS_HTTPD_ARGS *httpd_args = (RTEMS_HTTPD_ARGS*)args;
37
38 struct shttpd_ctx *ctx;
39
40 if (httpd_args != NULL)
41 if (httpd_args->init_callback != NULL)
42 httpd_args->init_callback();
43
44 /**************************************
45 * Initialize the web server
46 */
47 /*
48 * Initialize SHTTPD context.
49 * Set WWW root to current WEB_ROOT_PATH.
50 */
51 ctx = shttpd_init(NULL, "document_root", httpd_args->webroot, NULL);
52
53 if (httpd_args != NULL)
54 if (httpd_args->addpages_callback != NULL)
55 httpd_args->addpages_callback(ctx);
56
57 /* Finished with args, so free them */
58 if (httpd_args != NULL)
59 free(httpd_args);
60
61 /* Open listening socket */
62 shttpd_listen(ctx, 9000);
63
64 rtems_webserver_running = TRUE;
65
66 /* Serve connections infinitely until someone kills us */
67 while (rtems_webserver_running)
68 shttpd_poll(ctx, 1000);
69
70 /* Unreached, because we will be killed by a signal */
71 shttpd_fini(ctx);
72
73 rtems_task_delete( RTEMS_SELF );
74 }
75
rtems_initialize_webserver(rtems_task_priority initial_priority,rtems_unsigned32 stack_size,rtems_mode initial_modes,rtems_attribute attribute_set,rtems_shttpd_init init_callback,rtems_shttpd_addpages addpages_callback,char * webroot)76 rtems_status_code rtems_initialize_webserver(rtems_task_priority initial_priority,
77 rtems_unsigned32 stack_size,
78 rtems_mode initial_modes,
79 rtems_attribute attribute_set,
80 rtems_shttpd_init init_callback,
81 rtems_shttpd_addpages addpages_callback,
82 char *webroot
83 )
84 {
85 rtems_status_code sc;
86 rtems_id tid;
87 RTEMS_HTTPD_ARGS *args;
88
89 if (stack_size < MIN_SHTTPD_STACK)
90 stack_size = MIN_SHTTPD_STACK;
91
92 args = malloc(sizeof(RTEMS_HTTPD_ARGS));
93
94 if (args != NULL)
95 {
96 args->init_callback = init_callback;
97 args->addpages_callback = addpages_callback;
98 strncpy(args->webroot,webroot,MAX_WEB_BASE_PATH_LENGTH);
99
100 sc = rtems_task_create(rtems_build_name('H', 'T', 'P', 'D'),
101 initial_priority,
102 stack_size,
103 initial_modes,
104 attribute_set,
105 &tid);
106
107 if (sc == RTEMS_SUCCESSFUL)
108 {
109 sc = rtems_task_start(tid, rtems_httpd_daemon, (rtems_task_argument)args);
110 }
111 }
112 else
113 {
114 sc = RTEMS_NO_MEMORY;
115 }
116
117 return sc;
118 }
119
rtems_terminate_webserver(void)120 void rtems_terminate_webserver(void)
121 {
122 rtems_webserver_running = FALSE; //not running, so terminate
123 }
124
rtems_webserver_ok(void)125 int rtems_webserver_ok(void)
126 {
127 return rtems_webserver_running;
128 }
129
130 void
set_close_on_exec(int fd)131 set_close_on_exec(int fd)
132 {
133 // RTEMS Does not have a functional "execve"
134 // so technically this call does not do anything,
135 // but it doesnt hurt either.
136 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
137 }
138
139 int
my_stat(const char * path,struct stat * stp)140 my_stat(const char *path, struct stat *stp)
141 {
142 return (stat(path, stp));
143 }
144
145 int
my_open(const char * path,int flags,int mode)146 my_open(const char *path, int flags, int mode)
147 {
148 return (open(path, flags, mode));
149 }
150
151 int
my_remove(const char * path)152 my_remove(const char *path)
153 {
154 return (remove(path));
155 }
156
157 int
my_rename(const char * path1,const char * path2)158 my_rename(const char *path1, const char *path2)
159 {
160 return (rename(path1, path2));
161 }
162
163 int
my_mkdir(const char * path,int mode)164 my_mkdir(const char *path, int mode)
165 {
166 return (mkdir(path, mode));
167 }
168
169 char *
my_getcwd(char * buffer,int maxlen)170 my_getcwd(char *buffer, int maxlen)
171 {
172 return (getcwd(buffer, maxlen));
173 }
174
175 int
set_non_blocking_mode(int fd)176 set_non_blocking_mode(int fd)
177 {
178 int ret = -1;
179 int flags;
180
181 if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
182 DBG(("nonblock: fcntl(F_GETFL): %d", ERRNO));
183 } else if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) != 0) {
184 DBG(("nonblock: fcntl(F_SETFL): %d", ERRNO));
185 } else {
186 ret = 0; /* Success */
187 }
188
189 return (ret);
190 }
191
192 #if !defined(NO_CGI)
193 int
spawn_process(struct conn * c,const char * prog,char * envblk,char ** envp)194 spawn_process(struct conn *c, const char *prog, char *envblk, char **envp)
195 {
196 return (-1); // RTEMS does not have subprocess support as standard.
197 }
198 #endif
199