blob: 7742a7b6d44e430e1e92c1d6b93b308522f3e0c4 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001#include "wsIntrn.h"
2#include <sys/types.h>
3#include <sys/wait.h>
4#include "uemf.h"
5
6static int cgiMax;
7typedef struct {
8 webs_t wp;
9 long fplacemark;
10 int handle;
11 char_t **envp;
12 char_t **argp;
13 char_t *cgiPath;
14 char_t *stdOut;
15 char_t *stdIn;
16} cgiRec;
17static cgiRec **cgiList;
18
19int websCgiProcess(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
20 char_t *url, char_t *path, char_t* query)
21{
22
23 int n, envpsize, argpsize, pHandle, cid;
24 char_t *cp, *cgiName, *cgiPath, **argp, **envp, **ep;
25 char_t cgiBuf[FNAMESIZE], *stdIn, *stdOut, cwd[FNAMESIZE];
26 sym_t *s;
27 cgiRec *cgip;
28 a_assert(path && *path == '/');
29 a_assert(url && *url);
30 a_assert(websValid(wp));
31 websStats.cgiHits++;
32 char *cgipath_temp = NULL;
33 gstrncpy(cgiBuf, path, TSZ(cgiBuf)-1);
34 cgipath_temp = gstrchr(&cgiBuf[1], '/');
35 if(cgipath_temp!=NULL)
36 {
37 cgipath_temp++;
38 }else
39 {
40 websError(wp, 200, T("cgiBuf error,check path"));
41
42 return 1;
43 }
44 printf("[goahead]cgipath_temp->%s.\n",cgipath_temp);
45 //if ((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL) {
46 if ((cgiName = gstrchr(cgipath_temp, '/')) == NULL) {
47
48 if((cgiName = gstrchr(&cgiBuf[1], '/')) == NULL)
49 {
50 websError(wp, 200, T("Missing CGI name"));
51
52 return 1;
53 }
54 }
55 cgiName++;
56 printf("[goahead]cgiName->%s.\n",cgiName);
57 if ((cp = gstrchr(cgiName, '/')) != NULL) {
58 *cp = '\0';
59 }
60 // fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s/%s"), websGetDefaultDir(),
61 // CGI_BIN, cgiName);
62 fmtAlloc(&cgiPath, FNAMESIZE, T("%s/%s"),"/etc_ro/cgi-bin", cgiName);
63 {
64 gstat_t sbuf;
65 if (gstat(cgiPath, &sbuf) != 0 || (sbuf.st_mode & S_IFREG) == 0) {
66 websError(wp, 200, T("CGI process file does not exist"));
67 bfree(B_L, cgiPath);
68 return 1;
69 }
70 if (gaccess(cgiPath, X_OK) != 0) {
71 websError(wp, 200, T("CGI process file is not executable"));
72 bfree(B_L, cgiPath);
73 return 1;
74 }
75 }
76 ggetcwd(cwd, FNAMESIZE);
77 if ((cp = gstrrchr(cgiPath, '/')) != NULL) {
78 *cp = '\0';
79 gchdir(cgiPath);
80 *cp = '/';
81 }
82 argpsize = 10;
83 argp = balloc(B_L, argpsize * sizeof(char_t *));
84 if(argp == NULL){
85 bfreeSafe(B_L, cgiPath);
86 return 1;
87 }
88 *argp = cgiPath;
89 n = 1;
90 if (gstrchr(query, '=') == NULL) {
91 websDecodeUrl(query, query, gstrlen(query));
92 for (cp = gstrtok(query, T(" ")); cp != NULL; ) {
93 *(argp+n) = cp;
94 n++;
95 if (n >= argpsize) {
96 argpsize *= 2;
97 argp = brealloc(B_L, argp, argpsize * sizeof(char_t *));
98 if(argp == NULL){
99 bfreeSafe(B_L, cgiPath);
100 return 1;
101 }
102 }
103 cp = gstrtok(NULL, T(" "));
104 }
105 }
106 *(argp+n) = NULL;
107 envpsize = WEBS_SYM_INIT;
108 envp = balloc(B_L, envpsize * sizeof(char_t *));
109 if(envp == NULL){
110 bfreeSafe(B_L, cgiPath);
111 bfreeSafe(B_L, argp);
112 return 1;
113 }
114 n = 0;
115 fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("PATH_TRANSLATED"), cgiPath);
116 n++;
117 fmtAlloc(envp+n, FNAMESIZE, T("%s=%s/%s"),T("SCRIPT_NAME"),
118 CGI_BIN, cgiName);
119 n++;
120 fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("REMOTE_USER"), wp->userName);
121 n++;
122 fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"),T("AUTH_TYPE"), wp->authType);
123 n++;
124 for (s = symFirst(wp->cgiVars); s != NULL; s = symNext(wp->cgiVars)) {
125 if (s->content.valid && s->content.type == string &&
126 gstrcmp(s->name.value.string, T("REMOTE_HOST")) != 0 &&
127 gstrcmp(s->name.value.string, T("HTTP_AUTHORIZATION")) != 0) {
128 fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), s->name.value.string,
129 s->content.value.string);
130 n++;
131 if (n >= envpsize) {
132 envpsize *= 2;
133 envp = brealloc(B_L, envp, envpsize * sizeof(char_t *));
134 if(envp == NULL){
135 bfreeSafe(B_L, cgiPath);
136 bfreeSafe(B_L, argp);
137 return 1;
138 }
139 }
140 }
141 }
142 if (wp->flags & WEBS_CGI_UPLOAD)
143 {
144
145 if((wp->has_firmware_upload_clean)||(wp->flags & WEBS_CGI_FIRMWARE_UPLOAD))
146 {
147 fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), FIRMWARE_TMP_FILE);
148 }
149 else
150 {
151 fmtAlloc(envp+n, FNAMESIZE, T("%s=%s"), T("UPLOAD_FILENAME"), wp->cgiStdin);
152 }
153 n++;
154 }
155 *(envp+n) = NULL;
156 if (wp->cgiStdin == NULL) {
157 wp->cgiStdin = websGetCgiCommName(wp);
158 }
159 stdIn = wp->cgiStdin;
160 stdOut = websGetCgiCommName(wp);
161 printf("[goahead]cgiPath->%s.\n",cgiPath);
162
163 if ((pHandle = websLaunchCgiProc(cgiPath, argp, envp, stdIn, stdOut))
164 == -1) {
165 websError(wp, 200, T("failed to spawn CGI task"));
166 for (ep = envp; *ep != NULL; ep++) {
167 bfreeSafe(B_L, *ep);
168 }
169 bfreeSafe(B_L, cgiPath);
170 bfreeSafe(B_L, argp);
171 bfreeSafe(B_L, envp);
172 bfreeSafe(B_L, stdOut);
173 } else {
174 cid = hAllocEntry((void***) &cgiList, &cgiMax, sizeof(cgiRec));
175 if(cgiList){
176 cgip = cgiList[cid];
177 cgip->handle = pHandle;
178 cgip->stdIn = stdIn;
179 cgip->stdOut = stdOut;
180 cgip->cgiPath = cgiPath;
181 cgip->argp = argp;
182 cgip->envp = envp;
183 cgip->wp = wp;
184 cgip->fplacemark = 0;
185 websTimeoutCancel(wp);
186 }
187 else
188 {
189 bfreeSafe(B_L, cgiPath);
190 bfreeSafe(B_L, argp);
191 bfreeSafe(B_L, envp);
192 bfreeSafe(B_L, stdOut);
193 }
194 }
195 gchdir(cwd);
196 return 1;
197
198}
199
200int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
201 char_t *url, char_t *path, char_t* query)
202{
203 if(!(wp->flags & WEBS_POST_REQUEST))
204 {
205 //websError(wp, 200, T("NOT POST REQUEST"));
206 printf("[goahead]NOT POST REQUEST.\n");
207 websDone(wp, 0);
208 return 1;
209 }
210
211 if (wp->flags & WEBS_CGI_HTTPSHARE_UPLOAD)
212 {
xf.libdd93d52023-05-12 07:10:14 -0700213 printf("[httpshare]call process_cgi_end.\n");
lh9ed821d2023-04-07 01:36:19 -0700214 return zte_process_cgi_end(wp);
215 }else if(wp->flags & WEBS_CGI_UPLOAD)
216 {
217 printf("[goahead]call upload cgi.\n");
218 return websCgiProcess(wp, urlPrefix, webDir, arg,url, path, query);
219 }else
220 {
221 //websError(wp, 200, T("NOT CGI OR HTTPSHARE,RETURN ERROR"));
222 printf("[goahead]wrong cgi request.\n");
223 websDone(wp, 0);
224 return 1;
225 }
226
227}
228
229void websCgiGatherOutput (cgiRec *cgip)
230{
231 gstat_t sbuf;
232 char_t cgiBuf[FNAMESIZE];
233 if ((gstat(cgip->stdOut, &sbuf) == 0) &&
234 (sbuf.st_size > cgip->fplacemark)) {
235 int fdout;
236 fdout = gopen(cgip->stdOut, O_RDONLY | O_BINARY, 0444 );
237 if (fdout >= 0) {
238 webs_t wp = cgip->wp;
239 int nRead;
240 int rc;
241 if (cgip->fplacemark == 0) {
242 websWrite(wp, T("HTTP/1.0 200 OK\n"));
243 }
244 if(glseek(fdout, cgip->fplacemark, SEEK_SET) < 0)
245 {
246 printf("[goahead]glseek fail.\n");
247 }
248 while ((nRead = gread(fdout, cgiBuf, FNAMESIZE)) > 0) {
249 rc = websWriteBlock(wp, cgiBuf, nRead);
250 if (rc < 0) {
251 //todo: cov m
252 }
253 cgip->fplacemark += nRead;
254 }
255 gclose(fdout);
256 }
257 }
258}
259
260void websCgiCleanup()
261{
262 cgiRec *cgip;
263 webs_t wp;
264 char_t **ep;
265 int cid, nTries;
266 for (cid = 0; cid < cgiMax; cid++) {
267 if ((cgip = cgiList[cid]) != NULL) {
268 int exit_status;
269 wp = cgip->wp;
270 websCgiGatherOutput (cgip);
271 if ( websCheckCgiProc(cgip->handle, &exit_status) == 0) {
272 nTries = 0;
273 while ((cgip->fplacemark == 0) && (nTries < 100)) {
274 websCgiGatherOutput(cgip);
275 if (cgip->fplacemark == 0) {
276 }
277 nTries++;
278 }
279 gunlink(cgip->stdIn);
280 gunlink(cgip->stdOut);
281 cgiMax = hFree((void***) &cgiList, cid);
282 for (ep = cgip->envp; ep != NULL && *ep != NULL; ep++) {
283 bfreeSafe(B_L, *ep);
284 }
285 bfreeSafe(B_L, cgip->cgiPath);
286 bfreeSafe(B_L, cgip->argp);
287 bfreeSafe(B_L, cgip->envp);
288 bfreeSafe(B_L, cgip->stdOut);
289 bfreeSafe(B_L, cgip);
290 if(wp->has_firmware_upload_clean){
291 if (WIFEXITED(exit_status) && WEXITSTATUS(exit_status) != 0) {
292 if (cgip->fplacemark == 0) { //cov h
293 websError(wp, 200, T("CGI generated no output"));
294 } else {
295 websDone(wp, 200);
296 }
297 return;
298 }
299 sync();
300 //doSystem("sleep 3 && reboot &");
301 }
302 if (cgip->fplacemark == 0) { //cov h
303 websError(wp, 200, T("CGI generated no output"));
304 } else {
305 websDone(wp, 200);
306 }
307 }
308 }
309 }
310}
311