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