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