Changeset 0a7278e in rtems
- Timestamp:
-
Nov 29, 2009, 1:20:53 PM
(11 years ago)
- Author:
- Ralf Corsepius <ralf.corsepius@…>
- Branches:
- 4.10, 4.11, 5, master
- Children:
- 18daff9
- Parents:
- 0893220
- Message:
-
Whitespace removal.
- Location:
- cpukit
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
-
r0893220
|
r0a7278e
|
|
12 | 12 | |
13 | 13 | /* |
14 | | * The ASP module processes ASP pages and executes embedded scripts. It |
15 | | * support an open scripting architecture with in-built support for |
| 14 | * The ASP module processes ASP pages and executes embedded scripts. It |
| 15 | * support an open scripting architecture with in-built support for |
16 | 16 | * Ejscript(TM). |
17 | 17 | */ |
… |
… |
|
70 | 70 | /* |
71 | 71 | * Process ASP requests and expand all scripting commands. We read the |
72 | | * entire ASP page into memory and then process. If you have really big |
| 72 | * entire ASP page into memory and then process. If you have really big |
73 | 73 | * documents, it is better to make them plain HTML files rather than ASPs. |
74 | 74 | */ |
… |
… |
|
195 | 195 | if (websValid(wp)) { |
196 | 196 | if (result) { |
197 | | websWrite(wp, T("<h2><b>ASP Error: %s</b></h2>\n"), |
| 197 | websWrite(wp, T("<h2><b>ASP Error: %s</b></h2>\n"), |
198 | 198 | result); |
199 | 199 | websWrite(wp, T("<pre>%s</pre>"), nextp); |
… |
… |
|
244 | 244 | */ |
245 | 245 | |
246 | | int websAspDefine(char_t *name, |
| 246 | int websAspDefine(char_t *name, |
247 | 247 | int (*fn)(int ejid, webs_t wp, int argc, char_t **argv)) |
248 | 248 | { |
249 | | return ejSetGlobalFunctionDirect(websAspFunctions, name, |
| 249 | return ejSetGlobalFunctionDirect(websAspFunctions, name, |
250 | 250 | (int (*)(int, void*, int, char_t**)) fn); |
251 | 251 | } |
… |
… |
|
261 | 261 | |
262 | 262 | a_assert(websValid(wp)); |
263 | | |
| 263 | |
264 | 264 | for (i = 0; i < argc; ) { |
265 | 265 | a_assert(argv); |
… |
… |
|
306 | 306 | */ |
307 | 307 | |
308 | | static char_t *skipWhite(char_t *s) |
| 308 | static char_t *skipWhite(char_t *s) |
309 | 309 | { |
310 | 310 | a_assert(s); |
-
r0893220
|
r0a7278e
|
|
14 | 14 | * This module implements a very fast block allocation scheme suitable for |
15 | 15 | * ROMed environments. It maintains block class queues for rapid allocation |
16 | | * and minimal fragmentation. This module does not coalesce blocks. The |
17 | | * storage space may be populated statically or via the traditional malloc |
18 | | * mechanisms. Large blocks greater than the maximum class size may be |
19 | | * allocated from the O/S or run-time system via malloc. To permit the use |
| 16 | * and minimal fragmentation. This module does not coalesce blocks. The |
| 17 | * storage space may be populated statically or via the traditional malloc |
| 18 | * mechanisms. Large blocks greater than the maximum class size may be |
| 19 | * allocated from the O/S or run-time system via malloc. To permit the use |
20 | 20 | * of malloc, call bopen with flags set to B_USE_MALLOC (this is the default). |
21 | | * It is recommended that bopen be called first thing in the application. |
22 | | * If it is not, it will be called with default values on the first call to |
| 21 | * It is recommended that bopen be called first thing in the application. |
| 22 | * If it is not, it will be called with default values on the first call to |
23 | 23 | * balloc(). Note that this code is not designed for multi-threading purposes |
24 | 24 | * and it depends on newly declared variables being initialized to zero. |
25 | | */ |
| 25 | */ |
26 | 26 | |
27 | 27 | /********************************* Includes ***********************************/ |
… |
… |
|
86 | 86 | |
87 | 87 | /* |
88 | | * ROUNDUP4(size) returns the next higher integer value of size that is |
| 88 | * ROUNDUP4(size) returns the next higher integer value of size that is |
89 | 89 | * divisible by 4, or the value of size if size is divisible by 4. |
90 | 90 | * ROUNDUP4() is used in aligning memory allocations on 4-byte boundaries. |
… |
… |
|
132 | 132 | /* |
133 | 133 | * Initialize the balloc module. bopen should be called the very first thing |
134 | | * after the application starts and bclose should be called the last thing |
135 | | * before exiting. If bopen is not called, it will be called on the first |
136 | | * allocation with default values. "buf" points to memory to use of size |
137 | | * "bufsize". If buf is NULL, memory is allocated using malloc. flags may |
| 134 | * after the application starts and bclose should be called the last thing |
| 135 | * before exiting. If bopen is not called, it will be called on the first |
| 136 | * allocation with default values. "buf" points to memory to use of size |
| 137 | * "bufsize". If buf is NULL, memory is allocated using malloc. flags may |
138 | 138 | * be set to B_USE_MALLOC if using malloc is okay. This routine will allocate |
139 | 139 | * an initial buffer of size bufsize for use by the application. |
… |
… |
|
206 | 206 | /******************************************************************************/ |
207 | 207 | /* |
208 | | * Allocate a block of the requested size. First check the block |
| 208 | * Allocate a block of the requested size. First check the block |
209 | 209 | * queues for a suitable one. |
210 | 210 | */ |
… |
… |
|
290 | 290 | if (bFreeLeft > memSize) { |
291 | 291 | /* |
292 | | * The q was empty, and the free list has spare memory so |
| 292 | * The q was empty, and the free list has spare memory so |
293 | 293 | * create a new block out of the primary free block |
294 | 294 | */ |
… |
… |
|
391 | 391 | return; |
392 | 392 | } |
393 | | |
| 393 | |
394 | 394 | #ifdef B_VERIFY_CAUSES_SEVERE_OVERHEAD |
395 | 395 | bFillBlock(bp, memSize); |
… |
… |
|
443 | 443 | * Duplicate an ascii string, allow NULL pointers and then dup an empty string. |
444 | 444 | * If UNICODE, bstrdup above works with wide chars, so we need this routine |
445 | | * for ascii strings. |
| 445 | * for ascii strings. |
446 | 446 | */ |
447 | 447 | |
… |
… |
|
464 | 464 | /* |
465 | 465 | * Reallocate a block. Allow NULL pointers and just do a malloc. |
466 | | * Note: if the realloc fails, we return NULL and the previous buffer is |
| 466 | * Note: if the realloc fails, we return NULL and the previous buffer is |
467 | 467 | * preserved. |
468 | 468 | */ |
… |
… |
|
495 | 495 | /******************************************************************************/ |
496 | 496 | /* |
497 | | * Find the size of the block to be balloc'ed. It takes in a size, finds the |
| 497 | * Find the size of the block to be balloc'ed. It takes in a size, finds the |
498 | 498 | * smallest binary block it fits into, adds an overhead amount and returns. |
499 | 499 | * q is the binary size used to keep track of block sizes in use. Called |
… |
… |
|
527 | 527 | #ifdef B_STATS |
528 | 528 | /* |
529 | | * Statistics. Do output via calling the writefn callback function with |
530 | | * "handle" as the output file handle. |
| 529 | * Statistics. Do output via calling the writefn callback function with |
| 530 | * "handle" as the output file handle. |
531 | 531 | */ |
532 | 532 | |
… |
… |
|
569 | 569 | mem = count * (1 << (q + B_SHIFT)); |
570 | 570 | total += mem; |
571 | | (*writefn)(handle, |
| 571 | (*writefn)(handle, |
572 | 572 | T("%2d %5d %4d %6d %4d %5d %4d\n"), |
573 | | q, 1 << (q + B_SHIFT), count, mem, bStats[q].inuse, |
| 573 | q, 1 << (q + B_SHIFT), count, mem, bStats[q].inuse, |
574 | 574 | bStats[q].inuse * (1 << (q + B_SHIFT)), bStats[q].alloc); |
575 | 575 | } |
… |
… |
|
582 | 582 | * bFreeSize Initial memory reserved with bopen call |
583 | 583 | * bStatsMemMalloc memory from calls to system MALLOC |
584 | | * bStatsMemMax |
| 584 | * bStatsMemMax |
585 | 585 | * bStatsBallocMax largest amount of memory from balloc calls |
586 | 586 | * bStatsMemInUse |
… |
… |
|
600 | 600 | (*writefn)(handle, T("Memory currently balloced %7d\n"), bStatsBallocInUse); |
601 | 601 | (*writefn)(handle, T("Max blocks allocated %7d\n"), bStatsBlksMax); |
602 | | (*writefn)(handle, T("Maximum stack used %7d\n"), |
| 602 | (*writefn)(handle, T("Maximum stack used %7d\n"), |
603 | 603 | (int) bStackStart - (int) bStackMin); |
604 | 604 | |
… |
… |
|
619 | 619 | memcpy(files, bStatsFiles, len); |
620 | 620 | qsort(files, bStatsFilesMax, sizeof(bStatsFileType), bStatsFileSort); |
621 | | |
| 621 | |
622 | 622 | (*writefn)(handle, T("\nMemory Currently Allocated\n")); |
623 | 623 | total = 0; |
624 | | (*writefn)(handle, |
| 624 | (*writefn)(handle, |
625 | 625 | T(" bytes, blocks in use, total times,") |
626 | 626 | T("largest, q\n")); |
… |
… |
|
629 | 629 | if (fp->file[0]) { |
630 | 630 | (*writefn)(handle, T("%18s, %7d, %5d, %6d, %7d,%4d\n"), |
631 | | fp->file, fp->allocated, fp->count, fp->times, fp->largest, |
| 631 | fp->file, fp->allocated, fp->count, fp->times, fp->largest, |
632 | 632 | fp->q); |
633 | 633 | total += fp->allocated; |
… |
… |
|
645 | 645 | fp = blkp->who; |
646 | 646 | if (gisalnum(*cp)) { |
647 | | (*writefn)(handle, T("%-50s allocated by %s\n"), cp, |
| 647 | (*writefn)(handle, T("%-50s allocated by %s\n"), cp, |
648 | 648 | fp->file); |
649 | 649 | } |
… |
… |
|
775 | 775 | |
776 | 776 | /* |
777 | | * Update the per block stats. Try from the end first |
| 777 | * Update the per block stats. Try from the end first |
778 | 778 | */ |
779 | 779 | for (bp = &bStatsBlks[bStatsBlksMax - 1]; bp >= bStatsBlks; bp--) { |
… |
… |
|
833 | 833 | /* |
834 | 834 | * verifyUsedBlock verifies that a block which was previously allocated is |
835 | | * still uncorrupted. |
| 835 | * still uncorrupted. |
836 | 836 | */ |
837 | 837 | |
… |
… |
|
886 | 886 | * First verify all the free blocks. |
887 | 887 | */ |
888 | | for (q = 0; q < B_MAX_CLASS; q++) { |
| 888 | for (q = 0; q < B_MAX_CLASS; q++) { |
889 | 889 | for (bp = bQhead[q]; bp != NULL; bp = bp->u.next) { |
890 | 890 | verifyFreeBlock(bp, q); |
-
r0893220
|
r0a7278e
|
|
12 | 12 | /* |
13 | 13 | * This module implements the /cgi-bin handler. CGI processing differs from |
14 | | * goforms processing in that each CGI request is executed as a separate |
| 14 | * goforms processing in that each CGI request is executed as a separate |
15 | 15 | * process, rather than within the webserver process. For each CGI request the |
16 | 16 | * environment of the new process must be set to include all the CGI variables |
… |
… |
|
46 | 46 | * Process a form request. Returns 1 always to indicate it handled the URL |
47 | 47 | */ |
48 | | int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, |
| 48 | int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, |
49 | 49 | char_t *url, char_t *path, char_t* query) |
50 | 50 | { |
… |
… |
|
101 | 101 | #endif /* ! VXWORKS */ |
102 | 102 | |
103 | | |
| 103 | |
104 | 104 | /* |
105 | 105 | * Get the CWD for resetting after launching the child process CGI |
… |
… |
|
117 | 117 | * Build command line arguments. Only used if there is no non-encoded |
118 | 118 | * = character. This is indicative of a ISINDEX query. POST separators |
119 | | * are & and others are +. argp will point to a balloc'd array of |
| 119 | * are & and others are +. argp will point to a balloc'd array of |
120 | 120 | * pointers. Each pointer will point to substring within the |
121 | | * query string. This array of string pointers is how the spawn or |
122 | | * exec routines expect command line arguments to be passed. Since |
| 121 | * query string. This array of string pointers is how the spawn or |
| 122 | * exec routines expect command line arguments to be passed. Since |
123 | 123 | * we don't know ahead of time how many individual items there are in |
124 | | * the query string, the for loop includes logic to grow the array |
| 124 | * the query string, the for loop includes logic to grow the array |
125 | 125 | * size via brealloc. |
126 | 126 | */ |
… |
… |
|
144 | 144 | /* |
145 | 145 | * Add all CGI variables to the environment strings to be passed |
146 | | * to the spawned CGI process. This includes a few we don't |
| 146 | * to the spawned CGI process. This includes a few we don't |
147 | 147 | * already have in the symbol table, plus all those that are in |
148 | | * the cgiVars symbol table. envp will point to a balloc'd array of |
| 148 | * the cgiVars symbol table. envp will point to a balloc'd array of |
149 | 149 | * pointers. Each pointer will point to a balloc'd string containing |
150 | 150 | * the keyword value pair in the form keyword=value. Since we don't |
… |
… |
|
184 | 184 | if (wp->cgiStdin == NULL) { |
185 | 185 | wp->cgiStdin = websGetCgiCommName(); |
186 | | } |
| 186 | } |
187 | 187 | stdIn = wp->cgiStdin; |
188 | 188 | stdOut = websGetCgiCommName(); |
… |
… |
|
191 | 191 | * If successful, the cleanup will be done after the process completes. |
192 | 192 | */ |
193 | | if ((pHandle = websLaunchCgiProc(cgiPath, argp, envp, stdIn, stdOut)) |
| 193 | if ((pHandle = websLaunchCgiProc(cgiPath, argp, envp, stdIn, stdOut)) |
194 | 194 | == -1) { |
195 | 195 | websError(wp, 200, T("failed to spawn CGI task")); |
… |
… |
|
235 | 235 | gstat_t sbuf; |
236 | 236 | char_t cgiBuf[FNAMESIZE]; |
237 | | if ((gstat(cgip->stdOut, &sbuf) == 0) && |
| 237 | if ((gstat(cgip->stdOut, &sbuf) == 0) && |
238 | 238 | (sbuf.st_size > cgip->fplacemark)) { |
239 | 239 | int fdout; |
… |
… |
|
284 | 284 | */ |
285 | 285 | nTries = 0; |
286 | | /* |
| 286 | /* |
287 | 287 | * Make sure we didn't miss something during a task switch. |
288 | 288 | * Maximum wait is 100 times 10 msecs (1 second). |
… |
… |
|
290 | 290 | while ((cgip->fplacemark == 0) && (nTries < 100)) { |
291 | 291 | websCgiGatherOutput(cgip); |
292 | | /* |
293 | | * There are some cases when we detect app exit |
294 | | * before the file is ready. |
| 292 | /* |
| 293 | * There are some cases when we detect app exit |
| 294 | * before the file is ready. |
295 | 295 | */ |
296 | 296 | if (cgip->fplacemark == 0) { |
-
r0893220
|
r0a7278e
|
|
36 | 36 | * Process a default URL request. This will validate the URL and handle "../" |
37 | 37 | * and will provide support for Active Server Pages. As the handler is the |
38 | | * last handler to run, it always indicates that it has handled the URL |
39 | | * by returning 1. |
| 38 | * last handler to run, it always indicates that it has handled the URL |
| 39 | * by returning 1. |
40 | 40 | */ |
41 | 41 | |
… |
… |
|
85 | 85 | * Open the document. Stat for later use. |
86 | 86 | */ |
87 | | if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY, |
| 87 | if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY, |
88 | 88 | 0666) < 0) { |
89 | 89 | websError(wp, 400, T("Cannot open URL <b>%s</b>"), url); |
90 | 90 | return 1; |
91 | | } |
| 91 | } |
92 | 92 | |
93 | 93 | if (websPageStat(wp, lpath, path, &sbuf) < 0) { |
… |
… |
|
235 | 235 | * |
236 | 236 | * GoAhead is vulnerable to a directory traversal bug. A request such as |
237 | | * |
| 237 | * |
238 | 238 | * GoAhead-server/../../../../../../../ results in an error message |
239 | 239 | * 'Cannot open URL'. |
… |
… |
|
243 | 243 | * web root and read arbitrary files from the server. |
244 | 244 | * Hence a request like: |
245 | | * |
| 245 | * |
246 | 246 | * GoAhead-server/..%5C..%5C..%5C..%5C..%5C..%5C/winnt/win.ini returns the |
247 | 247 | * contents of the win.ini file. |
… |
… |
|
258 | 258 | token = gstrchr(token, '\\'); |
259 | 259 | } |
260 | | |
| 260 | |
261 | 261 | token = gstrtok(path, T("/")); |
262 | 262 | |
263 | 263 | /* |
264 | 264 | * Look at each directory segment and process "." and ".." segments |
265 | | * Don't allow the browser to pop outside the root web. |
| 265 | * Don't allow the browser to pop outside the root web. |
266 | 266 | */ |
267 | 267 | while (token != NULL) { |
… |
… |
|
364 | 364 | |
365 | 365 | /******************************************************************************/ |
366 | | /* |
| 366 | /* |
367 | 367 | * Closing down. Free resources. |
368 | 368 | */ |
-
r0893220
|
r0a7278e
|
|
1 | | /* |
| 1 | /* |
2 | 2 | * ej.h -- Ejscript(TM) header |
3 | 3 | * |
… |
… |
|
14 | 14 | /******************************** Description *********************************/ |
15 | 15 | |
16 | | /* |
| 16 | /* |
17 | 17 | * GoAhead Ejscript(TM) header. This defines the Ejscript API and internal |
18 | 18 | * structures. |
… |
… |
|
36 | 36 | extern int ejOpenEngine(sym_fd_t variables, sym_fd_t functions); |
37 | 37 | extern void ejCloseEngine(int eid); |
38 | | extern int ejSetGlobalFunction(int eid, char_t *name, |
| 38 | extern int ejSetGlobalFunction(int eid, char_t *name, |
39 | 39 | int (*fn)(int eid, void *handle, int argc, char_t **argv)); |
40 | 40 | extern void ejSetVar(int eid, char_t *var, char_t *value); |
-
r0893220
|
r0a7278e
|
|
1 | | /* |
| 1 | /* |
2 | 2 | * ejIntrn.h -- Ejscript(TM) header |
3 | 3 | * |
… |
… |
|
14 | 14 | /******************************** Description *********************************/ |
15 | 15 | |
16 | | /* |
| 16 | /* |
17 | 17 | * GoAhead Ejscript(TM) header. This defines the Ejscript API and internal |
18 | 18 | * structures. |
… |
… |
|
194 | 194 | extern int ejRemoveGlobalFunction(int eid, char_t *name); |
195 | 195 | extern void *ejGetGlobalFunction(int eid, char_t *name); |
196 | | extern int ejSetGlobalFunctionDirect(sym_fd_t functions, char_t *name, |
| 196 | extern int ejSetGlobalFunctionDirect(sym_fd_t functions, char_t *name, |
197 | 197 | int (*fn)(int eid, void *handle, int argc, char_t **argv)); |
198 | 198 | extern void ejError(ej_t* ep, char_t* fmt, ...); |
-
r0893220
|
r0a7278e
|
|
12 | 12 | |
13 | 13 | /* |
14 | | * Ejscript lexical analyser. This implementes a lexical analyser for a |
| 14 | * Ejscript lexical analyser. This implementes a lexical analyser for a |
15 | 15 | * a subset of the JavaScript language. |
16 | 16 | */ |
… |
… |
|
509 | 509 | return TOK_LITERAL; |
510 | 510 | |
511 | | case '0': case '1': case '2': case '3': case '4': |
| 511 | case '0': case '1': case '2': case '3': case '4': |
512 | 512 | case '5': case '6': case '7': case '8': case '9': |
513 | 513 | do { |
… |
… |
|
541 | 541 | } |
542 | 542 | } |
543 | | if (! gisalpha(*tokq->servp) && *tokq->servp != '$' && |
| 543 | if (! gisalpha(*tokq->servp) && *tokq->servp != '$' && |
544 | 544 | *tokq->servp != '_') { |
545 | 545 | ejError(ep, T("Invalid identifier %s"), tokq->servp); |
… |
… |
|
567 | 567 | } |
568 | 568 | |
569 | | /* |
| 569 | /* |
570 | 570 | * Skip white space after token to find out whether this is |
571 | 571 | * a function or not. |
572 | | */ |
| 572 | */ |
573 | 573 | while (c == ' ' || c == '\t' || c == '\r' || c == '\n') { |
574 | 574 | if ((c = inputGetc(ep)) < 0) |
… |
… |
|
683 | 683 | /******************************************************************************/ |
684 | 684 | /* |
685 | | * Convert a hex or octal character back to binary, return original char if |
| 685 | * Convert a hex or octal character back to binary, return original char if |
686 | 686 | * not a hex digit |
687 | 687 | */ |
-
r0893220
|
r0a7278e
|
|
175 | 175 | return NULL; |
176 | 176 | } |
177 | | |
| 177 | |
178 | 178 | if (gstat(path, &sbuf) < 0) { |
179 | 179 | gclose(fd); |
… |
… |
|
181 | 181 | return NULL; |
182 | 182 | } |
183 | | |
| 183 | |
184 | 184 | if ((fileBuf = balloc(B_L, sbuf.st_size + 1)) == NULL) { |
185 | 185 | gclose(fd); |
… |
… |
|
187 | 187 | return NULL; |
188 | 188 | } |
189 | | |
| 189 | |
190 | 190 | if (gread(fd, fileBuf, sbuf.st_size) != (int)sbuf.st_size) { |
191 | 191 | gclose(fd); |
… |
… |
|
194 | 194 | return NULL; |
195 | 195 | } |
196 | | |
| 196 | |
197 | 197 | fileBuf[sbuf.st_size] = '\0'; |
198 | 198 | gclose(fd); |
… |
… |
|
293 | 293 | void *endlessLoopTest; |
294 | 294 | int loopCounter; |
295 | | |
296 | | |
| 295 | |
| 296 | |
297 | 297 | a_assert(script); |
298 | 298 | |
299 | 299 | if (emsg) { |
300 | 300 | *emsg = NULL; |
301 | | } |
| 301 | } |
302 | 302 | |
303 | 303 | if ((ep = ejPtr(eid)) == NULL) { |
-
r0893220
|
r0a7278e
|
|
30 | 30 | */ |
31 | 31 | |
32 | | static char_t *basicProdDir = NULL; |
| 32 | static char_t *basicProdDir = NULL; |
33 | 33 | static char_t *basicDefaultDir = T("."); /* Default set to current */ |
34 | 34 | |
35 | 35 | /* |
36 | | * hAlloc chain list of table schemas to be closed |
| 36 | * hAlloc chain list of table schemas to be closed |
37 | 37 | */ |
38 | 38 | |
… |
… |
|
47 | 47 | |
48 | 48 | /******************************************************************************/ |
49 | | /* |
50 | | * Add a schema to the module-internal schema database |
| 49 | /* |
| 50 | * Add a schema to the module-internal schema database |
51 | 51 | */ |
52 | 52 | |
… |
… |
|
58 | 58 | a_assert(pTableRegister); |
59 | 59 | |
60 | | trace(4, T("DB: Registering database table <%s>\n"), |
| 60 | trace(4, T("DB: Registering database table <%s>\n"), |
61 | 61 | pTableRegister->name); |
62 | 62 | |
… |
… |
|
64 | 64 | * Bump up the size of the table array |
65 | 65 | */ |
66 | | tid = hAllocEntry((void*) &dbListTables, |
67 | | &dbMaxTables, sizeof(dbTable_t)); |
| 66 | tid = hAllocEntry((void*) &dbListTables, |
| 67 | &dbMaxTables, sizeof(dbTable_t)); |
68 | 68 | |
69 | 69 | /* |
… |
… |
|
93 | 93 | |
94 | 94 | for (i = 0; (i < pTableRegister->nColumns); i++) { |
95 | | pTable->columnNames[i] = |
| 95 | pTable->columnNames[i] = |
96 | 96 | bstrdup(B_L, pTableRegister->columnNames[i]); |
97 | 97 | pTable->columnTypes[i] = pTableRegister->columnTypes[i]; |
… |
… |
|
118 | 118 | */ |
119 | 119 | |
120 | | int dbOpen(char_t *tablename, char_t *filename, |
| 120 | int dbOpen(char_t *tablename, char_t *filename, |
121 | 121 | int (*gettime)(int did), int flags) |
122 | 122 | { |
123 | | basicProdDir = NULL; |
| 123 | basicProdDir = NULL; |
124 | 124 | basicDefaultDir = T("."); |
125 | 125 | dbMaxTables = 0; |
… |
… |
|
235 | 235 | */ |
236 | 236 | |
237 | | int dbSearchStr(int did, char_t *tablename, |
| 237 | int dbSearchStr(int did, char_t *tablename, |
238 | 238 | char_t *colName, char_t *value, int flags) |
239 | 239 | { |
… |
… |
|
253 | 253 | return DB_ERR_TABLE_NOT_FOUND; |
254 | 254 | } |
255 | | |
| 255 | |
256 | 256 | nColumns = pTable->nColumns; |
257 | 257 | nRows = pTable->nRows; |
… |
… |
|
270 | 270 | pRow = pTable->rows[row]; |
271 | 271 | if (pRow) { |
272 | | compareVal = (char_t *)(pRow[column]); |
| 272 | compareVal = (char_t *)(pRow[column]); |
273 | 273 | if (compareVal && (gstrcmp(compareVal, value) == 0)) { |
274 | 274 | return row; |
… |
… |
|
281 | 281 | * Return -2 if search column was not found |
282 | 282 | */ |
283 | | trace(3, T("DB: Unable to find column <%s> in table <%s>\n"), |
| 283 | trace(3, T("DB: Unable to find column <%s> in table <%s>\n"), |
284 | 284 | colName, tablename); |
285 | 285 | return DB_ERR_COL_NOT_FOUND; |
… |
… |
|
317 | 317 | size = pTable->nColumns * max(sizeof(int), sizeof(char_t *)); |
318 | 318 | return hAllocEntry((void***) &(pTable->rows), &(pTable->nRows), size); |
319 | | } |
| 319 | } |
320 | 320 | |
321 | 321 | return -1; |
… |
… |
|
324 | 324 | /******************************************************************************/ |
325 | 325 | /* |
326 | | * Delete a row in the table. |
| 326 | * Delete a row in the table. |
327 | 327 | */ |
328 | 328 | |
… |
… |
|
354 | 354 | */ |
355 | 355 | while (column < nColumns) { |
356 | | if (pRow[column] && |
| 356 | if (pRow[column] && |
357 | 357 | (pTable->columnTypes[column] == T_STRING)) { |
358 | 358 | bfree(B_L, (char_t *)pRow[column]); |
… |
… |
|
368 | 368 | bfreeSafe(B_L, pRow); |
369 | 369 | pTable->nRows = hFree((void ***)&pTable->rows, row); |
370 | | trace(5, T("DB: Deleted row <%d> from table <%s>\n"), |
| 370 | trace(5, T("DB: Deleted row <%d> from table <%s>\n"), |
371 | 371 | row, tablename); |
372 | 372 | } |
373 | 373 | return 0; |
374 | 374 | } else { |
375 | | trace(3, T("DB: Unable to delete row <%d> from table <%s>\n"), |
| 375 | trace(3, T("DB: Unable to delete row <%d> from table <%s>\n"), |
376 | 376 | row, tablename); |
377 | 377 | } |
378 | | |
| 378 | |
379 | 379 | return -1; |
380 | 380 | } |
… |
… |
|
382 | 382 | /*****************************************************************************/ |
383 | 383 | /* |
384 | | * Grow the rows in the table to the nominated size. |
| 384 | * Grow the rows in the table to the nominated size. |
385 | 385 | */ |
386 | 386 | |
… |
… |
|
409 | 409 | |
410 | 410 | if (nRows >= nNewRows) { |
411 | | /* |
| 411 | /* |
412 | 412 | * If number of rows already allocated exceeds requested number, do nothing |
413 | 413 | */ |
… |
… |
|
415 | 415 | nNewRows, tablename); |
416 | 416 | } else { |
417 | | trace(4, T("DB: Setting rows to <%d> in table <%s>\n"), |
| 417 | trace(4, T("DB: Setting rows to <%d> in table <%s>\n"), |
418 | 418 | nNewRows, tablename); |
419 | 419 | while (pTable->nRows < nNewRows) { |
… |
… |
|
423 | 423 | } |
424 | 424 | } |
425 | | } |
| 425 | } |
426 | 426 | |
427 | 427 | return nRet; |
… |
… |
|
436 | 436 | { |
437 | 437 | int tid; |
438 | | |
| 438 | |
439 | 439 | a_assert(tablename); |
440 | 440 | tid = dbGetTableId(did, tablename); |
… |
… |
|
456 | 456 | int colIndex, *pRow, tid; |
457 | 457 | dbTable_t *pTable; |
458 | | |
| 458 | |
459 | 459 | a_assert(table); |
460 | 460 | a_assert(column); |
… |
… |
|
490 | 490 | *returnValue = pRow[colIndex]; |
491 | 491 | return 0; |
492 | | } |
| 492 | } |
493 | 493 | return DB_ERR_ROW_DELETED; |
494 | 494 | } |
… |
… |
|
513 | 513 | /* |
514 | 514 | * The dbWriteInt function writes a value into a table at a given row and |
515 | | * column. The existence of the row and column is verified before the |
| 515 | * column. The existence of the row and column is verified before the |
516 | 516 | * write. 0 is returned on succes, -1 is returned on error. |
517 | 517 | */ |
… |
… |
|
536 | 536 | |
537 | 537 | pTable = dbListTables[tid]; |
538 | | |
| 538 | |
539 | 539 | if (pTable) { |
540 | 540 | /* |
… |
… |
|
566 | 566 | /******************************************************************************/ |
567 | 567 | /* |
568 | | * The dbWriteStr function writes a string value into a table at a given row |
569 | | * and column. The existence of the row and column is verified before the |
| 568 | * The dbWriteStr function writes a string value into a table at a given row |
| 569 | * and column. The existence of the row and column is verified before the |
570 | 570 | * write. The column is also checked to confirm it is a string field. |
571 | 571 | * 0 is returned on succes, -1 is returned on error. |
… |
… |
|
658 | 658 | a_assert(key && *key); |
659 | 659 | a_assert(value); |
660 | | |
| 660 | |
661 | 661 | fmtAlloc(&pLineOut, BUF_MAX, T("%s=%s\n"), key, value); |
662 | 662 | |
… |
… |
|
697 | 697 | */ |
698 | 698 | fmtAlloc(&tmpFile, FNAMESIZE, T("%s/data.tmp"), basicGetProductDir()); |
699 | | if ((fd = gopen(tmpFile, |
| 699 | if ((fd = gopen(tmpFile, |
700 | 700 | O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) < 0) { |
701 | 701 | trace(1, T("WARNING: Failed to open file %s\n"), tmpFile); |
… |
… |
|
724 | 724 | * write it out. |
725 | 725 | */ |
726 | | if ((pRow == NULL) || (pRow[0] == '\0') || |
| 726 | if ((pRow == NULL) || (pRow[0] == '\0') || |
727 | 727 | (*(char_t *)(pRow[0]) == '\0')) { |
728 | 728 | continue; |
… |
… |
|
731 | 731 | * Print the ROW=rowNumber directive to the file |
732 | 732 | */ |
733 | | fmtAlloc(&tmpNum, 20, T("%d"), row); |
| 733 | fmtAlloc(&tmpNum, 20, T("%d"), row); |
734 | 734 | rc = dbWriteKeyValue(fd, KEYWORD_ROW, tmpNum); |
735 | 735 | bfreeSafe(B_L, tmpNum); |
… |
… |
|
740 | 740 | * Print the key-value pairs (COLUMN=value) for data cells |
741 | 741 | */ |
742 | | for (column = 0; (column < nColumns) && (rc >= 0); |
| 742 | for (column = 0; (column < nColumns) && (rc >= 0); |
743 | 743 | column++, colNames++, colTypes++) { |
744 | 744 | if (*colTypes == T_STRING) { |
745 | | rc = dbWriteKeyValue(fd, *colNames, |
| 745 | rc = dbWriteKeyValue(fd, *colNames, |
746 | 746 | (char_t *)(pRow[column])); |
747 | 747 | } else { |
748 | | fmtAlloc(&tmpNum, 20, T("%d"), pRow[column]); |
| 748 | fmtAlloc(&tmpNum, 20, T("%d"), pRow[column]); |
749 | 749 | rc = dbWriteKeyValue(fd, *colNames, tmpNum); |
750 | 750 | bfreeSafe(B_L, tmpNum); |
… |
… |
|
753 | 753 | |
754 | 754 | if (rc < 0) { |
755 | | trace(1, T("WARNING: Failed to write to file %s\n"), |
| 755 | trace(1, T("WARNING: Failed to write to file %s\n"), |
756 | 756 | tmpFile); |
757 | 757 | nRet = -1; |
… |
… |
|
813 | 813 | /******************************************************************************/ |
814 | 814 | /* |
815 | | * Parse the file. These files consist of key-value pairs, separated by the |
| 815 | * Parse the file. These files consist of key-value pairs, separated by the |
816 | 816 | * "=" sign. Parsing of tables starts with the "TABLE=value" pair, and rows |
817 | 817 | * are parsed starting with the "ROW=value" pair. |
… |
… |
|
956 | 956 | } |
957 | 957 | } |
958 | | |
| 958 | |
959 | 959 | return -1; |
960 | 960 | } |
961 | 961 | |
962 | 962 | /******************************************************************************/ |
963 | | /* |
| 963 | /* |
964 | 964 | * Return a pointer to the table name, given its ID |
965 | 965 | */ |
… |
… |
|
992 | 992 | */ |
993 | 993 | |
994 | | static int GetColumnIndex(int tid, char_t *colName) |
| 994 | static int GetColumnIndex(int tid, char_t *colName) |
995 | 995 | { |
996 | 996 | int column; |
… |
… |
|
1020 | 1020 | int len; |
1021 | 1021 | |
1022 | | if (basicProdDir != NULL) { |
| 1022 | if (basicProdDir != NULL) { |
1023 | 1023 | bfree(B_L, basicProdDir); |
1024 | 1024 | } |
1025 | | |
| 1025 | |
1026 | 1026 | basicProdDir = bstrdup(B_L, proddir); |
1027 | 1027 | /* |
-
r0893220
|
r0a7278e
|
|
14 | 14 | * This module implements the /goform handler. It emulates CGI processing |
15 | 15 | * but performs this in-process and not as an external process. This enables |
16 | | * a very high performance implementation with easy parsing and decoding |
| 16 | * a very high performance implementation with easy parsing and decoding |
17 | 17 | * of query strings and posted data. |
18 | 18 | */ |
… |
… |
|
31 | 31 | */ |
32 | 32 | |
33 | | int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, |
| 33 | int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, |
34 | 34 | char_t *url, char_t *path, char_t *query) |
35 | 35 | { |
… |
… |
|
59 | 59 | |
60 | 60 | /* |
61 | | * Lookup the C form function first and then try tcl (no javascript support |
| 61 | * Lookup the C form function first and then try tcl (no javascript support |
62 | 62 | * yet). |
63 | 63 | */ |
… |
… |
|
93 | 93 | */ |
94 | 94 | |
95 | | int websFormDefine(char_t *name, void (*fn)(webs_t wp, char_t *path, |
| 95 | int websFormDefine(char_t *name, void (*fn)(webs_t wp, char_t *path, |
96 | 96 | char_t *query)) |
97 | 97 | { |
-
r0893220
|
r0a7278e
|
|
29 | 29 | |
30 | 30 | static int websUrlHandlerSort(const void *p1, const void *p2); |
31 | | static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, |
| 31 | static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, |
32 | 32 | int sid, char_t *url, char_t *path, char_t *query); |
33 | 33 | static char_t *websCondenseMultipleChars(char_t *strToCondense, char_t cCondense); |
… |
… |
|
73 | 73 | /******************************************************************************/ |
74 | 74 | /* |
75 | | * Define a new URL handler. urlPrefix is the URL prefix to match. webDir is |
| 75 | * Define a new URL handler. urlPrefix is the URL prefix to match. webDir is |
76 | 76 | * an optional root directory path for a web directory. arg is an optional |
77 | 77 | * arg to pass to the URL handler. flags defines the matching order. Valid |
78 | | * flags include WEBS_HANDLER_LAST, WEBS_HANDLER_FIRST. If multiple users |
79 | | * specify last or first, their order is defined alphabetically by the |
| 78 | * flags include WEBS_HANDLER_LAST, WEBS_HANDLER_FIRST. If multiple users |
| 79 | * specify last or first, their order is defined alphabetically by the |
80 | 80 | * urlPrefix. |
81 | 81 | */ |
82 | 82 | |
83 | 83 | int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, int arg, |
84 | | int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webdir, int arg, |
| 84 | int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webdir, int arg, |
85 | 85 | char_t *url, char_t *path, char_t *query), int flags) |
86 | 86 | { |
… |
… |
|
115 | 115 | * Sort in decreasing URL length order observing the flags for first and last |
116 | 116 | */ |
117 | | qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType), |
| 117 | qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType), |
118 | 118 | websUrlHandlerSort); |
119 | 119 | return 0; |
… |
… |
|
122 | 122 | /******************************************************************************/ |
123 | 123 | /* |
124 | | * Delete an existing URL handler. We don't reclaim the space of the old |
| 124 | * Delete an existing URL handler. We don't reclaim the space of the old |
125 | 125 | * handler, just NULL the entry. Return -1 if handler is not found. |
126 | 126 | */ |
127 | 127 | |
128 | | int websUrlHandlerDelete(int (*handler)(webs_t wp, char_t *urlPrefix, |
| 128 | int websUrlHandlerDelete(int (*handler)(webs_t wp, char_t *urlPrefix, |
129 | 129 | char_t *webDir, int arg, char_t *url, char_t *path, char_t *query)) |
130 | 130 | { |
… |
… |
|
173 | 173 | } |
174 | 174 | } |
175 | | return -rc; |
| 175 | return -rc; |
176 | 176 | } |
177 | 177 | |
… |
… |
|
217 | 217 | */ |
218 | 218 | |
219 | | static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, |
| 219 | static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, |
220 | 220 | int sid, char_t *url, char_t *path, char_t *query) |
221 | 221 | { |
… |
… |
|
226 | 226 | |
227 | 227 | /* |
228 | | * Trim the urlPrefix off the path and set the webdirectory. Add one to step |
| 228 | * Trim the urlPrefix off the path and set the webdirectory. Add one to step |
229 | 229 | * over the trailing '/' |
230 | 230 | */ |
… |
… |
|
237 | 237 | /* |
238 | 238 | * See if any valid handlers are defined for this request. If so, call them |
239 | | * and continue calling valid handlers until one accepts the request. |
| 239 | * and continue calling valid handlers until one accepts the request. |
240 | 240 | * Return true if a handler was invoked, else return FALSE. |
241 | 241 | */ |
… |
… |
|
256 | 256 | wp->state = WEBS_PROCESSING; |
257 | 257 | websStats.handlerHits++; |
258 | | |
| 258 | |
259 | 259 | websSetRequestPath(wp, websGetDefaultDir(), NULL); |
260 | 260 | |
… |
… |
|
266 | 266 | |
267 | 267 | /* |
268 | | * We loop over each handler in order till one accepts the request. |
| 268 | * We loop over each handler in order till one accepts the request. |
269 | 269 | * The security handler will handle the request if access is NOT allowed. |
270 | 270 | */ |
… |
… |
|
277 | 277 | first = 0; |
278 | 278 | } |
279 | | if ((*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg, |
| 279 | if ((*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg, |
280 | 280 | wp->url, wp->path, wp->query)) { |
281 | 281 | return 1; |
282 | 282 | } |
283 | 283 | if (!websValid(wp)) { |
284 | | trace(0, |
| 284 | trace(0, |
285 | 285 | T("webs: handler %s called websDone, but didn't return 1\n"), |
286 | 286 | sp->urlPrefix); |
… |
… |
|
290 | 290 | } |
291 | 291 | /* |
292 | | * If no handler processed the request, then return an error. Note: It is |
| 292 | * If no handler processed the request, then return an error. Note: It is |
293 | 293 | * the handlers responsibility to call websDone |
294 | 294 | */ |
… |
… |
|
327 | 327 | /* |
328 | 328 | * Look at each directory segment and process "." and ".." segments |
329 | | * Don't allow the browser to pop outside the root web. |
| 329 | * Don't allow the browser to pop outside the root web. |
330 | 330 | */ |
331 | 331 | while (token != NULL) { |
… |
… |
|
394 | 394 | *pStr = *pScan; |
395 | 395 | } |
396 | | |
| 396 | |
397 | 397 | pScan++; |
398 | 398 | pStr++; |
-
r0893220
|
r0a7278e
|
|
3 | 3 | * $Id$ |
4 | 4 | */ |
5 | | |
| 5 | |
6 | 6 | /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All |
7 | 7 | rights reserved. |
-
r0893220
|
r0a7278e
|
|
106 | 106 | |
107 | 107 | #if (defined (WIN) || defined (NW)) |
108 | | if ((cp = gstrrchr(name, '/')) == NULL && |
| 108 | if ((cp = gstrrchr(name, '/')) == NULL && |
109 | 109 | (cp = gstrrchr(name, '\\')) == NULL) |
110 | 110 | #else |
… |
… |
|
260 | 260 | int prec = -1; |
261 | 261 | for ( ; c != '\0'; c = *fmt++) { |
262 | | if (c == '-') { |
263 | | f |= flag_minus; |
264 | | } else if (c == '+') { |
265 | | f |= flag_plus; |
266 | | } else if (c == ' ') { |
267 | | f |= flag_space; |
268 | | } else if (c == '#') { |
269 | | f |= flag_hash; |
270 | | } else if (c == '0') { |
271 | | f |= flag_zero; |
| 262 | if (c == '-') { |
| 263 | f |= flag_minus; |
| 264 | } else if (c == '+') { |
| 265 | f |= flag_plus; |
| 266 | } else if (c == ' ') { |
| 267 | f |= flag_space; |
| 268 | } else if (c == '#') { |
| 269 | f |= flag_hash; |
| 270 | } else if (c == '0') { |
| 271 | f |= flag_zero; |
272 | 272 | } else { |
273 | 273 | break; |
… |
… |
|
342 | 342 | if (f & flag_hash && value != 0) { |
343 | 343 | if (c == 'x') { |
344 | | put_ulong(&buf, value, 16, 0, T("0x"), width, |
| 344 | put_ulong(&buf, value, 16, 0, T("0x"), width, |
345 | 345 | prec, f); |
346 | 346 | } else { |
347 | | put_ulong(&buf, value, 16, 1, T("0X"), width, |
| 347 | put_ulong(&buf, value, 16, 1, T("0X"), width, |
348 | 348 | prec, f); |
349 | 349 | } |
… |
… |
|
472 | 472 | int i; |
473 | 473 | |
474 | | if (len < 0) { |
475 | | len = strnlen(s, prec >= 0 ? prec : ULONG_MAX); |
476 | | } else if (prec >= 0 && prec < len) { |
477 | | len = prec; |
| 474 | if (len < 0) { |
| 475 | len = strnlen(s, prec >= 0 ? prec : ULONG_MAX); |
| 476 | } else if (prec >= 0 && prec < len) { |
| 477 | len = prec; |
478 | 478 | } |
479 | 479 | if (width > len && !(f & flag_minus)) { |
480 | | for (i = len; i < width; ++i) { |
481 | | put_char(buf, ' '); |
482 | | } |
483 | | } |
484 | | for (i = 0; i < len; ++i) { |
485 | | put_char(buf, s[i]); |
| 480 | for (i = len; i < width; ++i) { |
| 481 | put_char(buf, ' '); |
| 482 | } |
| 483 | } |
| 484 | for (i = 0; i < len; ++i) { |
| 485 | put_char(buf, s[i]); |
486 | 486 | } |
487 | 487 | if (width > len && f & flag_minus) { |
488 | | for (i = len; i < width; ++i) { |
489 | | put_char(buf, ' '); |
| 488 | for (i = len; i < width; ++i) { |
| 489 | put_char(buf, ' '); |
490 | 490 | } |
491 | 491 | } |
… |
… |
|
505 | 505 | for (len = 1, x = 1; x < ULONG_MAX / base; ++len, x = x2) { |
506 | 506 | x2 = x * base; |
507 | | if (x2 > value) { |
508 | | break; |
| 507 | if (x2 > value) { |
| 508 | break; |
509 | 509 | } |
510 | 510 | } |
511 | 511 | zeros = (prec > len) ? prec - len : 0; |
512 | 512 | width -= zeros + len; |
513 | | if (prefix != NULL) { |
514 | | width -= strnlen(prefix, ULONG_MAX); |
| 513 | if (prefix != NULL) { |
| 514 | width -= strnlen(prefix, ULONG_MAX); |
515 | 515 | } |
516 | 516 | if (!(f & flag_minus)) { |
517 | 517 | if (f & flag_zero) { |
518 | | for (i = 0; i < width; ++i) { |
519 | | put_char(buf, '0'); |
| 518 | for (i = 0; i < width; ++i) { |
| 519 | put_char(buf, '0'); |
520 | 520 | } |
521 | 521 | } else { |
522 | | for (i = 0; i < width; ++i) { |
523 | | put_char(buf, ' '); |
| 522 | for (i = 0; i < width; ++i) { |
| 523 | put_char(buf, ' '); |
524 | 524 | } |
525 | 525 | } |
526 | 526 | } |
527 | | if (prefix != NULL) { |
528 | | put_string(buf, prefix, -1, 0, -1, flag_none); |
529 | | } |
530 | | for (i = 0; i < zeros; ++i) { |
531 | | put_char(buf, '0'); |
| 527 | if (prefix != NULL) { |
| 528 | put_string(buf, prefix, -1, 0, -1, flag_none); |
| 529 | } |
| 530 | for (i = 0; i < zeros; ++i) { |
| 531 | put_char(buf, '0'); |
532 | 532 | } |
533 | 533 | for ( ; x > 0; x /= base) { |
… |
… |
|
537 | 537 | } |
538 | 538 | if (f & flag_minus) { |
539 | | for (i = 0; i < width; ++i) { |
540 | | put_char(buf, ' '); |
| 539 | for (i = 0; i < width; ++i) { |
| 540 | put_char(buf, ' '); |
541 | 541 | } |
542 | 542 | } |
-
r0893220
|
r0a7278e
|
|
37 | 37 | * | | | | |
38 | 38 | * rq->buf rq->servp rq->endp rq->enduf |
39 | | * |
| 39 | * |
40 | 40 | * The queue is empty when servp == endp. This means that the queue will hold |
41 | 41 | * at most rq->buflen -1 bytes. It is the filler's responsibility to ensure |
… |
… |
|
78 | 78 | * ringq should it need to grow to accomodate data being added. "maxsize" is |
79 | 79 | * an upper limit (sanity level) beyond which the q must not grow. Set maxsize |
80 | | * to -1 to imply no upper limit. The buffer for the ringq is always |
| 80 | * to -1 to imply no upper limit. The buffer for the ringq is always |
81 | 81 | * dynamically allocated. Set maxsize |
82 | 82 | */ |
… |
… |
|
124 | 124 | /******************************************************************************/ |
125 | 125 | /* |
126 | | * Return the length of the data in the ringq. Users must fill the queue to |
| 126 | * Return the length of the data in the ringq. Users must fill the queue to |
127 | 127 | * a high water mark of at most one less than the queue size. |
128 | 128 | */ |
… |
… |
|
168 | 168 | /******************************************************************************/ |
169 | 169 | /* |
170 | | * Add a char to the queue. Note if being used to store wide strings |
| 170 | * Add a char to the queue. Note if being used to store wide strings |
171 | 171 | * this does not add a trailing '\0'. Grow the q as required. |
172 | 172 | */ |
… |
… |
|
414 | 414 | /******************************************************************************/ |
415 | 415 | /* |
416 | | * Return the maximum number of bytes the ring q can accept via a single |
| 416 | * Return the maximum number of bytes the ring q can accept via a single |
417 | 417 | * block copy. Useful if the user is doing their own data insertion. |
418 | 418 | */ |
… |
… |
|
424 | 424 | a_assert(rq); |
425 | 425 | a_assert(rq->buflen == (rq->endbuf - rq->buf)); |
426 | | |
| 426 | |
427 | 427 | space = rq->buflen - RINGQ_LEN(rq) - 1; |
428 | 428 | in_a_line = rq->endbuf - rq->endp; |
… |
… |
|
433 | 433 | /******************************************************************************/ |
434 | 434 | /* |
435 | | * Return the maximum number of bytes the ring q can provide via a single |
| 435 | * Return the maximum number of bytes the ring q can provide via a single |
436 | 436 | * block copy. Useful if the user is doing their own data retrieval. |
437 | 437 | */ |
-
r0893220
|
r0a7278e
|
|
25 | 25 | /********************************** Defines ***********************************/ |
26 | 26 | /* |
27 | | * The following #defines change the behaviour of security in the absence |
| 27 | * The following #defines change the behaviour of security in the absence |
28 | 28 | * of User Management. |
29 | 29 | * Note that use of User management functions require prior calling of |
… |
… |
|
54 | 54 | */ |
55 | 55 | |
56 | | int websSecurityHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, |
| 56 | int websSecurityHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, |
57 | 57 | char_t *url, char_t *path, char_t *query) |
58 | 58 | { |
… |
… |
|
78 | 78 | return 0; |
79 | 79 | } |
80 | | |
| 80 | |
81 | 81 | /* |
82 | 82 | * Check to see if URL must be encrypted |
… |
… |
|
117 | 117 | websStats.access++; |
118 | 118 | websError(wp, 401, T("Access Denied\nUnknown User")); |
119 | | trace(3, T("SEC: Unknown user <%s> attempted to access <%s>\n"), |
| 119 | trace(3, T("SEC: Unknown user <%s> attempted to access <%s>\n"), |
120 | 120 | userid, path); |
121 | 121 | nRet = 1; |
… |
… |
|
154 | 154 | a_assert(wp->nonce); |
155 | 155 | a_assert(wp->password); |
156 | | |
| 156 | |
157 | 157 | digestCalc = websCalcDigest(wp); |
158 | 158 | a_assert(digestCalc); |
… |
… |
|
176 | 176 | #endif |
177 | 177 | websStats.errors++; |
178 | | websError(wp, 401, |
| 178 | websError(wp, 401, |
179 | 179 | T("Access to this document requires a password")); |
180 | 180 | nRet = 1; |
… |
… |
|
212 | 212 | /******************************************************************************/ |
213 | 213 | /* |
214 | | * Store the new password, expect a decoded password. Store in websPassword in |
| 214 | * Store the new password, expect a decoded password. Store in websPassword in |
215 | 215 | * the decoded form. |
216 | 216 | */ |
-
r0893220
|
r0a7278e
|
|
10 | 10 | |
11 | 11 | /* |
12 | | * Posix Socket Module. This supports blocking and non-blocking buffered |
| 12 | * Posix Socket Module. This supports blocking and non-blocking buffered |
13 | 13 | * socket I/O. |
14 | 14 | */ |
… |
… |
|
42 | 42 | /*********************************** Code *************************************/ |
43 | 43 | /* |
44 | | * Write to a socket. Absorb as much data as the socket can buffer. Block if |
45 | | * the socket is in blocking mode. Returns -1 on error, otherwise the number |
| 44 | * Write to a socket. Absorb as much data as the socket can buffer. Block if |
| 45 | * the socket is in blocking mode. Returns -1 on error, otherwise the number |
46 | 46 | * of bytes written. |
47 | 47 | */ |
… |
… |
|
61 | 61 | |
62 | 62 | /* |
63 | | * Loop adding as much data to the output ringq as we can absorb. Initiate a |
| 63 | * Loop adding as much data to the output ringq as we can absorb. Initiate a |
64 | 64 | * flush when the ringq is too full and continue. Block in socketFlush if the |
65 | 65 | * socket is in blocking mode. |
… |
… |
|
105 | 105 | char *byteBuf; |
106 | 106 | int r, len; |
107 | | |
| 107 | |
108 | 108 | len = gstrlen(buf); |
109 | 109 | byteBuf = ballocUniToAsc(buf, len); |
… |
… |
|
120 | 120 | * Read from a socket. Return the number of bytes read if successful. This |
121 | 121 | * may be less than the requested "bufsize" and may be zero. Return -1 for |
122 | | * errors. Return 0 for EOF. Otherwise return the number of bytes read. |
| 122 | * errors. Return 0 for EOF. Otherwise return the number of bytes read. |
123 | 123 | * If this routine returns zero it indicates an EOF condition. |
124 | 124 | * which can be verified with socketEof() |
125 | | |
| 125 | |
126 | 126 | * Note: this ignores the line buffer, so a previous socketGets |
127 | | * which read a partial line may cause a subsequent socketRead to miss some |
| 127 | * which read a partial line may cause a subsequent socketRead to miss some |
128 | 128 | * data. This routine may block if the socket is in blocking mode. |
129 | 129 | * |
… |
… |
|
162 | 162 | * This flush is critical for readers of datagram packets. If the |
163 | 163 | * buffer is not big enough to read the whole datagram in one hit, |
164 | | * the recvfrom call will fail. |
| 164 | * the recvfrom call will fail. |
165 | 165 | */ |
166 | 166 | ringqFlush(rq); |
… |
… |
|
182 | 182 | /* |
183 | 183 | * If bytesRead is 0, this is EOF since socketRead should never |
184 | | * be called unless there is data yet to be read. Set the flag. |
| 184 | * be called unless there is data yet to be read. Set the flag. |
185 | 185 | * Then pass back the number of bytes read. |
186 | 186 | */ |
… |
… |
|
205 | 205 | * Get a string from a socket. This returns data in *buf in a malloced string |
206 | 206 | * after trimming the '\n'. If there is zero bytes returned, *buf will be set |
207 | | * to NULL. If doing non-blocking I/O, it returns -1 for error, EOF or when |
| 207 | * to NULL. If doing non-blocking I/O, it returns -1 for error, EOF or when |
208 | 208 | * no complete line yet read. If doing blocking I/O, it will block until an |
209 | | * entire line is read. If a partial line is read socketInputBuffered or |
210 | | * socketEof can be used to distinguish between EOF and partial line still |
| 209 | * entire line is read. If a partial line is read socketInputBuffered or |
| 210 | * socketEof can be used to distinguish between EOF and partial line still |
211 | 211 | * buffered. This routine eats and ignores carriage returns. |
212 | 212 | */ |
… |
… |
|
232 | 232 | return rc; |
233 | 233 | } |
234 | | |
| 234 | |
235 | 235 | if (rc == 0) { |
236 | 236 | /* |
… |
… |
|
309 | 309 | } |
310 | 310 | continue; |
311 | | } |
| 311 | } |
312 | 312 | #endif |
313 | 313 | /* |
… |
… |
|
318 | 318 | if (sp->saveMask < 0 ) { |
319 | 319 | sp->saveMask = sp->handlerMask; |
320 | | socketRegisterInterest(sp, |
| 320 | socketRegisterInterest(sp, |
321 | 321 | sp->handlerMask | SOCKET_WRITABLE); |
322 | 322 | } |
… |
… |
|
434 | 434 | */ |
435 | 435 | |
436 | | void socketCreateHandler(int sid, int handlerMask, socketHandler_t handler, |
| 436 | void socketCreateHandler(int sid, int handlerMask, socketHandler_t handler, |
437 | 437 | int data) |
438 | 438 | { |
… |
… |
|
536 | 536 | */ |
537 | 537 | #ifndef UEMF |
538 | | #ifdef WIN |
| 538 | #ifdef WIN |
539 | 539 | if (sp->interestEvents & FD_WRITE) { |
540 | 540 | emfTime_t blockTime = { 0, 0 }; |
… |
… |
|
548 | 548 | /******************************************************************************/ |
549 | 549 | /* |
550 | | * If the sendto failed, swap the first two bytes in the |
| 550 | * If the sendto failed, swap the first two bytes in the |
551 | 551 | * sockaddr structure. This is a kludge due to a change in |
552 | | * VxWorks between versions 5.3 and 5.4, but we want the |
| 552 | * VxWorks between versions 5.3 and 5.4, but we want the |
553 | 553 | * product to run on either. |
554 | 554 | */ |
… |
… |
|
662 | 662 | if ((sp = socketList[i]) == NULL) { |
663 | 663 | continue; |
664 | | } |
| 664 | } |
665 | 665 | socketHighestFd = max(socketHighestFd, sp->sock); |
666 | 666 | } |
-
r0893220
|
r0a7278e
|
|
11 | 11 | |
12 | 12 | /* |
13 | | * Posix Socket Module. This supports blocking and non-blocking buffered |
| 13 | * Posix Socket Module. This supports blocking and non-blocking buffered |
14 | 14 | * socket I/O. |
15 | 15 | */ |
… |
… |
|
164 | 164 | hostent = gethostbyname(host); |
165 | 165 | if (hostent != NULL) { |
166 | | memcpy((char *) &sockaddr.sin_addr, |
| 166 | memcpy((char *) &sockaddr.sin_addr, |
167 | 167 | (char *) hostent->h_addr_list[0], |
168 | 168 | (size_t) hostent->h_length); |
… |
… |
|
222 | 222 | if (host) { |
223 | 223 | /* |
224 | | * Connect to the remote server in blocking mode, then go into |
| 224 | * Connect to the remote server in blocking mode, then go into |
225 | 225 | * non-blocking mode if desired. |
226 | 226 | */ |
… |
… |
|
251 | 251 | } |
252 | 252 | if ((rc = connect(sp->sock, (struct sockaddr *) &sockaddr, |
253 | | sizeof(sockaddr))) < 0 && |
| 253 | sizeof(sockaddr))) < 0 && |
254 | 254 | (rc = tryAlternateConnect(sp->sock, |
255 | 255 | (struct sockaddr *) &sockaddr)) < 0) { |
… |
… |
|
273 | 273 | rc = 1; |
274 | 274 | setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)); |
275 | | if (bind(sp->sock, (struct sockaddr *) &sockaddr, |
| 275 | if (bind(sp->sock, (struct sockaddr *) &sockaddr, |
276 | 276 | sizeof(sockaddr)) < 0) { |
277 | 277 | socketFree(sid); |
… |
… |
|
309 | 309 | /******************************************************************************/ |
310 | 310 | /* |
311 | | * If the connection failed, swap the first two bytes in the |
| 311 | * If the connection failed, swap the first two bytes in the |
312 | 312 | * sockaddr structure. This is a kludge due to a change in |
313 | | * VxWorks between versions 5.3 and 5.4, but we want the |
| 313 | * VxWorks between versions 5.3 and 5.4, but we want the |
314 | 314 | * product to run on either. |
315 | 315 | */ |
… |
… |
|
452 | 452 | bytesRead = recv(sp->sock, buf, toRead, 0); |
453 | 453 | } |
454 | | |
| 454 | |
455 | 455 | /* |
456 | | * BUG 01865 -- CPU utilization hangs on Windows. The original code used |
| 456 | * BUG 01865 -- CPU utilization hangs on Windows. The original code used |
457 | 457 | * the 'errno' global variable, which is not set by the winsock functions |
458 | 458 | * as it is under *nix platforms. We use the platform independent |
459 | | * socketGetError() function instead, which does handle Windows correctly. |
| 459 | * socketGetError() function instead, which does handle Windows correctly. |
460 | 460 | * Other, *nix compatible platforms should work as well, since on those |
461 | 461 | * platforms, socketGetError() just returns the value of errno. |
462 | 462 | * Thanks to Jonathan Burgoyne for the fix. |
463 | 463 | */ |
464 | | if (bytesRead < 0) |
| 464 | if (bytesRead < 0) |
465 | 465 | { |
466 | 466 | *errCode = socketGetError(); |
467 | | if (*errCode == ECONNRESET) |
| 467 | if (*errCode == ECONNRESET) |
468 | 468 | { |
469 | 469 | sp->flags |= SOCKET_CONNRESET; |
… |
… |
|
600 | 600 | continue; |
601 | 601 | } |
602 | | } |
| 602 | } |
603 | 603 | if (sp->flags & SOCKET_CONNRESET) { |
604 | 604 | socketCloseConnection(sid); |
… |
… |
|
624 | 624 | /******************************************************************************/ |
625 | 625 | /* |
626 | | * Wait for a handle to become readable or writable and return a number of |
| 626 | * Wait for a handle to become readable or writable and return a number of |
627 | 627 | * noticed events. Timeout is in milliseconds. |
628 | 628 | */ |
… |
… |
|
774 | 774 | index = sp->sock / (NBBY * sizeof(fd_mask)); |
775 | 775 | bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask))); |
776 | | |
| 776 | |
777 | 777 | /* |
778 | 778 | * Set the appropriate bit in the ready masks for the sp->sock. |
… |
… |
|
894 | 894 | sid = sp->sid; |
895 | 895 | if (sp->currentEvents & SOCKET_READABLE) { |
896 | | if (sp->flags & SOCKET_LISTENING) { |
| 896 | if (sp->flags & SOCKET_LISTENING) { |
897 | 897 | socketAccept(sp); |
898 | 898 | sp->currentEvents = 0; |
899 | 899 | return 1; |
900 | | } |
| 900 | } |
901 | 901 | |
902 | 902 | } else { |
… |
… |
|
930 | 930 | */ |
931 | 931 | if (sp->handler && (sp->handlerMask & sp->currentEvents)) { |
932 | | (sp->handler)(sid, sp->handlerMask & sp->currentEvents, |
| 932 | (sp->handler)(sid, sp->handlerMask & sp->currentEvents, |
933 | 933 | sp->handler_data); |
934 | 934 | /* |
935 | 935 | * Make sure socket pointer is still valid, then reset the currentEvents. |
936 | | */ |
| 936 | */ |
937 | 937 | if (socketList && sid < socketMax && socketList[sid] == sp) { |
938 | 938 | sp->currentEvents = 0; |
… |
… |
|
1009 | 1009 | |
1010 | 1010 | for (i = 0; i < socketMax; i++) { |
1011 | | if ((sp = socketList[i]) == NULL || |
| 1011 | if ((sp = socketList[i]) == NULL || |
1012 | 1012 | (sp->handlerMask & SOCKET_READABLE) == 0) { |
1013 | 1013 | continue; |
-
r0893220
|
r0a7278e
|
|
9 | 9 | |
10 | 10 | /* |
11 | | * Posix Socket Module. This supports blocking and non-blocking buffered |
| 11 | * Posix Socket Module. This supports blocking and non-blocking buffered |
12 | 12 | * socket I/O. |
13 | 13 | */ |
… |
… |
|
163 | 163 | hostent = gethostbyname(host); |
164 | 164 | if (hostent != NULL) { |
165 | | memcpy((char *) &sockaddr.sin_addr, |
| 165 | memcpy((char *) &sockaddr.sin_addr, |
166 | 166 | (char *) hostent->h_addr_list[0], |
167 | 167 | (size_t) hostent->h_length); |
… |
… |
|
221 | 221 | if (host) { |
222 | 222 | /* |
223 | | * Connect to the remote server in blocking mode, then go into |
| 223 | * Connect to the remote server in blocking mode, then go into |
224 | 224 | * non-blocking mode if desired. |
225 | 225 | */ |
… |
… |
|
250 | 250 | } |
251 | 251 | if ((rc = connect(sp->sock, (struct sockaddr *) &sockaddr, |
252 | | sizeof(sockaddr))) < 0 && |
| 252 | sizeof(sockaddr))) < 0 && |
253 | 253 | (rc = tryAlternateConnect(sp->sock, |
254 | 254 | (struct sockaddr *) &sockaddr)) < 0) { |
… |
… |
|
272 | 272 | rc = 1; |
273 | 273 | setsockopt(sp->sock, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)); |
274 | | if (bind(sp->sock, (struct sockaddr *) &sockaddr, |
| 274 | if (bind(sp->sock, (struct sockaddr *) &sockaddr, |
275 | 275 | sizeof(sockaddr)) < 0) { |
276 | 276 | socketFree(sid); |
… |
… |
|
307 | 307 | /******************************************************************************/ |
308 | 308 | /* |
309 | | * If the connection failed, swap the first two bytes in the |
| 309 | * If the connection failed, swap the first two bytes in the |
310 | 310 | * sockaddr structure. This is a kludge due to a change in |
311 | | * VxWorks between versions 5.3 and 5.4, but we want the |
| 311 | * VxWorks between versions 5.3 and 5.4, but we want the |
312 | 312 | * product to run on either. |
313 | 313 | */ |
… |
… |
|
585 | 585 | continue; |
586 | 586 | } |
587 | | } |
| 587 | } |
588 | 588 | if (sp->currentEvents & sp->handlerMask) { |
589 | 589 | return 1; |
… |
… |
|
605 | 605 | /******************************************************************************/ |
606 | 606 | /* |
607 | | * Wait for a handle to become readable or writable and return a number of |
| 607 | * Wait for a handle to become readable or writable and return a number of |
608 | 608 | * noticed events. Timeout is in milliseconds. |
609 | 609 | */ |
… |
… |
|
755 | 755 | index = sp->sock / (NBBY * sizeof(fd_mask)); |
756 | 756 | bit = 1 << (sp->sock % (NBBY * sizeof(fd_mask))); |
757 | | |
| 757 | |
758 | 758 | /* |
759 | 759 | * Set the appropriate bit in the ready masks for the sp->sock. |
… |
… |
|
875 | 875 | sid = sp->sid; |
876 | 876 | if (sp->currentEvents & SOCKET_READABLE) { |
877 | | if (sp->flags & SOCKET_LISTENING) { |
| 877 | if (sp->flags & SOCKET_LISTENING) { |
878 | 878 | socketAccept(sp); |
879 | 879 | sp->currentEvents = 0; |
880 | 880 | return 1; |
881 | | } |
| 881 | } |
882 | 882 | |
883 | 883 | } else { |
… |
… |
|
911 | 911 | */ |
912 | 912 | if (sp->handler && (sp->handlerMask & sp->currentEvents)) { |
913 | | (sp->handler)(sid, sp->handlerMask & sp->currentEvents, |
| 913 | (sp->handler)(sid, sp->handlerMask & sp->currentEvents, |
914 | 914 | sp->handler_data); |
915 | 915 | /* |
916 | 916 | * Make sure socket pointer is still valid, then reset the currentEvents. |
917 | | */ |
| 917 | */ |
918 | 918 | if (socketList && sid < socketMax && socketList[sid] == sp) { |
919 | 919 | sp->currentEvents = 0; |
… |
… |
|
990 | 990 | |
991 | 991 | for (i = 0; i < socketMax; i++) { |
992 | | if ((sp = socketList[i]) == NULL || |
| 992 | if ((sp = socketList[i]) == NULL || |
993 | 993 | (sp->handlerMask & SOCKET_READABLE) == 0) { |
994 | 994 | continue; |
-
r0893220
|
r0a7278e
|
|
51 | 51 | /*#ifdef DEV*/ |
52 | 52 | } else if (etype == E_ASSERT) { |
53 | | fmtAlloc(&buf, E_MAX_ERROR, |
54 | | T("Assertion %s, failed at %s %d\n"), fmtBuf, E_ARGS); |
| 53 | fmtAlloc(&buf, E_MAX_ERROR, |
| 54 | T("Assertion %s, failed at %s %d\n"), fmtBuf, E_ARGS); |
55 | 55 | /*#endif*/ |
56 | 56 | } else if (etype == E_USER) { |
… |
… |
|
61 | 61 | * bfreeSafe(B_L, buf) below will fail, because 'buf' is randomly |
62 | 62 | * initialized. To be nice, we format a message saying that this is an |
63 | | * unknown message type, and in doing so give buf a valid value. Thanks |
| 63 | * unknown message type, and in doing so give buf a valid value. Thanks |
64 | 64 | * to Simon Byholm. |
65 | 65 | */ |
… |
… |
|
130 | 130 | */ |
131 | 131 | |
132 | | void (*traceSetHandler(void (*function)(int level, char_t *buf))) |
| 132 | void (*traceSetHandler(void (*function)(int level, char_t *buf))) |
133 | 133 | (int level, char *buf) |
134 | 134 | { |
… |
… |
|
189 | 189 | |
190 | 190 | /******************************************************************************/ |
191 | | /* |
| 191 | /* |
192 | 192 | * Convert a string to upper case |
193 | 193 | */ |
… |
… |
|
216 | 216 | /* |
217 | 217 | * Convert integer to ascii string. Allow a NULL string in which case we |
218 | | * allocate a dynamic buffer. |
| 218 | * allocate a dynamic buffer. |
219 | 219 | */ |
220 | 220 | |
-
r0893220
|
r0a7278e
|
|
14 | 14 | /******************************** Description *********************************/ |
15 | 15 | |
16 | | /* |
| 16 | /* |
17 | 17 | * GoAhead Web Server header. This defines the Web public APIs |
18 | 18 | */ |
… |
… |
|
72 | 72 | #endif /* NW */ |
73 | 73 | |
74 | | #ifdef SCOV5 |
| 74 | #ifdef SCOV5 |
75 | 75 | #include <sys/types.h> |
76 | 76 | #include <stdio.h> |
… |
… |
|
280 | 280 | |
281 | 281 | /********************************** Unicode ***********************************/ |
282 | | /* |
283 | | * Constants and limits. Also FNAMESIZE and PATHSIZE are currently defined |
| 282 | /* |
| 283 | * Constants and limits. Also FNAMESIZE and PATHSIZE are currently defined |
284 | 284 | * in param.h to be 128 and 512 |
285 | 285 | */ |
… |
… |
|
313 | 313 | |
314 | 314 | /* |
315 | | * Text size of buffer macro. A buffer bytes will hold (size / char size) |
316 | | * characters. |
| 315 | * Text size of buffer macro. A buffer bytes will hold (size / char size) |
| 316 | * characters. |
317 | 317 | */ |
318 | 318 | #define TSZ(x) (sizeof(x) / sizeof(char_t)) |
… |
… |
|
654 | 654 | |
655 | 655 | /* |
656 | | * Allocation flags |
| 656 | * Allocation flags |
657 | 657 | */ |
658 | 658 | #define VALUE_ALLOCATE 0x1 |
… |
… |
|
692 | 692 | * | | | | |
693 | 693 | * rq->buf rq->servp rq->endp rq->enduf |
694 | | * |
| 694 | * |
695 | 695 | * The queue is empty when servp == endp. This means that the queue will hold |
696 | 696 | * at most rq->buflen -1 bytes. It is the fillers responsibility to ensure |
… |
… |
|
728 | 728 | |
729 | 729 | /* |
730 | | * Block classes are: 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, |
731 | | * 16384, 32768, 65536 |
| 730 | * Block classes are: 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, |
| 731 | * 16384, 32768, 65536 |
732 | 732 | */ |
733 | 733 | typedef struct { |
… |
… |
|
811 | 811 | /******************************************************************************/ |
812 | 812 | /* |
813 | | * Socket flags |
| 813 | * Socket flags |
814 | 814 | */ |
815 | 815 | |
… |
… |
|
847 | 847 | * Handler event masks |
848 | 848 | */ |
849 | | #define SOCKET_READABLE 0x2 /* Make socket readable */ |
| 849 | #define SOCKET_READABLE 0x2 /* Make socket readable */ |
850 | 850 | #define SOCKET_WRITABLE 0x4 /* Make socket writable */ |
851 | 851 | #define SOCKET_EXCEPTION 0x8 /* Interested in exceptions */ |
… |
… |
|
859 | 859 | |
860 | 860 | typedef void (*socketHandler_t)(int sid, int mask, int data); |
861 | | typedef int (*socketAccept_t)(int sid, char *ipaddr, int port, |
| 861 | typedef int (*socketAccept_t)(int sid, char *ipaddr, int port, |
862 | 862 | int listenSid); |
863 | 863 | typedef struct { |
… |
… |
|
1026 | 1026 | extern void socketClose(void); |
1027 | 1027 | extern void socketCloseConnection(int sid); |
1028 | | extern void socketCreateHandler(int sid, int mask, socketHandler_t |
| 1028 | extern void socketCreateHandler(int sid, int mask, socketHandler_t |
1029 | 1029 | handler, int arg); |
1030 | 1030 | extern void socketDeleteHandler(int sid); |
… |
… |
|
1037 | 1037 | extern int socketInputBuffered(int sid); |
1038 | 1038 | extern int socketOpen(void); |
1039 | | extern int socketOpenConnection(char *host, int port, |
| 1039 | extern int socketOpenConnection(char *host, int port, |
1040 | 1040 | socketAccept_t accept, int flags); |
1041 | 1041 | extern void socketProcess(int hid); |
… |
… |
|
1048 | 1048 | extern int socketSetBlock(int sid, int flags); |
1049 | 1049 | extern int socketGetBlock(int sid); |
1050 | | extern int socketAlloc(char *host, int port, socketAccept_t accept, |
| 1050 | extern int socketAlloc(char *host, int port, socketAccept_t accept, |
1051 | 1051 | int flags); |
1052 | 1052 | extern void socketFree(int sid); |
… |
… |
|
1075 | 1075 | extern void trace(int lev, char_t *fmt, ...); |
1076 | 1076 | extern void traceRaw(char_t *buf); |
1077 | | extern void (*traceSetHandler(void (*function)(int level, char_t *buf))) |
| 1077 | extern void (*traceSetHandler(void (*function)(int level, char_t *buf))) |
1078 | 1078 | (int level, char_t *buf); |
1079 | | |
| 1079 | |
1080 | 1080 | extern value_t valueInteger(long value); |
1081 | 1081 | extern value_t valueString(char_t *value, int flags); |
-
r0893220
|
r0a7278e
|
|
129 | 129 | #endif /* #ifdef UEMF */ |
130 | 130 | |
131 | | /* |
| 131 | /* |
132 | 132 | * Database Identifier returned from dbOpen() |
133 | 133 | */ |
134 | | static int didUM = -1; |
135 | | |
136 | | /* |
| 134 | static int didUM = -1; |
| 135 | |
| 136 | /* |
137 | 137 | * Configuration database persist filename |
138 | 138 | */ |
… |
… |
|
147 | 147 | /*********************************** Code *************************************/ |
148 | 148 | /* |
149 | | * umOpen() registers the UM tables in the fake emf-database |
| 149 | * umOpen() registers the UM tables in the fake emf-database |
150 | 150 | */ |
151 | 151 | |
… |
… |
|
176 | 176 | /******************************************************************************/ |
177 | 177 | /* |
178 | | * umClose() frees up the UM tables in the fake emf-database |
| 178 | * umClose() frees up the UM tables in the fake emf-database |
179 | 179 | */ |
180 | 180 | |
… |
… |
|
214 | 214 | |
215 | 215 | a_assert (saveFilename && *saveFilename); |
216 | | trace(3, T("UM: Writing User Configuration to file <%s>\n"), |
| 216 | trace(3, T("UM: Writing User Configuration to file <%s>\n"), |
217 | 217 | saveFilename); |
218 | 218 | |
… |
… |
|
237 | 237 | a_assert(saveFilename && *saveFilename); |
238 | 238 | |
239 | | trace(3, T("UM: Loading User Configuration from file <%s>\n"), |
| 239 | trace(3, T("UM: Loading User Configuration from file <%s>\n"), |
240 | 240 | saveFilename); |
241 | 241 | |
… |
… |
|
249 | 249 | /******************************************************************************/ |
250 | 250 | /* |
251 | | * Encrypt/Decrypt a text string. |
| 251 | * Encrypt/Decrypt a text string. |
252 | 252 | * Returns the number of characters encrypted. |
253 | 253 | */ |
… |
… |
|
270 | 270 | * Simply use existing character. |
271 | 271 | */ |
272 | | if (enChar && !gisspace(enChar)) |
| 272 | if (enChar && !gisspace(enChar)) |
273 | 273 | *textString = enChar; |
274 | 274 | /* |
… |
… |
|
306 | 306 | row = 0; |
307 | 307 | /* |
308 | | * Move through table until we retrieve the first row with non-null |
| 308 | * Move through table until we retrieve the first row with non-null |
309 | 309 | * column data. |
310 | 310 | */ |
311 | 311 | columnData = NULL; |
312 | | while ((check = dbReadStr(didUM, tableName, columnName, row++, |
| 312 | while ((check = dbReadStr(didUM, tableName, columnName, row++, |
313 | 313 | &columnData)) == 0 || (check == DB_ERR_ROW_DELETED)) { |
314 | 314 | if (columnData && *columnData) { |
… |
… |
|
322 | 322 | /******************************************************************************/ |
323 | 323 | /* |
324 | | * umGetNextRowData() - return a pointer to the first non-blank |
| 324 | * umGetNextRowData() - return a pointer to the first non-blank |
325 | 325 | * key value following the given one. |
326 | 326 | */ |
327 | 327 | |
328 | | static char_t *umGetNextRowData(char_t *tableName, char_t *columnName, |
| 328 | static char_t *umGetNextRowData(char_t *tableName, char_t *columnName, |
329 | 329 | char_t *keyLast) |
330 | 330 | { |
… |
… |
|
342 | 342 | key = NULL; |
343 | 343 | |
344 | | while ((((check = dbReadStr(didUM, tableName, columnName, row++, |
| 344 | while ((((check = dbReadStr(didUM, tableName, columnName, row++, |
345 | 345 | &key)) == 0) || (check == DB_ERR_ROW_DELETED)) && |
346 | 346 | ((key == NULL) || (gstrcmp(key, keyLast) != 0))) { |
… |
… |
|
355 | 355 | * Move through table until we retrieve the next row with a non-null key |
356 | 356 | */ |
357 | | while (((check = dbReadStr(didUM, tableName, columnName, row++, &key)) |
| 357 | while (((check = dbReadStr(didUM, tableName, columnName, row++, &key)) |
358 | 358 | == 0) || (check == DB_ERR_ROW_DELETED)) { |
359 | 359 | if (key && *key && (gstrcmp(key, keyLast) != 0)) { |
… |
… |
|
370 | 370 | */ |
371 | 371 | |
372 | | int umAddUser(char_t *user, char_t *pass, char_t *group, |
| 372 | int umAddUser(char_t *user, char_t *pass, char_t *group, |
373 | 373 | bool_t prot, bool_t disabled) |
374 | 374 | { |
… |
… |
|
425 | 425 | bfree(B_L, password); |
426 | 426 | dbWriteStr(didUM, UM_USER_TABLENAME, UM_GROUP, row, group); |
427 | | dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, prot); |
| 427 | dbWriteInt(didUM, UM_USER_TABLENAME, UM_PROT, row, prot); |
428 | 428 | dbWriteInt(didUM, UM_USER_TABLENAME, UM_DISABLE, row, disabled); |
429 | 429 | |
… |
… |
|
447 | 447 | if (umGetUserProtected(user)) { |
448 | 448 | return UM_ERR_PROTECTED; |
449 | | } |
| 449 | } |
450 | 450 | |
451 | 451 | /* |
… |
… |
|
454 | 454 | if ((row = dbSearchStr(didUM, UM_USER_TABLENAME, UM_NAME, user, 0)) >= 0) { |
455 | 455 | return dbDeleteRow(didUM, UM_USER_TABLENAME, row); |
456 | | } |
| 456 | } |
457 | 457 | |
458 | 458 | return UM_ERR_NOT_FOUND; |
… |
… |
|
473 | 473 | /* |
474 | 474 | * umGetNextUser() Returns the next user found in the "users" table after |
475 | | * the given user. |
| 475 | * the given user. |
476 | 476 | */ |
477 | 477 | |
… |
… |
|
698 | 698 | */ |
699 | 699 | |
700 | | int umAddGroup(char_t *group, short priv, accessMeth_t am, |
| 700 | int umAddGroup(char_t *group, short priv, accessMeth_t am, |
701 | 701 | bool_t prot, bool_t disabled) |
702 | 702 | { |
… |
… |
|
705 | 705 | a_assert(group && *group); |
706 | 706 | trace(3, T("UM: Adding group <%s>\n"), group); |
707 | | |
| 707 | |
708 | 708 | /* |
709 | 709 | * Do not allow duplicates |
… |
… |
|
762 | 762 | if (umGetGroupInUse(group)) { |
763 | 763 | return UM_ERR_IN_USE; |
764 | | } |
| 764 | } |
765 | 765 | |
766 | 766 | /* |
… |
… |
|
769 | 769 | if (umGetGroupProtected(group)) { |
770 | 770 | return UM_ERR_PROTECTED; |
771 | | } |
| 771 | } |
772 | 772 | |
773 | 773 | /* |
… |
… |
|
813 | 813 | if (dbSearchStr(didUM, UM_USER_TABLENAME, UM_GROUP, group, 0) >= 0) { |
814 | 814 | return TRUE; |
815 | | } |
| 815 | } |
816 | 816 | |
817 | 817 | /* |
… |
… |
|
820 | 820 | if (dbSearchStr(didUM, UM_ACCESS_TABLENAME, UM_GROUP, group, 0) >= 0) { |
821 | 821 | return TRUE; |
822 | | } |
| 822 | } |
823 | 823 | |
824 | 824 | return FALSE; |
… |
… |
|
920 | 920 | |
921 | 921 | if (row >= 0) { |
922 | | return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, |
| 922 | return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PRIVILEGE, row, |
923 | 923 | (int)privilege); |
924 | 924 | } else { |
… |
… |
|
961 | 961 | |
962 | 962 | if (row >= 0) { |
963 | | return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, |
| 963 | return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_DISABLE, row, |
964 | 964 | (int) !enabled); |
965 | 965 | } else { |
… |
… |
|
1002 | 1002 | |
1003 | 1003 | if (row >= 0) { |
1004 | | return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, |
| 1004 | return dbWriteInt(didUM, UM_GROUP_TABLENAME, UM_PROT, row, |
1005 | 1005 | (int) protect); |
1006 | 1006 | } else { |
… |
… |
|
1086 | 1086 | /******************************************************************************/ |
1087 | 1087 | /* |
1088 | | * umGetNextAccessLimit() - return a pointer to the first non-blank |
| 1088 | * umGetNextAccessLimit() - return a pointer to the first non-blank |
1089 | 1089 | * access limit following the given one |
1090 | 1090 | */ |
… |
… |
|
1125 | 1125 | if (row >= 0) { |
1126 | 1126 | dbReadInt(didUM, UM_ACCESS_TABLENAME, UM_METHOD, row, &am); |
1127 | | } |
| 1127 | } |
1128 | 1128 | |
1129 | 1129 | return (accessMeth_t) am; |
… |
… |
|
1182 | 1182 | |
1183 | 1183 | if (row >= 0) { |
1184 | | return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, |
| 1184 | return dbWriteInt(didUM, UM_ACCESS_TABLENAME, UM_SECURE, row, |
1185 | 1185 | (int)secure); |
1186 | 1186 | } else { |
… |
… |
|
1239 | 1239 | char_t *urlRet, *urlCheck, *lastChar; |
1240 | 1240 | int len; |
1241 | | |
| 1241 | |
1242 | 1242 | a_assert(url && *url); |
1243 | 1243 | urlRet = NULL; |
… |
… |
|
1258 | 1258 | lastChar--; |
1259 | 1259 | |
1260 | | while ((lastChar >= urlCheck) && ((*lastChar == '/') || |
| 1260 | while ((lastChar >= urlCheck) && ((*lastChar == '/') || |
1261 | 1261 | (*lastChar == '\\'))) { |
1262 | 1262 | *lastChar = 0; |
… |
… |
|
1264 | 1264 | } |
1265 | 1265 | |
1266 | | while ((lastChar >= urlCheck) && (*lastChar != '/') && |
| 1266 | while ((lastChar >= urlCheck) && (*lastChar != '/') && |
1267 | 1267 | (*lastChar != '\\')) { |
1268 | 1268 | *lastChar = 0; |
… |
… |
|
1287 | 1287 | accessMeth_t amRet; |
1288 | 1288 | char_t *urlHavingLimit, *group; |
1289 | | |
| 1289 | |
1290 | 1290 | urlHavingLimit = umGetAccessLimit(url); |
1291 | 1291 | if (urlHavingLimit) { |
… |
… |
|
1316 | 1316 | char_t *group, *usergroup, *urlHavingLimit; |
1317 | 1317 | short priv; |
1318 | | |
| 1318 | |
1319 | 1319 | a_assert(user && *user); |
1320 | 1320 | a_assert(url && *url); |
… |
… |
|
1373 | 1373 | |
1374 | 1374 | /* |
1375 | | * If the access method for the URL is AM_NONE then |
| 1375 | * If the access method for the URL is AM_NONE then |
1376 | 1376 | * the file "doesn't exist". |
1377 | 1377 | */ |
1378 | 1378 | if (amURL == AM_NONE) { |
1379 | 1379 | return FALSE; |
1380 | | } |
1381 | | |
1382 | | /* |
1383 | | * If Access Limit has a group specified, then the user must be a |
| 1380 | } |
| 1381 | |
| 1382 | /* |
| 1383 | * If Access Limit has a group specified, then the user must be a |
1384 | 1384 | * member of that group |
1385 | 1385 | */ |
… |
… |
|
1400 | 1400 | } |
1401 | 1401 | #endif |
1402 | | } |
1403 | | |
1404 | | /* |
1405 | | * Otherwise, user can access the URL |
| 1402 | } |
| 1403 | |
| 1404 | /* |
| 1405 | * Otherwise, user can access the URL |
1406 | 1406 | */ |
1407 | 1407 | return TRUE; |
-
r0893220
|
r0a7278e
|
|
31 | 31 | static void formDeleteUser(webs_t wp, char_t *path, char_t *query); |
32 | 32 | static void formDisplayUser(webs_t wp, char_t *path, char_t *query); |
33 | | static int aspGenerateUserList(int eid, webs_t wp, |
| 33 | static int aspGenerateUserList(int eid, webs_t wp, |
34 | 34 | int argc, char_t **argv); |
35 | 35 | |
36 | 36 | static void formAddGroup(webs_t wp, char_t *path, char_t *query); |
37 | 37 | static void formDeleteGroup(webs_t wp, char_t *path, char_t *query); |
38 | | static int aspGenerateGroupList(int eid, webs_t wp, |
| 38 | static int aspGenerateGroupList(int eid, webs_t wp, |
39 | 39 | int argc, char_t **argv); |
40 | 40 | |
41 | 41 | static void formAddAccessLimit(webs_t wp, char_t *path, char_t *query); |
42 | 42 | static void formDeleteAccessLimit(webs_t wp, char_t *path, char_t *query); |
43 | | static int aspGenerateAccessLimitList(int eid, webs_t wp, |
| 43 | static int aspGenerateAccessLimitList(int eid, webs_t wp, |
44 | 44 | int argc, char_t **argv); |
45 | 45 | |
46 | | static int aspGenerateAccessMethodList(int eid, webs_t wp, |
| 46 | static int aspGenerateAccessMethodList(int eid, webs_t wp, |
47 | 47 | int argc, char_t **argv); |
48 | | static int aspGeneratePrivilegeList(int eid, webs_t wp, |
| 48 | static int aspGeneratePrivilegeList(int eid, webs_t wp, |
49 | 49 | int argc, char_t **argv); |
50 | 50 | |
… |
… |
|
93 | 93 | a_assert(wp); |
94 | 94 | |
95 | | userid = websGetVar(wp, T("user"), T("")); |
96 | | pass1 = websGetVar(wp, T("password"), T("")); |
97 | | pass2 = websGetVar(wp, T("passconf"), T("")); |
98 | | group = websGetVar(wp, T("group"), T("")); |
99 | | enabled = websGetVar(wp, T("enabled"), T("")); |
100 | | ok = websGetVar(wp, T("ok"), T("")); |
| 95 | userid = websGetVar(wp, T("user"), T("")); |
| 96 | pass1 = websGetVar(wp, T("password"), T("")); |
| 97 | pass2 = websGetVar(wp, T("passconf"), T("")); |
| 98 | group = websGetVar(wp, T("group"), T("")); |
| 99 | enabled = websGetVar(wp, T("enabled"), T("")); |
| 100 | ok = websGetVar(wp, T("ok"), T("")); |
101 | 101 | |
102 | 102 | websHeader(wp); |
… |
… |
|
164 | 164 | a_assert(wp); |
165 | 165 | |
166 | | userid = websGetVar(wp, T("user"), T("")); |
167 | | ok = websGetVar(wp, T("ok"), T("")); |
| 166 | userid = websGetVar(wp, T("user"), T("")); |
| 167 | ok = websGetVar(wp, T("ok"), T("")); |
168 | 168 | |
169 | 169 | websHeader(wp); |
… |
… |
|
199 | 199 | a_assert(wp); |
200 | 200 | |
201 | | userid = websGetVar(wp, T("user"), T("")); |
202 | | ok = websGetVar(wp, T("ok"), T("")); |
| 201 | userid = websGetVar(wp, T("user"), T("")); |
| 202 | ok = websGetVar(wp, T("ok"), T("")); |
203 | 203 | |
204 | 204 | websHeader(wp); |
… |
… |
|
235 | 235 | a_assert(wp); |
236 | 236 | |
237 | | nBytes = websWrite(wp, |
| 237 | nBytes = websWrite(wp, |
238 | 238 | T("<SELECT NAME=\"user\" SIZE=\"3\" TITLE=\"Select a User\">")); |
239 | 239 | row = 0; |
… |
… |
|
242 | 242 | |
243 | 243 | while (userid && (nBytes > 0)) { |
244 | | nBytes = websWrite(wp, T("<OPTION VALUE=\"%s\">%s\n"), |
| 244 | nBytes = websWrite(wp, T("<OPTION VALUE=\"%s\">%s\n"), |
245 | 245 | userid, userid); |
246 | 246 | userid = umGetNextUser(userid); |
… |
… |
|
268 | 268 | a_assert(wp); |
269 | 269 | |
270 | | group = websGetVar(wp, T("group"), T("")); |
271 | | method = websGetVar(wp, T("method"), T("")); |
272 | | enabled = websGetVar(wp, T("enabled"), T("")); |
273 | | privilege = websGetVar(wp, T("privilege"), T("")); |
274 | | ok = websGetVar(wp, T("ok"), T("")); |
| 270 | group = websGetVar(wp, T("group"), T("")); |
| 271 | method = websGetVar(wp, T("method"), T("")); |
| 272 | enabled = websGetVar(wp, T("enabled"), T("")); |
| 273 | privilege = websGetVar(wp, T("privilege"), T("")); |
| 274 | ok = websGetVar(wp, T("ok"), T("")); |
275 | 275 | |
276 | 276 | websHeader(wp); |
… |
… |
|
320 | 320 | group, nCheck); |
321 | 321 | } else { |
322 | | websWrite(wp, T("Group, \"%s\" was successfully added."), |
| 322 | websWrite(wp, T("Group, \"%s\" was successfully added."), |
323 | 323 | group); |
324 | 324 | } |
… |
… |
|
341 | 341 | a_assert(wp); |
342 | 342 | |
343 | | group = websGetVar(wp, T("group"), T("")); |
344 | | ok = websGetVar(wp, T("ok"), T("")); |
| 343 | group = websGetVar(wp, T("group"), T("")); |
| 344 | ok = websGetVar(wp, T("ok"), T("")); |
345 | 345 | |
346 | 346 | websHeader(wp); |
… |
… |
|
380 | 380 | row = 0; |
381 | 381 | nBytesSent = 0; |
382 | | nBytes = websWrite(wp, |
| 382 | nBytes = websWrite(wp, |
383 | 383 | T("<SELECT NAME=\"group\" SIZE=\"3\" TITLE=\"Select a Group\">")); |
384 | 384 | /* |
… |
… |
|
413 | 413 | a_assert(wp); |
414 | 414 | |
415 | | url = websGetVar(wp, T("url"), T("")); |
416 | | group = websGetVar(wp, T("group"), T("")); |
417 | | method = websGetVar(wp, T("method"), T("")); |
418 | | secure = websGetVar(wp, T("secure"), T("")); |
419 | | ok = websGetVar(wp, T("ok"), T("")); |
| 415 | url = websGetVar(wp, T("url"), T("")); |
| 416 | group = websGetVar(wp, T("group"), T("")); |
| 417 | method = websGetVar(wp, T("method"), T("")); |
| 418 | secure = websGetVar(wp, T("secure"), T("")); |
| 419 | ok = websGetVar(wp, T("ok"), T("")); |
420 | 420 | |
421 | 421 | websHeader(wp); |
… |
… |
|
467 | 467 | a_assert(wp); |
468 | 468 | |
469 | | url = websGetVar(wp, T("url"), T("")); |
470 | | ok = websGetVar(wp, T("ok"), T("")); |
| 469 | url = websGetVar(wp, T("url"), T("")); |
| 470 | ok = websGetVar(wp, T("ok"), T("")); |
471 | 471 | |
472 | 472 | websHeader(wp); |
… |
… |
|
476 | 476 | websWrite(wp, T("Delete Access Limit Cancelled")); |
477 | 477 | } else if (umDeleteAccessLimit(url) != 0) { |
478 | | websWrite(wp, T("ERROR: Unable to delete Access Limit for [%s]"), |
| 478 | websWrite(wp, T("ERROR: Unable to delete Access Limit for [%s]"), |
479 | 479 | url); |
480 | 480 | } else { |
481 | | websWrite(wp, T("Access Limit for [%s], was successfully deleted."), |
| 481 | websWrite(wp, T("Access Limit for [%s], was successfully deleted."), |
482 | 482 | url); |
483 | 483 | } |
… |
… |
|
493 | 493 | */ |
494 | 494 | |
495 | | static int aspGenerateAccessLimitList(int eid, webs_t wp, |
| 495 | static int aspGenerateAccessLimitList(int eid, webs_t wp, |
496 | 496 | int argc, char_t **argv) |
497 | 497 | { |
… |
… |
|
503 | 503 | row = nBytesSent = 0; |
504 | 504 | url = umGetFirstAccessLimit(); |
505 | | nBytes = websWrite(wp, |
| 505 | nBytes = websWrite(wp, |
506 | 506 | T("<SELECT NAME=\"url\" SIZE=\"3\" TITLE=\"Select a URL\">")); |
507 | 507 | |
… |
… |
|
522 | 522 | */ |
523 | 523 | |
524 | | static int aspGenerateAccessMethodList(int eid, webs_t wp, |
| 524 | static int aspGenerateAccessMethodList(int eid, webs_t wp, |
525 | 525 | int argc, char_t **argv) |
526 | 526 | { |
… |
… |
|
529 | 529 | a_assert(wp); |
530 | 530 | |
531 | | nBytes = websWrite(wp, |
| 531 | nBytes = websWrite(wp, |
532 | 532 | T("<SELECT NAME=\"method\" SIZE=\"3\" TITLE=\"Select a Method\">")); |
533 | | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">FULL ACCESS\n"), |
| 533 | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">FULL ACCESS\n"), |
534 | 534 | AM_FULL); |
535 | | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">BASIC ACCESS\n"), |
| 535 | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">BASIC ACCESS\n"), |
536 | 536 | AM_BASIC); |
537 | | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\" SELECTED>DIGEST ACCESS\n"), |
| 537 | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\" SELECTED>DIGEST ACCESS\n"), |
538 | 538 | AM_DIGEST); |
539 | | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">NO ACCESS\n"), |
| 539 | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">NO ACCESS\n"), |
540 | 540 | AM_NONE); |
541 | 541 | nBytes += websWrite(wp, T("</SELECT>")); |
… |
… |
|
548 | 548 | */ |
549 | 549 | |
550 | | static int aspGeneratePrivilegeList(int eid, webs_t wp, |
| 550 | static int aspGeneratePrivilegeList(int eid, webs_t wp, |
551 | 551 | int argc, char_t **argv) |
552 | 552 | { |
… |
… |
|
559 | 559 | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">READ\n"), PRIV_READ); |
560 | 560 | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">EXECUTE\n"), PRIV_WRITE); |
561 | | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">ADMINISTRATE\n"), |
| 561 | nBytes += websWrite(wp, T("<OPTION VALUE=\"%d\">ADMINISTRATE\n"), |
562 | 562 | PRIV_ADMIN); |
563 | 563 | nBytes += websWrite(wp, T("</SELECT>")); |
… |
… |
|
577 | 577 | a_assert(wp); |
578 | 578 | |
579 | | ok = websGetVar(wp, T("ok"), T("")); |
| 579 | ok = websGetVar(wp, T("ok"), T("")); |
580 | 580 | |
581 | 581 | websHeader(wp); |
… |
… |
|
606 | 606 | a_assert(wp); |
607 | 607 | |
608 | | ok = websGetVar(wp, T("ok"), T("")); |
| 608 | ok = websGetVar(wp, T("ok"), T("")); |
609 | 609 | |
610 | 610 | websHeader(wp); |
-
r0893220
|
r0a7278e
|
|
48 | 48 | return buf; |
49 | 49 | } |
50 | | if (websUrlParse(url, &parsebuf, NULL, NULL, NULL, NULL, NULL, |
| 50 | if (websUrlParse(url, &parsebuf, NULL, NULL, NULL, NULL, NULL, |
51 | 51 | NULL, &ext) < 0) { |
52 | 52 | gstrcpy(buf, T("text/plain")); |
… |
… |
|
73 | 73 | */ |
74 | 74 | |
75 | | int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath, |
76 | | char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag, |
| 75 | int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath, |
| 76 | char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag, |
77 | 77 | char_t **pext) |
78 | 78 | { |
… |
… |
|
129 | 129 | if ((cp = gstrchr(tok, '/')) != NULL) { |
130 | 130 | /* |
131 | | * If a full URL is supplied, we need to copy the host and port |
| 131 | * If a full URL is supplied, we need to copy the host and port |
132 | 132 | * portions into static buffers. |
133 | 133 | */ |
… |
… |
|
156 | 156 | path = tok; |
157 | 157 | tok = query; |
158 | | } |
| 158 | } |
159 | 159 | |
160 | 160 | /* |
-
r0893220
|
r0a7278e
|
|
30 | 30 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, |
31 | 31 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
32 | | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, |
| 32 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, |
33 | 33 | -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, |
34 | 34 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, |
… |
… |
|
84 | 84 | c, i); |
85 | 85 | return -1; |
86 | | } |
| 86 | } |
87 | 87 | shiftbuf = shiftbuf | (c << shift); |
88 | 88 | shift -= 6; |
-
r0893220
|
r0a7278e
|
|
89 | 89 | time(&now); |
90 | 90 | fprintf(stdout, "/*\n * webrom.c -- Compiled Web Pages\n *\n"); |
91 | | fprintf(stdout, " * Compiled by GoAhead WebCompile: %s */\n\n", |
| 91 | fprintf(stdout, " * Compiled by GoAhead WebCompile: %s */\n\n", |
92 | 92 | gctime(&now)); |
93 | 93 | fprintf(stdout, "#include \"wsIntrn.h\"\n\n"); |
… |
… |
|
110 | 110 | if (gstat(file, &sbuf) == 0 && sbuf.st_mode & S_IFDIR) { |
111 | 111 | continue; |
112 | | } |
| 112 | } |
113 | 113 | if ((fd = gopen(file, O_RDONLY | O_BINARY)) < 0) { |
114 | 114 | fprintf(stderr, "Can't open file %s\n", file); |
… |
… |
|
171 | 171 | continue; |
172 | 172 | } |
173 | | fprintf(stdout, " { T(\"/%s\"), page_%d, %d },\n", cp, nFile, |
| 173 | fprintf(stdout, " { T(\"/%s\"), page_%d, %d },\n", cp, nFile, |
174 | 174 | sbuf.st_size); |
175 | 175 | nFile++; |
176 | 176 | } |
177 | | fclose(lp); |
178 | | |
| 177 | fclose(lp); |
| 178 | |
179 | 179 | fprintf(stdout, " { 0, 0, 0 },\n"); |
180 | 180 | fprintf(stdout, "};\n"); |
-
r0893220
|
r0a7278e
|
|
58 | 58 | /* The following holds the pointer to an allocated websTimer_t structure . |
59 | 59 | * Using this method only one timer can be active at a time, but |
60 | | * for the WebServer, this should be OK. |
| 60 | * for the WebServer, this should be OK. |
61 | 61 | */ |
62 | 62 | websTimer_t *tp; |
… |
… |
|
76 | 76 | static timer_t timer_id; |
77 | 77 | static void rtems_httpd_daemon(rtems_task_argument args); |
78 | | |
| 78 | |
79 | 79 | /*********************************** Code *************************************/ |
80 | 80 | /* |
… |
… |
|
91 | 91 | **********************************************************************/ |
92 | 92 | priority = 40; |
93 | | |
| 93 | |
94 | 94 | sc = rtems_task_create(rtems_build_name('H', 'T', 'P', 'D'), |
95 | 95 | priority, 8*1024, |
… |
… |
|
107 | 107 | { |
108 | 108 | return(RTEMS_UNSATISFIED); |
109 | | } |
| 109 | } |
110 | 110 | |
111 | 111 | return(RTEMS_SUCCESSFUL); |
… |
… |
|
117 | 117 | { |
118 | 118 | /* |
119 | | * Initialize the memory allocator. Allow use of malloc and start with a |
| 119 | * Initialize the memory allocator. Allow use of malloc and start with a |
120 | 120 | * 10K heap. |
121 | 121 | */ |
… |
… |
|
186 | 186 | |
187 | 187 | /* |
188 | | * Define the local Ip address, host name, default home page and the |
| 188 | * Define the local Ip address, host name, default home page and the |
189 | 189 | * root web directory. |
190 | 190 | */ |
… |
… |
|
193 | 193 | return -1; |
194 | 194 | } |
195 | | |
| 195 | |
196 | 196 | /* intaddr.s_addr = (unsigned long) hostGetByName(host); */ |
197 | 197 | if ((hp = gethostbyname(host)) == NULL) { |
… |
… |
|
229 | 229 | websSetPassword(password); |
230 | 230 | |
231 | | /* |
| 231 | /* |
232 | 232 | * Open the web server on the given port. If that port is taken, try |
233 | 233 | * the next sequential port for up to "retries" attempts. |
… |
… |
|
237 | 237 | /* |
238 | 238 | * First create the URL handlers. Note: handlers are called in sorted order |
239 | | * with the longest path handler examined first. Here we define the security |
| 239 | * with the longest path handler examined first. Here we define the security |
240 | 240 | * handler, forms handler and the default web page handler. |
241 | 241 | */ |
242 | | websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler, |
| 242 | websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler, |
243 | 243 | WEBS_HANDLER_FIRST); |
244 | 244 | websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0); |
245 | | websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler, |
246 | | WEBS_HANDLER_LAST); |
| 245 | websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler, |
| 246 | WEBS_HANDLER_LAST); |
247 | 247 | |
248 | 248 | /* |
… |
… |
|
256 | 256 | * Create a handler for the default home page |
257 | 257 | */ |
258 | | websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0); |
| 258 | websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0); |
259 | 259 | return 0; |
260 | 260 | } |
… |
… |
|
263 | 263 | /* |
264 | 264 | * Test Javascript binding for ASP. This will be invoked when "aspTest" is |
265 | | * embedded in an ASP page. See web/asp.asp for usage. Set browser to |
| 265 | * embedded in an ASP page. See web/asp.asp for usage. Set browser to |
266 | 266 | * "localhost/asp.asp" to test. |
267 | 267 | */ |
… |
… |
|
287 | 287 | char_t *name, *address; |
288 | 288 | |
289 | | name = websGetVar(wp, T("name"), T("Joe Smith")); |
290 | | address = websGetVar(wp, T("address"), T("1212 Milky Way Ave.")); |
| 289 | name = websGetVar(wp, T("name"), T("Joe Smith")); |
| 290 | address = websGetVar(wp, T("address"), T("1212 Milky Way Ave.")); |
291 | 291 | |
292 | 292 | websHeader(wp); |
… |
… |
|
343 | 343 | return NULL; |
344 | 344 | } |
345 | | |
| 345 | |
346 | 346 | #if 0 |
347 | 347 | act.sa_flags = 0; |
… |
… |
|
388 | 388 | |
389 | 389 | /* Copy the timer structure to a local first and delete it before calling |
390 | | * the function, since the function could create another timer. In this |
| 390 | * the function, since the function could create another timer. In this |
391 | 391 | * implementation, only one timer can be allocated at a time. |
392 | 392 | */ |
… |
… |
|
421 | 421 | |
422 | 422 | #if B_STATS |
423 | | static void memLeaks() |
| 423 | static void memLeaks() |
424 | 424 | { |
425 | 425 | int fd=1; |
-
r0893220
|
r0a7278e
|
|
128 | 128 | * Optional request log support |
129 | 129 | */ |
130 | | websLogFd = gopen(websLogname, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY, |
| 130 | websLogFd = gopen(websLogname, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY, |
131 | 131 | 0666); |
132 | 132 | a_assert(websLogFd >= 0); |
133 | 133 | #endif |
134 | | |
| 134 | |
135 | 135 | return websOpenListen(port, retries); |
136 | 136 | } |
… |
… |
|
155 | 155 | websCloseListen(); |
156 | 156 | |
157 | | /* |
| 157 | /* |
158 | 158 | * Close each open browser connection and free all resources |
159 | 159 | */ |
… |
… |
|
208 | 208 | orig, port - 1); |
209 | 209 | return -1; |
210 | | } |
| 210 | } |
211 | 211 | |
212 | 212 | /* |
… |
… |
|
223 | 223 | } else { |
224 | 224 | fmtAlloc(&websHostUrl, WEBS_MAX_URL + 80, T("%s:%d"), websHost, port); |
225 | | fmtAlloc(&websIpaddrUrl, WEBS_MAX_URL + 80, T("%s:%d"), |
| 225 | fmtAlloc(&websIpaddrUrl, WEBS_MAX_URL + 80, T("%s:%d"), |
226 | 226 | websIpaddr, port); |
227 | 227 | } |
… |
… |
|
279 | 279 | * to know for permitting administrative operations only for local access |
280 | 280 | */ |
281 | | if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 || |
282 | | gstrcmp(wp->ipaddr, websIpaddr) == 0 || |
| 281 | if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 || |
| 282 | gstrcmp(wp->ipaddr, websIpaddr) == 0 || |
283 | 283 | gstrcmp(wp->ipaddr, websHost) == 0) { |
284 | 284 | wp->flags |= WEBS_LOCAL_REQUEST; |
… |
… |
|
318 | 318 | if (mask & SOCKET_READABLE) { |
319 | 319 | websReadEvent(wp); |
320 | | } |
| 320 | } |
321 | 321 | if (mask & SOCKET_WRITABLE) { |
322 | 322 | if (websValid(wp) && wp->writeSocket) { |
323 | 323 | (*wp->writeSocket)(wp); |
324 | 324 | } |
325 | | } |
| 325 | } |
326 | 326 | } |
327 | 327 | |
… |
… |
|
329 | 329 | /* |
330 | 330 | * The webs read handler. This is the primary read event loop. It uses a |
331 | | * state machine to track progress while parsing the HTTP request. |
| 331 | * state machine to track progress while parsing the HTTP request. |
332 | 332 | * Note: we never block as the socket is always in non-blocking mode. |
333 | 333 | */ |
… |
… |
|
357 | 357 | /* |
358 | 358 | * Get more input into "text". Returns 0, if more data is needed |
359 | | * to continue, -1 if finished with the request, or 1 if all |
| 359 | * to continue, -1 if finished with the request, or 1 if all |
360 | 360 | * required data is available for current state. |
361 | 361 | */ |
… |
… |
|
372 | 372 | |
373 | 373 | /* |
374 | | * This is the state machine for the web server. |
| 374 | * This is the state machine for the web server. |
375 | 375 | */ |
376 | 376 | switch(wp->state) { |
… |
… |
|
385 | 385 | wp->state = WEBS_HEADER; |
386 | 386 | break; |
387 | | |
| 387 | |
388 | 388 | case WEBS_HEADER: |
389 | 389 | /* |
… |
… |
|
423 | 423 | nbytes += 1; |
424 | 424 | */ |
425 | | } else |
| 425 | } else |
426 | 426 | #endif |
427 | 427 | if (wp->query) { |
428 | 428 | if (wp->query[0] && !(wp->flags & WEBS_POST_DATA)) { |
429 | 429 | /* |
430 | | * Special case where the POST request also had query data |
| 430 | * Special case where the POST request also had query data |
431 | 431 | * specified in the URL, ie. url?query_data. In this case |
432 | 432 | * the URL query data is separated by a '&' from the posted |
… |
… |
|
534 | 534 | /******************************************************************************/ |
535 | 535 | /* |
536 | | * Get input from the browser. Return TRUE (!0) if the request has been |
537 | | * handled. Return -1 on errors or if the request has been processed, |
| 536 | * Get input from the browser. Return TRUE (!0) if the request has been |
| 537 | * handled. Return -1 on errors or if the request has been processed, |
538 | 538 | * 1 if input read, and 0 to instruct the caller to call again for more input. |
539 | 539 | * |
540 | 540 | * Note: socketRead will Return the number of bytes read if successful. This |
541 | 541 | * may be less than the requested "bufsize" and may be zero. It returns -1 for |
542 | | * errors. It returns 0 for EOF. Otherwise it returns the number of bytes |
543 | | * read. Since this may be zero, callers should use socketEof() to |
| 542 | * errors. It returns 0 for EOF. Otherwise it returns the number of bytes |
| 543 | * read. Since this may be zero, callers should use socketEof() to |
544 | 544 | * distinguish between this and EOF. |
545 | 545 | */ |
546 | 546 | |
547 | | static int websGetInput(webs_t wp, char_t **ptext, int *pnbytes) |
| 547 | static int websGetInput(webs_t wp, char_t **ptext, int *pnbytes) |
548 | 548 | { |
549 | 549 | char_t *text; |
… |
… |
|
593 | 593 | } else { /* Valid data */ |
594 | 594 | /* |
595 | | * Convert to UNICODE if necessary. First be sure the string |
| 595 | * Convert to UNICODE if necessary. First be sure the string |
596 | 596 | * is NULL terminated. |
597 | 597 | */ |
… |
… |
|
622 | 622 | if (wp->flags & WEBS_SECURE) { |
623 | 623 | /* |
624 | | * If state is WEBS_BEGIN and the request is secure, a -1 will |
| 624 | * If state is WEBS_BEGIN and the request is secure, a -1 will |
625 | 625 | * usually indicate SSL negotiation |
626 | 626 | */ |
… |
… |
|
639 | 639 | if (eof) { |
640 | 640 | /* |
641 | | * If this is a post request without content length, process |
642 | | * the request as we now have all the data. Otherwise just |
| 641 | * If this is a post request without content length, process |
| 642 | * the request as we now have all the data. Otherwise just |
643 | 643 | * close the connection. |
644 | 644 | */ |
… |
… |
|
667 | 667 | * this code assumes we were only expecting a one line header, which |
668 | 668 | * is not necessarily the case. So we weren't processing the whole |
669 | | * header and weren't fufilling requests properly. |
| 669 | * header and weren't fufilling requests properly. |
670 | 670 | */ |
671 | 671 | #ifdef UNUSED |
… |
… |
|
766 | 766 | */ |
767 | 767 | host = path = port = proto = query = ext = NULL; |
768 | | if (websUrlParse(url, &buf, &host, &path, &port, &query, &proto, |
| 768 | if (websUrlParse(url, &buf, &host, &path, &port, &query, &proto, |
769 | 769 | NULL, &ext) < 0) { |
770 | 770 | websError(wp, 400, T("Bad URL format")); |
… |
… |
|
788 | 788 | wp->protocol = bstrdup(B_L, proto); |
789 | 789 | wp->protoVersion = bstrdup(B_L, protoVer); |
790 | | |
| 790 | |
791 | 791 | if ((testPort = socketGetPort(wp->listenSid)) >= 0) { |
792 | 792 | wp->port = testPort; |
… |
… |
|
804 | 804 | #ifdef WEBS_PROXY_SUPPORT |
805 | 805 | /* |
806 | | * Determine if this is a request for local webs data. If it is not a proxied |
| 806 | * Determine if this is a request for local webs data. If it is not a proxied |
807 | 807 | * request from the browser, we won't see the "http://" or the system name, so |
808 | 808 | * we assume it must be talking to us directly for local webs data. |
809 | 809 | * Note: not fully implemented yet. |
810 | 810 | */ |
811 | | if (gstrstr(wp->url, T("http://")) == NULL || |
812 | | ((gstrcmp(wp->host, T("localhost")) == 0 || |
| 811 | if (gstrstr(wp->url, T("http://")) == NULL || |
| 812 | ((gstrcmp(wp->host, T("localhost")) == 0 || |
813 | 813 | gstrcmp(wp->host, websHost) == 0) && (wp->port == websPort))) { |
814 | 814 | wp->flags |= WEBS_LOCAL_PAGE; |
… |
… |
|
842 | 842 | websSetVar(wp, T("HTTP_AUTHORIZATION"), T("")); |
843 | 843 | |
844 | | /* |
| 844 | /* |
845 | 845 | * Parse the header and create the Http header keyword variables |
846 | 846 | * We rewrite the header as we go for non-local requests. NOTE: this |
… |
… |
|
894 | 894 | authType = bstrdup (B_L, value); |
895 | 895 | a_assert (authType); |
896 | | /* |
| 896 | /* |
897 | 897 | * Truncate authType at the next non-alpha character |
898 | 898 | */ |
… |
… |
|
1056 | 1056 | if (wp->clen > 0) |
1057 | 1057 | { |
1058 | | wp->flags |= WEBS_CLEN; |
| 1058 | wp->flags |= WEBS_CLEN; |
1059 | 1059 | websSetVar(wp, T("CONTENT_LENGTH"), value); |
1060 | 1060 | } |
… |
… |
|
1173 | 1173 | if (*keyword) { |
1174 | 1174 | /* |
1175 | | * If keyword has already been set, append the new value to what has |
| 1175 | * If keyword has already been set, append the new value to what has |
1176 | 1176 | * been stored. |
1177 | 1177 | */ |
… |
… |
|
1198 | 1198 | /* |
1199 | 1199 | * Define a webs (CGI) variable for this connection. Also create in relevant |
1200 | | * scripting engines. Note: the incoming value may be volatile. |
| 1200 | * scripting engines. Note: the incoming value may be volatile. |
1201 | 1201 | */ |
1202 | 1202 | |
… |
… |
|
1251 | 1251 | a_assert(websValid(wp)); |
1252 | 1252 | a_assert(var && *var); |
1253 | | |
| 1253 | |
1254 | 1254 | if ((sp = symLookup(wp->cgiVars, var)) != NULL) { |
1255 | 1255 | a_assert(sp->content.type == string); |
… |
… |
|
1272 | 1272 | a_assert(websValid(wp)); |
1273 | 1273 | a_assert(var && *var); |
1274 | | |
| 1274 | |
1275 | 1275 | if (gstrcmp(value, websGetVar(wp, var, T(" __UNDEF__ "))) == 0) { |
1276 | 1276 | return 1; |
… |
… |
|
1296 | 1296 | /******************************************************************************/ |
1297 | 1297 | /* |
1298 | | * Output a HTTP response back to the browser. If redirect is set to a |
| 1298 | * Output a HTTP response back to the browser. If redirect is set to a |
1299 | 1299 | * URL, the browser will be sent to this location. |
1300 | 1300 | */ |
… |
… |
|
1325 | 1325 | } |
1326 | 1326 | |
1327 | | /* |
| 1327 | /* |
1328 | 1328 | * By license terms the following line of code must not be modified. |
1329 | 1329 | */ |
1330 | 1330 | websWrite(wp, T("Server: %s\r\n"), WEBS_NAME); |
1331 | 1331 | |
1332 | | /* |
| 1332 | /* |
1333 | 1333 | * Timestamp/Date is usually the next to go |
1334 | 1334 | */ |
… |
… |
|
1342 | 1342 | if (code == 401) { |
1343 | 1343 | if (!(wp->flags & WEBS_AUTH_DIGEST)) { |
1344 | | websWrite(wp, T("WWW-Authenticate: Basic realm=\"%s\"\r\n"), |
| 1344 | websWrite(wp, T("WWW-Authenticate: Basic realm=\"%s\"\r\n"), |
1345 | 1345 | websGetRealm()); |
1346 | 1346 | #ifdef DIGEST_ACCESS_SUPPORT |
… |
… |
|
1349 | 1349 | |
1350 | 1350 | /* $$$ before... (note commas instead of semicolons...) |
1351 | | nonce = websCalcNonce(wp), |
1352 | | opaque = websCalcOpaque(wp), |
| 1351 | nonce = websCalcNonce(wp), |
| 1352 | opaque = websCalcOpaque(wp), |
1353 | 1353 | $$$ after */ |
1354 | 1354 | nonce = websCalcNonce(wp); |
1355 | | opaque = websCalcOpaque(wp); |
| 1355 | opaque = websCalcOpaque(wp); |
1356 | 1356 | /* ...$$$ end */ |
1357 | | websWrite(wp, |
| 1357 | websWrite(wp, |
1358 | 1358 | T("WWW-Authenticate: Digest realm=\"%s\", domain=\"%s\",") |
1359 | 1359 | T("qop=\"%s\", nonce=\"%s\", opaque=\"%s\",") |
1360 | | T("algorithm=\"%s\", stale=\"%s\"\r\n"), |
| 1360 | T("algorithm=\"%s\", stale=\"%s\"\r\n"), |
1361 | 1361 | websGetRealm(), |
1362 | 1362 | websGetHostUrl(), |
… |
… |
|
1377 | 1377 | websWrite(wp, T("Content-Type: text/html\r\n")); |
1378 | 1378 | /* |
1379 | | * We don't do a string length here as the message may be multi-line. |
1380 | | * Ie. <CR><LF> will count as only one and we will have a content-length |
| 1379 | * We don't do a string length here as the message may be multi-line. |
| 1380 | * Ie. <CR><LF> will count as only one and we will have a content-length |
1381 | 1381 | * that is too short. |
1382 | 1382 | * |
… |
… |
|
1437 | 1437 | * Add human readable message for completeness. Should not be required. |
1438 | 1438 | */ |
1439 | | fmtAlloc(&msgbuf, WEBS_MAX_URL + 80, |
| 1439 | fmtAlloc(&msgbuf, WEBS_MAX_URL + 80, |
1440 | 1440 | T("<html><head></head><body>\r\n\ |
1441 | 1441 | This document has moved to a new <a href=\"%s\">location</a>.\r\n\ |
… |
… |
|
1450 | 1450 | |
1451 | 1451 | /******************************************************************************/ |
1452 | | /* |
| 1452 | /* |
1453 | 1453 | * Output an error message and cleanup |
1454 | 1454 | */ |
… |
… |
|
1479 | 1479 | if (!reEntry) |
1480 | 1480 | { |
1481 | | /* |
| 1481 | /* |
1482 | 1482 | * The dmfRichError function that we're about to call may very well call |
1483 | 1483 | * websError() as part of its work. If that happens, we do NOT want to |
… |
… |
|
1507 | 1507 | */ |
1508 | 1508 | buf = NULL; |
1509 | | fmtAlloc(&buf, WEBS_BUFSIZE, msg, websErrorMsg(code), |
| 1509 | fmtAlloc(&buf, WEBS_BUFSIZE, msg, websErrorMsg(code), |
1510 | 1510 | websErrorMsg(code), wp->url, userMsg); |
1511 | 1511 | |
… |
… |
|
1545 | 1545 | char_t *buf; |
1546 | 1546 | int rc; |
1547 | | |
| 1547 | |
1548 | 1548 | a_assert(websValid(wp)); |
1549 | 1549 | |
… |
… |
|
1556 | 1556 | trace(0, T("webs: websWrite lost data, buffer overflow\n")); |
1557 | 1557 | } |
1558 | | |
| 1558 | |
1559 | 1559 | va_end(vargs); |
1560 | 1560 | a_assert(buf); |
… |
… |
|
1569 | 1569 | /* |
1570 | 1570 | * Write a block of data of length "nChars" to the user's browser. Public |
1571 | | * write block procedure. If unicode is turned on this function expects |
| 1571 | * write block procedure. If unicode is turned on this function expects |
1572 | 1572 | * buf to be a unicode string and it converts it to ASCII before writing. |
1573 | | * See websWriteDataNonBlock to always write binary or ASCII data with no |
| 1573 | * See websWriteDataNonBlock to always write binary or ASCII data with no |
1574 | 1574 | * unicode conversion. This returns the number of char_t's processed. |
1575 | 1575 | * It spins until nChars are flushed to the socket. For non-blocking |
… |
… |
|
1595 | 1595 | pBuf = asciiBuf = ballocUniToAsc(buf, nChars); |
1596 | 1596 | |
1597 | | while (nChars > 0) { |
| 1597 | while (nChars > 0) { |
1598 | 1598 | #ifdef WEBS_SSL_SUPPORT |
1599 | 1599 | if (wp->flags & WEBS_SECURE) { |
… |
… |
|
1670 | 1670 | char_t *ip, *op; |
1671 | 1671 | int num, i, c; |
1672 | | |
| 1672 | |
1673 | 1673 | a_assert(decoded); |
1674 | 1674 | a_assert(token); |
… |
… |
|
1732 | 1732 | *newLine = '\0'; |
1733 | 1733 | } |
1734 | | fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%s\t%s\t%s\tcode = %d\n"), |
| 1734 | fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%s\t%s\t%s\tcode = %d\n"), |
1735 | 1735 | timeStr, wp->ipaddr, wp->url, code); |
1736 | 1736 | #else |
1737 | | fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%d %s %d %d\n"), time(0), |
| 1737 | fmtAlloc(&buf, WEBS_MAX_URL + 80, T("%d %s %d %d\n"), time(0), |
1738 | 1738 | wp->url, code, wp->written); |
1739 | 1739 | #endif |
… |
… |
|
1829 | 1829 | /* |
1830 | 1830 | * If using Keep Alive (HTTP/1.1) we keep the socket open for a period |
1831 | | * while waiting for another request on the socket. |
| 1831 | * while waiting for another request on the socket. |
1832 | 1832 | */ |
1833 | 1833 | if (wp->flags & WEBS_KEEP_ALIVE) { |
… |
… |
|
1838 | 1838 | ringqFlush(&wp->header); |
1839 | 1839 | } |
1840 | | socketCreateHandler(wp->sid, SOCKET_READABLE, websSocketEvent, |
| 1840 | socketCreateHandler(wp->sid, SOCKET_READABLE, websSocketEvent, |
1841 | 1841 | (int) wp); |
1842 | 1842 | websTimeoutCancel(wp); |
… |
… |
|
2243 | 2243 | a_assert(websValid(wp)); |
2244 | 2244 | |
2245 | | if (dir) { |
| 2245 | if (dir) { |
2246 | 2246 | tmp = wp->dir; |
2247 | 2247 | wp->dir = bstrdup(B_L, dir); |
… |
… |
|
2373 | 2373 | #ifdef WEBS_IF_MODIFIED_SUPPORT |
2374 | 2374 | /******************************************************************************/ |
2375 | | /* |
2376 | | * These functions are intended to closely mirror the syntax for HTTP-date |
| 2375 | /* |
| 2376 | * These functions are intended to closely mirror the syntax for HTTP-date |
2377 | 2377 | * from RFC 2616 (HTTP/1.1 spec). This code was submitted by Pete Bergstrom. |
2378 | 2378 | */ |
2379 | 2379 | |
2380 | | /* |
| 2380 | /* |
2381 | 2381 | * RFC1123Date = wkday "," SP date1 SP time SP "GMT" |
2382 | 2382 | * RFC850Date = weekday "," SP date2 SP time SP "GMT" |
2383 | 2383 | * ASCTimeDate = wkday SP date3 SP time SP 4DIGIT |
2384 | 2384 | * |
2385 | | * Each of these functions tries to parse the value and update the index to |
| 2385 | * Each of these functions tries to parse the value and update the index to |
2386 | 2386 | * the point it leaves off parsing. |
2387 | 2387 | */ |
… |
… |
|
2391 | 2391 | |
2392 | 2392 | /******************************************************************************/ |
2393 | | /* |
| 2393 | /* |
2394 | 2394 | * Parse an N-digit value |
2395 | 2395 | */ |
2396 | 2396 | |
2397 | | static int parseNDIGIT(char_t *buf, int digits, int *index) |
| 2397 | static int parseNDIGIT(char_t *buf, int digits, int *index) |
2398 | 2398 | { |
2399 | 2399 | int tmpIndex, returnValue; |
… |
… |
|
2407 | 2407 | } |
2408 | 2408 | *index = tmpIndex; |
2409 | | |
| 2409 | |
2410 | 2410 | return returnValue; |
2411 | 2411 | } |
… |
… |
|
2416 | 2416 | */ |
2417 | 2417 | |
2418 | | static int parseMonth(char_t *buf, int *index) |
2419 | | { |
2420 | | /* |
2421 | | * "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | |
| 2418 | static int parseMonth(char_t *buf, int *index) |
| 2419 | { |
| 2420 | /* |
| 2421 | * "Jan" | "Feb" | "Mar" | "Apr" | "May" | "Jun" | |
2422 | 2422 | * "Jul" | "Aug" | "Sep" | "Oct" | "Nov" | "Dec" |
2423 | 2423 | */ |
… |
… |
|
2494 | 2494 | |
2495 | 2495 | /******************************************************************************/ |
2496 | | /* |
| 2496 | /* |
2497 | 2497 | * Parse a year value (either 2 or 4 digits) |
2498 | 2498 | */ |
2499 | 2499 | |
2500 | | static int parseYear(char_t *buf, int *index) |
| 2500 | static int parseYear(char_t *buf, int *index) |
2501 | 2501 | { |
2502 | 2502 | int tmpIndex, returnValue; |
… |
… |
|
2511 | 2511 | if (returnValue >= 0) { |
2512 | 2512 | /* |
2513 | | * Assume that any year earlier than the start of the |
| 2513 | * Assume that any year earlier than the start of the |
2514 | 2514 | * epoch for time_t (1970) specifies 20xx |
2515 | 2515 | */ |
… |
… |
|
2528 | 2528 | |
2529 | 2529 | /******************************************************************************/ |
2530 | | /* |
2531 | | * The formulas used to build these functions are from "Calendrical Calculations", |
| 2530 | /* |
| 2531 | * The formulas used to build these functions are from "Calendrical Calculations", |
2532 | 2532 | * by Nachum Dershowitz, Edward M. Reingold, Cambridge University Press, 1997. |
2533 | 2533 | */ |
… |
… |
|
2542 | 2542 | */ |
2543 | 2543 | |
2544 | | int GregorianLeapYearP(long year) |
| 2544 | int GregorianLeapYearP(long year) |
2545 | 2545 | { |
2546 | 2546 | int result; |
2547 | 2547 | long tmp; |
2548 | | |
| 2548 | |
2549 | 2549 | tmp = year % 400; |
2550 | 2550 | |
… |
… |
|
2566 | 2566 | */ |
2567 | 2567 | |
2568 | | long FixedFromGregorian(long month, long day, long year) |
| 2568 | long FixedFromGregorian(long month, long day, long year) |
2569 | 2569 | { |
2570 | 2570 | long fixedDate; |
2571 | 2571 | |
2572 | | fixedDate = (long)(GregorianEpoch - 1 + 365 * (year - 1) + |
| 2572 | fixedDate = (long)(GregorianEpoch - 1 + 365 * (year - 1) + |
2573 | 2573 | floor((year - 1) / 4.0) - |
2574 | | floor((double)(year - 1) / 100.0) + |
2575 | | floor((double)(year - 1) / 400.0) + |
| 2574 | floor((double)(year - 1) / 100.0) + |
| 2575 | floor((double)(year - 1) / 400.0) + |
2576 | 2576 | floor((367.0 * ((double)month) - 362.0) / 12.0)); |
2577 | 2577 | |
… |
… |
|
2594 | 2594 | */ |
2595 | 2595 | |
2596 | | long GregorianYearFromFixed(long fixedDate) |
| 2596 | long GregorianYearFromFixed(long fixedDate) |
2597 | 2597 | { |
2598 | 2598 | long result, d0, n400, d1, n100, d2, n4, d3, n1, d4, year; |
… |
… |
|
2619 | 2619 | |
2620 | 2620 | /******************************************************************************/ |
2621 | | /* |
| 2621 | /* |
2622 | 2622 | * Returns the Gregorian date from a fixed date |
2623 | 2623 | * (not needed for this use, but included for completeness |
… |
… |
|
2625 | 2625 | |
2626 | 2626 | #if 0 |
2627 | | GregorianFromFixed(long fixedDate, long *month, long *day, long *year) |
| 2627 | GregorianFromFixed(long fixedDate, long *month, long *day, long *year) |
2628 | 2628 | { |
2629 | 2629 | long priorDays, correction; |
… |
… |
|
2646 | 2646 | |
2647 | 2647 | /******************************************************************************/ |
2648 | | /* |
| 2648 | /* |
2649 | 2649 | * Returns the difference between two Gregorian dates |
2650 | 2650 | */ |
2651 | 2651 | |
2652 | 2652 | long GregorianDateDifference( long month1, long day1, long year1, |
2653 | | long month2, long day2, long year2) |
2654 | | { |
2655 | | return FixedFromGregorian(month2, day2, year2) - |
| 2653 | long month2, long day2, long year2) |
| 2654 | { |
| 2655 | return FixedFromGregorian(month2, day2, year2) - |
2656 | 2656 | FixedFromGregorian(month1, day1, year1); |
2657 | 2657 | } |
… |
… |
|
2665 | 2665 | #define SECONDS_PER_DAY 24*60*60 |
2666 | 2666 | |
2667 | | static int parseTime(char_t *buf, int *index) |
2668 | | { |
2669 | | /* |
| 2667 | static int parseTime(char_t *buf, int *index) |
| 2668 | { |
| 2669 | /* |
2670 | 2670 | * Format of buf is - 2DIGIT ":" 2DIGIT ":" 2DIGIT |
2671 | 2671 | */ |
… |
… |
|
2702 | 2702 | */ |
2703 | 2703 | |
2704 | | static time_t dateToTimet(int year, int month, int day) |
| 2704 | static time_t dateToTimet(int year, int month, int day) |
2705 | 2705 | { |
2706 | 2706 | long dayDifference; |
2707 | 2707 | |
2708 | | /* |
2709 | | * Bug fix by Jeff Reeder (Jun 14, 2002): The 'month' parameter is |
2710 | | * numbered from 0 (Jan == 0), but FixedFromGregorian() takes |
2711 | | * months numbered from 1 (January == 1). We need to add 1 |
2712 | | * to the month |
| 2708 | /* |
| 2709 | * Bug fix by Jeff Reeder (Jun 14, 2002): The 'month' parameter is |
| 2710 | * numbered from 0 (Jan == 0), but FixedFromGregorian() takes |
| 2711 | * months numbered from 1 (January == 1). We need to add 1 |
| 2712 | * to the month |
2713 | 2713 | */ |
2714 | | dayDifference = FixedFromGregorian(month + 1, day, year) - |
| 2714 | dayDifference = FixedFromGregorian(month + 1, day, year) - |
2715 | 2715 | FixedFromGregorian(1, 1, 1970); |
2716 | 2716 | |
… |
… |
|
2724 | 2724 | */ |
2725 | 2725 | |
2726 | | static time_t parseDate1or2(char_t *buf, int *index) |
2727 | | { |
2728 | | /* |
| 2726 | static time_t parseDate1or2(char_t *buf, int *index) |
| 2727 | { |
| 2728 | /* |
2729 | 2729 | * Format of buf is either |
2730 | 2730 | * 2DIGIT SP month SP 4DIGIT |
… |
… |
|
2741 | 2741 | |
2742 | 2742 | if (buf[tmpIndex] == T(',')) { |
2743 | | /* |
2744 | | * Skip over the ", " |
2745 | | */ |
2746 | | tmpIndex += 2; |
| 2743 | /* |
| 2744 | * Skip over the ", " |
| 2745 | */ |
| 2746 | tmpIndex += 2; |
2747 | 2747 | |
2748 | 2748 | dayValue = parseNDIGIT(buf, 2, &tmpIndex); |
… |
… |
|
2751 | 2751 | * Skip over the space or hyphen |
2752 | 2752 | */ |
2753 | | tmpIndex++; |
| 2753 | tmpIndex++; |
2754 | 2754 | monthValue = parseMonth(buf, &tmpIndex); |
2755 | 2755 | if (monthValue >= 0) { |
… |
… |
|
2757 | 2757 | * Skip over the space or hyphen |
2758 | 2758 | */ |
2759 | | tmpIndex++; |
| 2759 | tmpIndex++; |
2760 | 2760 | yearValue = parseYear(buf, &tmpIndex); |
2761 | 2761 | } |
… |
… |
|
2766 | 2766 | (yearValue >= 0)) { |
2767 | 2767 | if (yearValue < 1970) { |
2768 | | /* |
2769 | | * Allow for Microsoft IE's year 1601 dates |
2770 | | */ |
2771 | | returnValue = 0; |
| 2768 | /* |
| 2769 | * Allow for Microsoft IE's year 1601 dates |
| 2770 | */ |
| 2771 | returnValue = 0; |
2772 | 2772 | } else { |
2773 | 2773 | returnValue = dateToTimet(yearValue, monthValue, dayValue); |
… |
… |
|
2776 | 2776 | } |
2777 | 2777 | } |
2778 | | |
| 2778 | |
2779 | 2779 | return returnValue; |
2780 | 2780 | } |
… |
… |
|
2785 | 2785 | */ |
2786 | 2786 | |
2787 | | static time_t parseDate3Time(char_t *buf, int *index) |
| 2787 | static time_t parseDate3Time(char_t *buf, int *index) |
2788 | 2788 | { |
2789 | 2789 | /* |
… |
… |
|
2800 | 2800 | monthValue = parseMonth(buf, &tmpIndex); |
2801 | 2801 | if (monthValue >= 0) { |
2802 | | /* |
2803 | | * Skip over the space |
2804 | | */ |
2805 | | tmpIndex++; |
| 2802 | /* |
| 2803 | * Skip over the space |
| 2804 | */ |
| 2805 | tmpIndex++; |
2806 | 2806 | if (buf[tmpIndex] == T(' ')) { |
2807 | 2807 | /* |
2808 | | * Skip over this space too |
2809 | | */ |
2810 | | tmpIndex++; |
| 2808 | * Skip over this space too |
| 2809 | */ |
| 2810 | tmpIndex++; |
2811 | 2811 | dayValue = parseNDIGIT(buf, 1, &tmpIndex); |
2812 | 2812 | } else { |
2813 | 2813 | dayValue = parseNDIGIT(buf, 2, &tmpIndex); |
2814 | 2814 | } |
2815 | | /* |
| 2815 | /* |
2816 | 2816 | * Now get the time and time SP 4DIGIT |
2817 | 2817 | */ |
2818 | 2818 | timeValue = parseTime(buf, &tmpIndex); |
2819 | 2819 | if (timeValue >= 0) { |
2820 | | /* |
| 2820 | /* |
2821 | 2821 | * Now grab the 4DIGIT year value |
2822 | 2822 | */ |
… |
… |
|
2832 | 2832 | *index = tmpIndex; |
2833 | 2833 | } |
2834 | | |
| 2834 | |
2835 | 2835 | return returnValue; |
2836 | 2836 | } |
… |
… |
|
2841 | 2841 | * Although this looks like a trivial function, I found I was replicating the implementation |
2842 | 2842 | * seven times in the parseWeekday function. In the interests of minimizing code size |
2843 | | * and redundancy, it is broken out into a separate function. The cost of an extra |
| 2843 | * and redundancy, it is broken out into a separate function. The cost of an extra |
2844 | 2844 | * function call I can live with given that it should only be called once per HTTP request. |
2845 | 2845 | */ |
2846 | 2846 | |
2847 | | static int bufferIndexIncrementGivenNTest(char_t *buf, int testIndex, char_t testChar, |
2848 | | int foundIncrement, int notfoundIncrement) |
| 2847 | static int bufferIndexIncrementGivenNTest(char_t *buf, int testIndex, char_t testChar, |
| 2848 | int foundIncrement, int notfoundIncrement) |
2849 | 2849 | { |
2850 | 2850 | if (buf[testIndex] == testChar) { |
… |
… |
|
2860 | 2860 | */ |
2861 | 2861 | |
2862 | | static int parseWeekday(char_t *buf, int *index) |
2863 | | { |
2864 | | /* |
| 2862 | static int parseWeekday(char_t *buf, int *index) |
| 2863 | { |
| 2864 | /* |
2865 | 2865 | * Format of buf is either |
2866 | 2866 | * "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | "Sun" |
… |
… |
|
2940 | 2940 | timeValue = parseTime(cmd, &index); |
2941 | 2941 | if (timeValue >= 0) { |
2942 | | /* |
| 2942 | /* |
2943 | 2943 | * Now match up that "GMT" string for completeness |
2944 | 2944 | * Compute the final value if there were no problems in the parse |
… |
… |
|
2951 | 2951 | } |
2952 | 2952 | } else { |
2953 | | /* |
| 2953 | /* |
2954 | 2954 | * Try the other form - wkday SP date3 SP time SP 4DIGIT |
2955 | 2955 | */ |
-
r0893220
|
r0a7278e
|
|
1 | | /* |
| 1 | /* |
2 | 2 | * webs.h -- GoAhead Web public header |
3 | 3 | * |
… |
… |
|
14 | 14 | /******************************** Description *********************************/ |
15 | 15 | |
16 | | /* |
| 16 | /* |
17 | 17 | * GoAhead Web Server header. This defines the Web public APIs. |
18 | 18 | * Include this header for files that contain ASP or Form procedures. |
… |
… |
|
46 | 46 | #define CGI_BIN T("cgi-bin") |
47 | 47 | |
48 | | /* |
| 48 | /* |
49 | 49 | * Request flags. Also returned by websGetRequestFlags(). |
50 | 50 | */ |
51 | | #define WEBS_LOCAL_PAGE 0x1 /* Request for local webs page */ |
| 51 | #define WEBS_LOCAL_PAGE 0x1 /* Request for local webs page */ |
52 | 52 | #define WEBS_KEEP_ALIVE 0x2 /* HTTP/1.1 keep alive */ |
53 | 53 | #define WEBS_DONT_USE_CACHE 0x4 /* Not implemented cache support */ |
… |
… |
|
56 | 56 | #define WEBS_POST_REQUEST 0x20 /* Post request operation */ |
57 | 57 | #define WEBS_LOCAL_REQUEST 0x40 /* Request from this system */ |
58 | | #define WEBS_HOME_PAGE 0x80 /* Request for the home page */ |
59 | | #define WEBS_ASP 0x100 /* ASP request */ |
| 58 | #define WEBS_HOME_PAGE 0x80 /* Request for the home page */ |
| 59 | #define WEBS_ASP 0x100 /* ASP request */ |
60 | 60 | #define WEBS_HEAD_REQUEST 0x200 /* Head request */ |
61 | 61 | #define WEBS_CLEN 0x400 /* Request had a content length */ |
… |
… |
|
75 | 75 | #define WEBS_HANDLER_LAST 0x2 /* Process this handler last */ |
76 | 76 | |
77 | | /* |
| 77 | /* |
78 | 78 | * Per socket connection webs structure |
79 | 79 | */ |
… |
… |
|
134 | 134 | /******************************** Prototypes **********************************/ |
135 | 135 | extern int websAccept(int sid, char *ipaddr, int port, int listenSid); |
136 | | extern int websAspDefine(char_t *name, |
| 136 | extern int websAspDefine(char_t *name, |
137 | 137 | int (*fn)(int ejid, webs_t wp, int argc, char_t **argv)); |
138 | 138 | extern int websAspRequest(webs_t wp, char_t *lpath); |
… |
… |
|
146 | 146 | extern char_t *websErrorMsg(int code); |
147 | 147 | extern void websFooter(webs_t wp); |
148 | | extern int websFormDefine(char_t *name, void (*fn)(webs_t wp, |
| 148 | extern int websFormDefine(char_t *name, void (*fn)(webs_t wp, |
149 | 149 | char_t *path, char_t *query)); |
150 | 150 | extern char_t *websGetDefaultDir(void); |
… |
… |
|
175 | 175 | extern void websRedirect(webs_t wp, char_t *url); |
176 | 176 | extern void websSecurityDelete(void); |
177 | | extern int websSecurityHandler(webs_t wp, char_t *urlPrefix, |
178 | | char_t *webDir, int arg, char_t *url, char_t *path, |
| 177 | extern int websSecurityHandler(webs_t wp, char_t *urlPrefix, |
| 178 | char_t *webDir, int arg, char_t *url, char_t *path, |
179 | 179 | char_t *query); |
180 | 180 | extern void websSetDefaultDir(char_t *dir); |
… |
… |
|
194 | 194 | extern int websTestVar(webs_t wp, char_t *var); |
195 | 195 | extern void websTimeoutCancel(webs_t wp); |
196 | | extern int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, |
197 | | int arg, int (*fn)(webs_t wp, char_t *urlPrefix, |
198 | | char_t *webDir, int arg, char_t *url, char_t *path, |
| 196 | extern int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, |
| 197 | int arg, int (*fn)(webs_t wp, char_t *urlPrefix, |
| 198 | char_t *webDir, int arg, char_t *url, char_t *path, |
199 | 199 | char_t *query), int flags); |
200 | 200 | extern int websUrlHandlerDelete(int (*fn)(webs_t wp, char_t *urlPrefix, |
201 | | char_t *webDir, int arg, char_t *url, char_t *path, |
| 201 | char_t *webDir, int arg, char_t *url, char_t *path, |
202 | 202 | char_t *query)); |
203 | 203 | extern int websUrlHandlerRequest(webs_t wp); |
204 | | extern int websUrlParse(char_t *url, char_t **buf, char_t **host, |
205 | | char_t **path, char_t **port, char_t **query, |
| 204 | extern int websUrlParse(char_t *url, char_t **buf, char_t **host, |
| 205 | char_t **path, char_t **port, char_t **query, |
206 | 206 | char_t **proto, char_t **tag, char_t **ext); |
207 | 207 | extern char_t *websUrlType(char_t *webs, char_t *buf, int charCnt); |
… |
… |
|
222 | 222 | |
223 | 223 | /* |
224 | | * Prototypes for functions available when running as part of the |
| 224 | * Prototypes for functions available when running as part of the |
225 | 225 | * GoAhead Embedded Management Framework (EMF) |
226 | 226 | */ |
-
r0893220
|
r0a7278e
|
|
66 | 66 | /*************************** Forward Declarations *****************************/ |
67 | 67 | |
68 | | static int websSSLSetCertStuff(SSL_CTX *ctx, |
69 | | char *cert_file, |
| 68 | static int websSSLSetCertStuff(SSL_CTX *ctx, |
| 69 | char *cert_file, |
70 | 70 | char *key_file); |
71 | 71 | static int websSSLVerifyCallback(int ok, X509_STORE_CTX *ctx); |
… |
… |
|
92 | 92 | char *certFile, *keyFile, *CApath, *CAfile; |
93 | 93 | SSL_METHOD *meth; |
94 | | |
| 94 | |
95 | 95 | /* |
96 | 96 | * Install and initialize the SSL library |
97 | 97 | */ |
98 | 98 | apps_startup(); |
99 | | trace(7, T("SSL: Initializing SSL\n")); |
| 99 | trace(7, T("SSL: Initializing SSL\n")); |
100 | 100 | |
101 | 101 | #ifdef SSLC |
… |
… |
|
118 | 118 | |
119 | 119 | if (sslctx == NULL) { |
120 | | trace(2, T("SSL: Unable to create SSL context!\n")); |
| 120 | trace(2, T("SSL: Unable to create SSL context!\n")); |
121 | 121 | return -1; |
122 | 122 | } |
… |
… |
|
136 | 136 | if ((!SSL_CTX_load_verify_locations(sslctx, CAfile, CApath)) || |
137 | 137 | (!SSL_CTX_set_default_verify_paths(sslctx))) { |
138 | | trace(2, T("SSL: Unable to set cert verification locations!\n")); |
| 138 | trace(2, T("SSL: Unable to set cert verification locations!\n")); |
139 | 139 | websSSLClose(); |
140 | 140 | return -1; |
… |
… |
|
169 | 169 | * Open the socket |
170 | 170 | */ |
171 | | sslListenSock = socketOpenConnection(NULL, SSL_PORT, |
| 171 | sslListenSock = socketOpenConnection(NULL, SSL_PORT, |
172 | 172 | websSSLAccept, SOCKET_BLOCK); |
173 | 173 | |
174 | 174 | if (sslListenSock < 0) { |
175 | | trace(2, T("SSL: Unable to open SSL socket on port <%d>!\n"), |
| 175 | trace(2, T("SSL: Unable to open SSL socket on port <%d>!\n"), |
176 | 176 | SSL_PORT); |
177 | 177 | return -1; |
… |
… |
|
198 | 198 | void websSSLClose() |
199 | 199 | { |
200 | | trace(7, T("SSL: Closing SSL\n")); |
| 200 | trace(7, T("SSL: Closing SSL\n")); |
201 | 201 | |
202 | 202 | if (sslctx != NULL) { |
… |
… |
|
246 | 246 | * to know for permitting administrative operations only for local access |
247 | 247 | */ |
248 | | if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 || |
249 | | gstrcmp(wp->ipaddr, websIpaddr) == 0 || |
| 248 | if (gstrcmp(wp->ipaddr, T("127.0.0.1")) == 0 || |
| 249 | gstrcmp(wp->ipaddr, websIpaddr) == 0 || |
250 | 250 | gstrcmp(wp->ipaddr, websHost) == 0) { |
251 | 251 | wp->flags |= WEBS_LOCAL_REQUEST; |
… |
… |
|
289 | 289 | if (mask & SOCKET_READABLE) { |
290 | 290 | websSSLReadEvent(wp); |
291 | | } |
| 291 | } |
292 | 292 | if (mask & SOCKET_WRITABLE) { |
293 | 293 | if (wp->writeSocket) { |
294 | 294 | (*wp->writeSocket)(wp); |
295 | 295 | } |
296 | | } |
| 296 | } |
297 | 297 | } |
298 | 298 | |
… |
… |
|
433 | 433 | |
434 | 434 | if (certFile != NULL) { |
435 | | if (SSL_CTX_use_certificate_file(ctx, certFile, |
| 435 | if (SSL_CTX_use_certificate_file(ctx, certFile, |
436 | 436 | SSL_FILETYPE_PEM) <= 0) { |
437 | 437 | trace(2, T("SSL: Unable to set certificate file <%s>\n"), |
438 | | certFile); |
| 438 | certFile); |
439 | 439 | return -1; |
440 | 440 | } |
… |
… |
|
446 | 446 | if (SSL_CTX_use_PrivateKey_file(ctx, keyFile, SSL_FILETYPE_PEM) <= 0) { |
447 | 447 | trace(2, T("SSL: Unable to set private key file <%s>\n"), |
448 | | keyFile); |
| 448 | keyFile); |
449 | 449 | return -1; |
450 | 450 | } |
451 | 451 | |
452 | | /* |
| 452 | /* |
453 | 453 | * Now we know that a key and cert have been set against |
454 | | * the SSL context |
| 454 | * the SSL context |
455 | 455 | */ |
456 | 456 | if (!SSL_CTX_check_private_key(ctx)) { |
457 | 457 | trace(2, T("SSL: Check of private key file <%s> FAILED!\n"), |
458 | | keyFile); |
| 458 | keyFile); |
459 | 459 | return -1; |
460 | 460 | } |
… |
… |
|
478 | 478 | } |
479 | 479 | |
480 | | if (SSL_CTX_use_certificate_file(sslctx, certFile, |
| 480 | if (SSL_CTX_use_certificate_file(sslctx, certFile, |
481 | 481 | SSL_FILETYPE_PEM) <= 0) { |
482 | 482 | return -1; |
483 | 483 | } |
484 | | /* |
| 484 | /* |
485 | 485 | * Confirm that the certificate and the private key jive. |
486 | 486 | */ |
… |
… |
|
509 | 509 | return -1; |
510 | 510 | } |
511 | | /* |
| 511 | /* |
512 | 512 | * Confirm that the certificate and the private key jive. |
513 | 513 | */ |
… |
… |
|
549 | 549 | /******************************************************************************/ |
550 | 550 | /* |
551 | | * Free SSL resources |
| 551 | * Free SSL resources |
552 | 552 | */ |
553 | 553 | |
… |
… |
|
558 | 558 | } |
559 | 559 | |
560 | | /* |
| 560 | /* |
561 | 561 | * Make sure we re-use sessions |
562 | 562 | */ |
… |
… |
|
585 | 585 | if ((wsp == NULL) || (wsp->bio == NULL)) { |
586 | 586 | return -1; |
587 | | } |
| 587 | } |
588 | 588 | |
589 | 589 | return BIO_eof(wsp->bio); |
… |
… |
|
602 | 602 | if ((wsp == NULL) || (wsp->bio == NULL)) { |
603 | 603 | return -1; |
604 | | } |
| 604 | } |
605 | 605 | |
606 | 606 | return BIO_read(wsp->bio, buf, len); |
… |
… |
|
627 | 627 | if ((wsp == NULL) || (wsp->bio == NULL)) { |
628 | 628 | return -1; |
629 | | } |
| 629 | } |
630 | 630 | |
631 | 631 | while (1) { |
… |
… |
|
634 | 634 | return rc; |
635 | 635 | } |
636 | | |
| 636 | |
637 | 637 | if (rc == 0) { |
638 | 638 | /* |
… |
… |
|
656 | 656 | } else if (c == '\r') { |
657 | 657 | continue; |
658 | | } |
| 658 | } |
659 | 659 | /* |
660 | 660 | * Append character to buf |
… |
… |
|
683 | 683 | if ((wsp == NULL) || (wsp->bio == NULL)) { |
684 | 684 | return -1; |
685 | | } |
| 685 | } |
686 | 686 | |
687 | 687 | return BIO_write(wsp->bio, buf, len); |
… |
… |
|
699 | 699 | if ((wsp == NULL) || (wsp->bio == NULL)) { |
700 | 700 | return -1; |
701 | | } |
| 701 | } |
702 | 702 | |
703 | 703 | return BIO_flush(wsp->bio); |
-
r0893220
|
r0a7278e
|
|
1 | | /* |
| 1 | /* |
2 | 2 | * websSSL.h -- SSL Patch header |
3 | 3 | * |
… |
… |
|
14 | 14 | /******************************** Description *********************************/ |
15 | 15 | |
16 | | /* |
17 | | * Header file for the GoAhead Patch for SSL. This defines the interface to |
| 16 | /* |
| 17 | * Header file for the GoAhead Patch for SSL. This defines the interface to |
18 | 18 | * integrate SSL into the GoAhead Webserver. |
19 | 19 | */ |
-
r0893220
|
r0a7278e
|
|
75 | 75 | /*****************************************************************************/ |
76 | 76 | /* |
77 | | * Convenience call to websMD5binary |
| 77 | * Convenience call to websMD5binary |
78 | 78 | * (Performs char_t to char conversion and back) |
79 | 79 | */ |
… |
… |
|
116 | 116 | /******************************************************************************/ |
117 | 117 | /* |
118 | | * Get a Nonce value for passing along to the client. This function |
119 | | * composes the string "RANDOMKEY:timestamp:myrealm" and |
120 | | * calculates the MD5 digest placing it in output. |
| 118 | * Get a Nonce value for passing along to the client. This function |
| 119 | * composes the string "RANDOMKEY:timestamp:myrealm" and |
| 120 | * calculates the MD5 digest placing it in output. |
121 | 121 | */ |
122 | 122 | |
… |
… |
|
142 | 142 | #ifdef DIGEST_ACCESS_SUPPORT |
143 | 143 | fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime), |
144 | | wp->realm); |
| 144 | wp->realm); |
145 | 145 | #else |
146 | | fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime), |
147 | | RANDOMKEY); |
| 146 | fmtAlloc(&prenonce, 256, T("%s:%s:%s"), RANDOMKEY, gasctime(newtime), |
| 147 | RANDOMKEY); |
148 | 148 | #endif |
149 | 149 | a_assert(prenonce); |
… |
… |
|
219 | 219 | fmtAlloc(&preDigest, 255, T("%s:%s:%s"), a1prime, wp->nonce, a2prime); |
220 | 220 | } else { |
221 | | fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"), |
222 | | a1prime, |
| 221 | fmtAlloc(&preDigest, 255, T("%s:%s:%s:%s:%s:%s"), |
| 222 | a1prime, |
223 | 223 | wp->nonce, |
224 | 224 | wp->nc, |
-
r0893220
|
r0a7278e
|
|
1 | | /* |
| 1 | /* |
2 | 2 | * websda.h -- GoAhead Digest Access Authentication public header |
3 | 3 | * |
… |
… |
|
14 | 14 | /******************************** Description *********************************/ |
15 | 15 | |
16 | | /* |
17 | | * GoAhead Digest Access Authentication header. This defines the Digest |
18 | | * access authentication public APIs. Include this header for files that |
| 16 | /* |
| 17 | * GoAhead Digest Access Authentication header. This defines the Digest |
| 18 | * access authentication public APIs. Include this header for files that |
19 | 19 | * use DAA functions |
20 | 20 | */ |
-
r0893220
|
r0a7278e
|
|
148 | 148 | sched_t *s; |
149 | 149 | |
150 | | if (sched == NULL || schedid == -1 || schedid >= schedMax || |
| 150 | if (sched == NULL || schedid == -1 || schedid >= schedMax || |
151 | 151 | (s = sched[schedid]) == NULL) { |
152 | 152 | return; |
… |
… |
|
161 | 161 | sched_t *s; |
162 | 162 | |
163 | | if (sched == NULL || schedid == -1 || schedid >= schedMax || |
| 163 | if (sched == NULL || schedid == -1 || schedid >= schedMax || |
164 | 164 | (s = sched[schedid]) == NULL) { |
165 | 165 | return; |
… |
… |
|
178 | 178 | sched_t *s; |
179 | 179 | int schedid; |
180 | | static int next = 0; |
| 180 | static int next = 0; |
181 | 181 | |
182 | 182 | /* |
… |
… |
|
207 | 207 | if (schedid == next) { |
208 | 208 | /* |
209 | | * We've gone all the way through the queue without finding |
| 209 | * We've gone all the way through the queue without finding |
210 | 210 | * anything to do so just return. |
211 | 211 | */ |
-
r0893220
|
r0a7278e
|
|
1 | | /* |
| 1 | /* |
2 | 2 | * wsIntrn.h -- Internal GoAhead Web server header |
3 | 3 | * |
… |
… |
|
8 | 8 | * $Id$ |
9 | 9 | */ |
10 | | |
| 10 | |
11 | 11 | #ifndef _h_WEBS_INTERNAL |
12 | 12 | #define _h_WEBS_INTERNAL 1 |
… |
… |
|
14 | 14 | /******************************** Description *********************************/ |
15 | 15 | |
16 | | /* |
| 16 | /* |
17 | 17 | * Internal GoAhead Web Server header. This defines the Web private APIs |
18 | 18 | * Include this header when you want to create URL handlers. |
… |
… |
|
22 | 22 | |
23 | 23 | /* |
24 | | * Define this to enable logging of web accesses to a file |
| 24 | * Define this to enable logging of web accesses to a file |
25 | 25 | * #define WEBS_LOG_SUPPORT 1 |
26 | 26 | * |
… |
… |
|
130 | 130 | |
131 | 131 | /********************************** Defines ***********************************/ |
132 | | /* |
| 132 | /* |
133 | 133 | * Read handler flags and state |
134 | 134 | */ |
… |
… |
|
148 | 148 | * URL handler structure. Stores the leading URL path and the handler |
149 | 149 | * function to call when the URL path is seen. |
150 | | */ |
151 | | typedef struct { |
152 | | int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, |
153 | | char_t *url, char_t *path, |
| 150 | */ |
| 151 | typedef struct { |
| 152 | int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg, |
| 153 | char_t *url, char_t *path, |
154 | 154 | char_t *query); /* Callback URL handler function */ |
155 | 155 | char_t *webDir; /* Web directory if required */ |
… |
… |
|
160 | 160 | } websUrlHandlerType; |
161 | 161 | |
162 | | /* |
| 162 | /* |
163 | 163 | * Webs statistics |
164 | 164 | */ |
… |
… |
|
180 | 180 | extern websStatsType websStats; /* Web access stats */ |
181 | 181 | |
182 | | /* |
| 182 | /* |
183 | 183 | * Error code list |
184 | 184 | */ |
… |
… |
|
188 | 188 | } websErrorType; |
189 | 189 | |
190 | | /* |
| 190 | /* |
191 | 191 | * Mime type list |
192 | 192 | */ |
… |
… |
|
245 | 245 | extern int websAspWrite(int ejid, webs_t wp, int argc, char_t **argv); |
246 | 246 | extern void websDefaultClose(void); |
247 | | extern int websDefaultHandler(webs_t wp, char_t *urlPrefix, |
248 | | char_t *webDir, int arg, char_t *url, char_t *path, |
| 247 | extern int websDefaultHandler(webs_t wp, char_t *urlPrefix, |
| 248 | char_t *webDir, int arg, char_t *url, char_t *path, |
249 | 249 | char_t *query); |
250 | 250 | extern int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, |
… |
… |
|
259 | 259 | char_t **envp, char_t *stdIn, char_t *stdOut); |
260 | 260 | extern int websOpen(int sid); |
261 | | extern void websResponse(webs_t wp, int code, char_t *msg, |
| 261 | extern void websResponse(webs_t wp, int code, char_t *msg, |
262 | 262 | char_t *redirect); |
263 | 263 | extern int websJavaScriptEval(webs_t wp, char_t *script); |
… |
… |
|
277 | 277 | extern int websRomPageStat(char_t *path, websStatType *sbuf); |
278 | 278 | extern long websRomPageSeek(webs_t wp, long offset, int origin); |
279 | | extern void websSetRequestSocketHandler(webs_t wp, int mask, |
| 279 | extern void websSetRequestSocketHandler(webs_t wp, int mask, |
280 | 280 | void (*fn)(webs_t wp)); |
281 | 281 | extern int websSolutionHandler(webs_t wp, char_t *urlPrefix, |
282 | | char_t *webDir, int arg, char_t *url, char_t *path, |
| 282 | char_t *webDir, int arg, char_t *url, char_t *path, |
283 | 283 | char_t *query); |
284 | 284 | extern void websUrlHandlerClose(void); |
… |
… |
|
291 | 291 | |
292 | 292 | /* |
293 | | * Prototypes for functions available when running as part of the |
| 293 | * Prototypes for functions available when running as part of the |
294 | 294 | * GoAhead Embedded Management Framework (EMF) |
295 | 295 | */ |
-
r0893220
|
r0a7278e
|
|
1 | | /** |
| 1 | /** |
2 | 2 | * @file libfs/devfs/devfs.h |
3 | 3 | * |
… |
… |
|
19 | 19 | */ |
20 | 20 | |
21 | | typedef struct |
| 21 | typedef struct |
22 | 22 | { |
23 | 23 | /** This member points to device name which is a null-terminated string */ |
… |
… |
|
45 | 45 | /** |
46 | 46 | * The following defines the device table size. This values |
47 | | * is configured during application configuration time by |
| 47 | * is configured during application configuration time by |
48 | 48 | * the user. The default value is set to 4. |
49 | 49 | */ |
… |
… |
|
57 | 57 | */ |
58 | 58 | |
59 | | extern rtems_filesystem_operations_table devFS_ops; |
| 59 | extern rtems_filesystem_operations_table devFS_ops; |
60 | 60 | |
61 | 61 | /** |
… |
… |
|
64 | 64 | */ |
65 | 65 | |
66 | | extern rtems_filesystem_file_handlers_r devFS_file_handlers; |
| 66 | extern rtems_filesystem_file_handlers_r devFS_file_handlers; |
67 | 67 | |
68 | 68 | |
… |
… |
|
70 | 70 | * This handler maps open operation to rtems_io_open. |
71 | 71 | * @param iop This is the RTEMS's internal representation of file. |
72 | | * @param pathname a null-terminated string that starts with /dev. |
| 72 | * @param pathname a null-terminated string that starts with /dev. |
73 | 73 | * @param flag access flags |
74 | 74 | * @param mode access mode |
… |
… |
|
167 | 167 | /** |
168 | 168 | * This routine is invoked upon determination of a node type. |
169 | | * Since this is a device-only filesystem, so there is only |
| 169 | * Since this is a device-only filesystem, so there is only |
170 | 170 | * one node type in the system. |
171 | | * |
172 | | * @param pathloc contains filesytem access information, this |
| 171 | * |
| 172 | * @param pathloc contains filesytem access information, this |
173 | 173 | * parameter is ignored |
174 | 174 | * @retval always returns RTEMS_FILESYSTEM_DEVICE |
… |
… |
|
183 | 183 | /** |
184 | 184 | * This routine is invoked to determine if 'pathname' exists. |
185 | | * This routine first check access flags, then it searches |
| 185 | * This routine first check access flags, then it searches |
186 | 186 | * the device table to get the information. |
187 | | * |
| 187 | * |
188 | 188 | * @param pathname device name to be searched |
189 | 189 | * @param flags access flags |
190 | 190 | * @param pathloc contains filesystem access information |
191 | | * @retval upon success(pathname exists), this routines |
192 | | * returns 0; if 'flag' is invalid, it returns -1 and errno |
| 191 | * @retval upon success(pathname exists), this routines |
| 192 | * returns 0; if 'flag' is invalid, it returns -1 and errno |
193 | 193 | * is set to EIO; otherwise, it returns -1 and errno is set to ENOENT |
194 | 194 | */ |
… |
… |
|
203 | 203 | |
204 | 204 | /** |
205 | | * This routine is given a path to evaluate and a valid start |
| 205 | * This routine is given a path to evaluate and a valid start |
206 | 206 | * location. It is responsible for finding the parent node for |
207 | 207 | * a requested make command, setting pathloc information to |
208 | | * identify the parent node, and setting the name pointer to |
209 | | * the first character of the name of the new node. In device |
| 208 | * identify the parent node, and setting the name pointer to |
| 209 | * the first character of the name of the new node. In device |
210 | 210 | * only filesystem, devices do not has a tree hierarchy, there |
211 | | * are no parent-child relationship. So this routine is rather |
| 211 | * are no parent-child relationship. So this routine is rather |
212 | 212 | * simple, it just set *name to path and returns |
213 | 213 | * |
214 | 214 | * @param path device path to be evaluated |
215 | | * @param pathloc contains filesystem access information, this |
| 215 | * @param pathloc contains filesystem access information, this |
216 | 216 | * parameter is ignored |
217 | | * @param name |
| 217 | * @param name |
218 | 218 | * @retval always returns 0 |
219 | 219 | */ |
… |
… |
|
229 | 229 | /** |
230 | 230 | * This routine is invoked upon registration of a new device |
231 | | * file. It is responsible for creating a item in the main |
232 | | * device table. This routine searches the device table in |
233 | | * sequential order, when found a empty slot, it fills the slot |
| 231 | * file. It is responsible for creating a item in the main |
| 232 | * device table. This routine searches the device table in |
| 233 | * sequential order, when found a empty slot, it fills the slot |
234 | 234 | * with proper values. |
235 | 235 | * |
… |
… |
|
240 | 240 | * @retval upon success, this routine returns 0; if 'path' |
241 | 241 | * already exist, it returns -1 and errno is set to EEXIST; |
242 | | * if device table is full, it returns -1 and errno is set |
| 242 | * if device table is full, it returns -1 and errno is set |
243 | 243 | * to ENOMEM |
244 | 244 | */ |
… |
… |
|
246 | 246 | extern int devFS_mknod( |
247 | 247 | const char *path, |
248 | | mode_t mode, |
249 | | dev_t dev, |
250 | | rtems_filesystem_location_info_t *pathloc |
| 248 | mode_t mode, |
| 249 | dev_t dev, |
| 250 | rtems_filesystem_location_info_t *pathloc |
251 | 251 | ); |
252 | 252 | |
… |
… |
|
257 | 257 | * initializing it to a known state, and set device file operation |
258 | 258 | * handlers. After this, the device-only filesytem is ready for use |
259 | | * |
| 259 | * |
260 | 260 | * @param temp_mt_entry |
261 | 261 | * @retval upon success, this routine returns 0; otherwise it returns |
262 | | * -1 and errno is set to proper value. The only error is when malloc |
| 262 | * -1 and errno is set to proper value. The only error is when malloc |
263 | 263 | * failed, and errno is set to NOMEM. |
264 | 264 | */ |
… |
… |
|
273 | 273 | * prints out their detail information. For example, on one system, |
274 | 274 | * devFS_show will print out following message: |
275 | | * |
| 275 | * |
276 | 276 | * /dev/console 0 0 |
277 | 277 | * /dev/clock 1 0 |
278 | 278 | * /dev/tty0 0 0 |
279 | 279 | * /flash 2 0 |
280 | | * |
281 | | * This routine is intended for debugging, and can be used by shell |
| 280 | * |
| 281 | * This routine is intended for debugging, and can be used by shell |
282 | 282 | * program to provide user with the system information. |
283 | | * |
| 283 | * |
284 | 284 | * @param none |
285 | 285 | * @retval 0 |
-
r0893220
|
r0a7278e
|
|
17 | 17 | #include "devfs.h" |
18 | 18 | |
19 | | rtems_filesystem_operations_table devFS_ops = |
| 19 | rtems_filesystem_operations_table devFS_ops = |
20 | 20 | { |
21 | 21 | devFS_evaluate_path, |
… |
… |
|
39 | 39 | |
40 | 40 | |
41 | | rtems_filesystem_file_handlers_r devFS_file_handlers = |
| 41 | rtems_filesystem_file_handlers_r devFS_file_handlers = |
42 | 42 | { |
43 | 43 | devFS_open, |
… |
… |
|
75 | 75 | |
76 | 76 | memset( |
77 | | device_name_table, 0, |
| 77 | device_name_table, 0, |
78 | 78 | sizeof( rtems_device_name_t ) * ( rtems_device_table_size ) |
79 | 79 | ); |
-
r0893220
|
r0a7278e
|
|
23 | 23 | int devFS_mknod( |
24 | 24 | const char *path, |
25 | | mode_t mode, |
26 | | dev_t dev, |
27 | | rtems_filesystem_location_info_t *pathloc |
| 25 | mode_t mode, |
| 26 | dev_t dev, |
| 27 | rtems_filesystem_location_info_t *pathloc |
28 | 28 | ) |
29 | 29 | { |
… |
… |
|
36 | 36 | |
37 | 37 | /* |
38 | | * This is a special case. In rtems_filesystem_initialize, |
39 | | * a special device '/dev' will be created. We check this |
40 | | * condition and do not create the '/dev' and the 'path' |
| 38 | * This is a special case. In rtems_filesystem_initialize, |
| 39 | * a special device '/dev' will be created. We check this |
| 40 | * condition and do not create the '/dev' and the 'path' |
41 | 41 | * actually passed in is 'dev', not '/dev'. Just return 0 to |
42 | 42 | * indicate we are OK. |
43 | 43 | */ |
44 | 44 | |
45 | | if ((path[0] == 'd') && (path[1] == 'e') && |
| 45 | if ((path[0] == 'd') && (path[1] == 'e') && |
46 | 46 | (path[2] == 'v') && (path[3] == '\0')) |
47 | 47 | return 0; |
-
r0893220
|
r0a7278e
|
|
18 | 18 | { |
19 | 19 | /* |
20 | | * There is only one type of node: device |
| 20 | * There is only one type of node: device |
21 | 21 | */ |
22 | 22 | |
-
r0893220
|
r0a7278e
|
|
27 | 27 | for (i = 0; i < rtems_device_table_size; i++){ |
28 | 28 | if (device_name_table[i].device_name){ |
29 | | printk("/%s %d %d\n", device_name_table[i].device_name, |
| 29 | printk("/%s %d %d\n", device_name_table[i].device_name, |
30 | 30 | device_name_table[i].major, device_name_table[i].minor); |
31 | 31 | } |
-
r0893220
|
r0a7278e
|
|
4 | 4 | * Application interface to MSDOS filesystem. |
5 | 5 | */ |
6 | | |
| 6 | |
7 | 7 | /* |
8 | 8 | * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia |
… |
… |
|
15 | 15 | * @(#) $Id$ |
16 | 16 | */ |
17 | | |
| 17 | |
18 | 18 | #ifndef _RTEMS_DOSFS_H |
19 | 19 | #define _RTEMS_DOSFS_H |
-
r0893220
|
r0a7278e
|
|
282 | 282 | return fat_buf_release(fs_info); |
283 | 283 | } |
284 | | |
| 284 | |
285 | 285 | /* fat_cluster_read -- |
286 | 286 | * wrapper for reading a whole cluster at once |
… |
… |
|
399 | 399 | /* Evaluate boot record */ |
400 | 400 | vol->bps = FAT_GET_BR_BYTES_PER_SECTOR(boot_rec); |
401 | | |
402 | | if ( (vol->bps != 512) && |
403 | | (vol->bps != 1024) && |
| 401 | |
| 402 | if ( (vol->bps != 512) && |
| 403 | (vol->bps != 1024) && |
404 | 404 | (vol->bps != 2048) && |
405 | 405 | (vol->bps != 4096)) |
… |
… |
|
444 | 444 | |
445 | 445 | vol->rdir_entrs = FAT_GET_BR_FILES_PER_ROOT_DIR(boot_rec); |
446 | | |
| 446 | |
447 | 447 | /* calculate the count of sectors occupied by the root directory */ |
448 | 448 | vol->rdir_secs = ((vol->rdir_entrs * FAT_DIRENTRY_SIZE) + (vol->bps - 1)) / |
… |
… |
|
455 | 455 | else |
456 | 456 | vol->fat_length = FAT_GET_BR_SECTORS_PER_FAT32(boot_rec); |
457 | | |
458 | | vol->data_fsec = vol->fat_loc + vol->fats * vol->fat_length + |
| 457 | |
| 458 | vol->data_fsec = vol->fat_loc + vol->fats * vol->fat_length + |
459 | 459 | vol->rdir_secs; |
460 | 460 | |
461 | 461 | /* for FAT12/16 root dir starts at(sector) */ |
462 | 462 | vol->rdir_loc = vol->fat_loc + vol->fats * vol->fat_length; |
463 | | |
| 463 | |
464 | 464 | if ( (FAT_GET_BR_TOTAL_SECTORS_NUM16(boot_rec)) != 0) |
465 | 465 | vol->tot_secs = FAT_GET_BR_TOTAL_SECTORS_NUM16(boot_rec); |
466 | 466 | else |
467 | 467 | vol->tot_secs = FAT_GET_BR_TOTAL_SECTORS_NUM32(boot_rec); |
468 | | |
| 468 | |
469 | 469 | data_secs = vol->tot_secs - vol->data_fsec; |
470 | 470 | |
… |
… |
|
497 | 497 | { |
498 | 498 | vol->rdir_cl = FAT_GET_BR_FAT32_ROOT_CLUSTER(boot_rec); |
499 | | |
| 499 | |
500 | 500 | vol->mirror = FAT_GET_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_MIRROR; |
501 | 501 | if (vol->mirror) |
… |
… |
|
518 | 518 | rtems_disk_release(vol->dd); |
519 | 519 | return -1; |
520 | | } |
521 | | |
522 | | if (FAT_GET_FSINFO_LEAD_SIGNATURE(fs_info_sector) != |
| 520 | } |
| 521 | |
| 522 | if (FAT_GET_FSINFO_LEAD_SIGNATURE(fs_info_sector) != |
523 | 523 | FAT_FSINFO_LEAD_SIGNATURE_VALUE) |
524 | 524 | { |
… |
… |
|
536 | 536 | rtems_disk_release(vol->dd); |
537 | 537 | return -1; |
538 | | } |
539 | | |
| 538 | } |
| 539 | |
540 | 540 | vol->free_cls = FAT_GET_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector); |
541 | 541 | vol->next_cl = FAT_GET_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector); |
542 | | rc = fat_fat32_update_fsinfo_sector(mt_entry, 0xFFFFFFFF, |
| 542 | rc = fat_fat32_update_fsinfo_sector(mt_entry, 0xFFFFFFFF, |
543 | 543 | 0xFFFFFFFF); |
544 | 544 | if ( rc != RC_OK ) |
-
r0893220
|
r0a7278e
|
|
51 | 51 | # define CT_LE_W(v) CPU_swap_u16((uint16_t)(v)) |
52 | 52 | # define CT_LE_L(v) CPU_swap_u32((uint32_t)(v)) |
53 | | #else |
| 53 | #else |
54 | 54 | # define CF_LE_W(v) (v) |
55 | 55 | # define CF_LE_L(v) (v) |
… |
… |
|
104 | 104 | #define FAT_GET_ADDR(x, ofs) ((uint8_t *)(x) + (ofs)) |
105 | 105 | |
106 | | #define FAT_GET_VAL8(x, ofs) (uint8_t)(*((uint8_t *)(x) + (ofs))) |
| 106 | #define FAT_GET_VAL8(x, ofs) (uint8_t)(*((uint8_t *)(x) + (ofs))) |
107 | 107 | |
108 | 108 | #define FAT_GET_VAL16(x, ofs) \ |
… |
… |
|
115 | 115 | ((uint32_t)(*((uint8_t *)(x) + (ofs) + 2)) << 16) | \ |
116 | 116 | ((uint32_t)(*((uint8_t *)(x) + (ofs) + 3)) << 24) ) |
117 | | |
| 117 | |
118 | 118 | #define FAT_SET_VAL8(x, ofs,val) \ |
119 | 119 | (*((uint8_t *)(x)+(ofs))=(uint8_t)(val)) |
120 | | |
| 120 | |
121 | 121 | #define FAT_SET_VAL16(x, ofs,val) do { \ |
122 | 122 | FAT_SET_VAL8((x),(ofs),(val)); \ |
… |
… |
|
140 | 140 | #define FAT_SET_BR_BYTES_PER_SECTOR(x,val) FAT_SET_VAL16(x, 11,val) |
141 | 141 | |
142 | | #define FAT_GET_BR_SECTORS_PER_CLUSTER(x) FAT_GET_VAL8( x, 13) |
143 | | #define FAT_SET_BR_SECTORS_PER_CLUSTER(x,val)FAT_SET_VAL8( x, 13,val) |
| 142 | #define FAT_GET_BR_SECTORS_PER_CLUSTER(x) FAT_GET_VAL8( x, 13) |
| 143 | #define FAT_SET_BR_SECTORS_PER_CLUSTER(x,val)FAT_SET_VAL8( x, 13,val) |
144 | 144 | |
145 | 145 | #define FAT_GET_BR_RESERVED_SECTORS_NUM(x) FAT_GET_VAL16(x, 14) |
… |
… |
|
155 | 155 | #define FAT_SET_BR_TOTAL_SECTORS_NUM16(x,val)FAT_SET_VAL16(x, 19,val) |
156 | 156 | |
157 | | #define FAT_GET_BR_MEDIA(x) FAT_GET_VAL8( x, 21) |
158 | | #define FAT_SET_BR_MEDIA(x,val) FAT_SET_VAL8( x, 21,val) |
| 157 | #define FAT_GET_BR_MEDIA(x) FAT_GET_VAL8( x, 21) |
| 158 | #define FAT_SET_BR_MEDIA(x,val) FAT_SET_VAL8( x, 21,val) |
159 | 159 | |
160 | 160 | #define FAT_GET_BR_SECTORS_PER_FAT(x) FAT_GET_VAL16(x, 22) |
… |
… |
|
252 | 252 | #define FAT_SET_FSINFO_TRAIL_SIGNATURE(x,val) FAT_SET_VAL32(x,508,val) |
253 | 253 | #define FAT_FSINFO_TRAIL_SIGNATURE_VALUE (0xAA550000) |
254 | | /* |
255 | | * I read FSInfo sector from offset 484 to access the information, so offsets |
| 254 | /* |
| 255 | * I read FSInfo sector from offset 484 to access the information, so offsets |
256 | 256 | * of these fields a relative |
257 | 257 | */ |
-
r0893220
|
r0a7278e
|
|
116 | 116 | |
117 | 117 | memset(lfat_fd, 0, sizeof(fat_file_fd_t)); |
118 | | |
| 118 | |
119 | 119 | lfat_fd->links_num = 1; |
120 | 120 | lfat_fd->flags &= ~FAT_FILE_REMOVED; |
… |
… |
|
585 | 585 | |
586 | 586 | fat_fd->fat_file_size = new_length; |
587 | | |
| 587 | |
588 | 588 | return RC_OK; |
589 | 589 | } |
-
r0893220
|
r0a7278e
|
|
275 | 275 | unlen--; |
276 | 276 | } |
277 | | |
| 277 | |
278 | 278 | /* |
279 | 279 | * Copy the unix filename into the dos filename string upto the end |
-
r0893220
|
r0a7278e
|
|
81 | 81 | |
82 | 82 | fat_dir_pos_init(&dir_pos); |
83 | | |
| 83 | |
84 | 84 | memset(short_node, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE); |
85 | 85 | memset(dot_dotdot, 0, MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE * 2); |
-
r0893220
|
r0a7278e
|
|
15 | 15 | #endif |
16 | 16 | |
17 | | #include <ctype.h> |
| 17 | #include <ctype.h> |
18 | 18 | #include <stdlib.h> |
19 | 19 | #include <unistd.h> |
… |
… |
|
259 | 259 | { |
260 | 260 | char* entry = (char*) fs_info->cl_buf + i; |
261 | | |
| 261 | |
262 | 262 | /* |
263 | 263 | * Is this directory from here on empty ? |
… |
… |
|
289 | 289 | char* p; |
290 | 290 | int q; |
291 | | |
| 291 | |
292 | 292 | /* |
293 | 293 | * Is this is the first entry of a LFN ? |
… |
… |
|
307 | 307 | lfn_start = |
308 | 308 | ((j * bts2rd) + i) / MSDOS_DIRECTORY_ENTRY_STRUCT_SIZE; |
309 | | |
| 309 | |
310 | 310 | /* |
311 | 311 | * Get the number of entries so we can count down and |
… |
… |
|
331 | 331 | continue; |
332 | 332 | } |
333 | | |
| 333 | |
334 | 334 | /* |
335 | 335 | * Extract the file name into the directory entry. The data is |
… |
… |
|
341 | 341 | * fit in the directory entry name field. |
342 | 342 | */ |
343 | | |
| 343 | |
344 | 344 | lfn_entries--; |
345 | 345 | p = entry + 1; |
346 | 346 | o = lfn_entries * MSDOS_LFN_LEN_PER_ENTRY; |
347 | | |
| 347 | |
348 | 348 | for (q = 0; q < MSDOS_LFN_LEN_PER_ENTRY; q++) |
349 | 349 | { |
350 | 350 | if (o >= (sizeof(tmp_dirent.d_name) - 1)) |
351 | 351 | break; |
352 | | |
| 352 | |
353 | 353 | tmp_dirent.d_name[o++] = *p; |
354 | 354 | |
… |
… |
|
373 | 373 | { |
374 | 374 | fat_dir_pos_t dir_pos; |
375 | | |
| 375 | |
376 | 376 | /* |
377 | 377 | * Skip active entries until get the entry to start from. |
… |
… |
|
447 | 447 | tmp_dirent.d_namlen = strlen(tmp_dirent.d_name); |
448 | 448 | } |
449 | | |
| 449 | |
450 | 450 | memcpy(buffer + cmpltd, &tmp_dirent, sizeof(struct dirent)); |
451 | 451 | |
… |
… |
|
462 | 462 | } |
463 | 463 | } |
464 | | |
| 464 | |
465 | 465 | if (count <= 0) |
466 | 466 | break; |
-
r0893220
|
r0a7278e
|
|
181 | 181 | uint32_t total_sectors = sector_cnt; |
182 | 182 | int last_percent = -1; |
183 | | |
| 183 | |
184 | 184 | /* |
185 | 185 | * allocate and fill buffer |
… |
… |
|
201 | 201 | * write to consecutive sectors |
202 | 202 | */ |
203 | | while ((ret_val == 0) && |
| 203 | while ((ret_val == 0) && |
204 | 204 | (sector_cnt > 0)) { |
205 | 205 | int percent = (sector_cnt * 100) / total_sectors; |
… |
… |
|
213 | 213 | sector_cnt--; |
214 | 214 | } |
215 | | |
| 215 | |
216 | 216 | msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, "\n"); |
217 | 217 | |
… |
… |
|
219 | 219 | msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_INFO, |
220 | 220 | "filling error on sector: %d\n", start_sector); |
221 | | |
| 221 | |
222 | 222 | /* |
223 | 223 | * cleanup |
… |
… |
|
302 | 302 | sectors_per_cluster /= 2; |
303 | 303 | } |
304 | | |
| 304 | |
305 | 305 | do { |
306 | 306 | /* |
… |
… |
|
321 | 321 | } |
322 | 322 | |
323 | | sectors_per_fat = ((fat_capacity |
| 323 | sectors_per_fat = ((fat_capacity |
324 | 324 | + (bytes_per_sector - 1)) |
325 | 325 | / bytes_per_sector); |
… |
… |
|
342 | 342 | * when maximum cluster size is exceeded, we have invalid data, abort... |
343 | 343 | */ |
344 | | if ((sectors_per_cluster * bytes_per_sector) |
| 344 | if ((sectors_per_cluster * bytes_per_sector) |
345 | 345 | > MS_BYTES_PER_CLUSTER_LIMIT) { |
346 | 346 | ret_val = EINVAL; |
… |
… |
|
385 | 385 | uint32_t sectors_per_cluster_adj = 0; |
386 | 386 | uint64_t total_size = 0; |
387 | | |
| 387 | |
388 | 388 | memset(fmt_params,0,sizeof(*fmt_params)); |
389 | | /* |
| 389 | /* |
390 | 390 | * this one is fixed in this implementation. |
391 | 391 | * At least one thing we don't have to magically guess... |
… |
… |
|
403 | 403 | */ |
404 | 404 | if (ret_val == 0) { |
405 | | if ((rqdata == NULL) || |
| 405 | if ((rqdata == NULL) || |
406 | 406 | (rqdata->fat_num == 0)) { |
407 | 407 | fmt_params->fat_num = 2; |
… |
… |
|
414 | 414 | } |
415 | 415 | } |
416 | | |
| 416 | |
417 | 417 | if (ret_val == 0) |
418 | 418 | msdos_format_printf (rqdata, MSDOS_FMT_INFO_LEVEL_DETAIL, |
419 | 419 | "number of fats: %d\n", fmt_params->fat_num); |
420 | | |
| 420 | |
421 | 421 | /* |
422 | 422 | * Now we get sort of a loop when determining things: |
423 | | * The FAT type (FAT12/16/32) is determined ONLY from the |
| 423 | * The FAT type (FAT12/16/32) is determined ONLY from the |
424 | 424 | * data cluster count: |
425 | 425 | * Disks with data cluster count < 4085 are FAT12. |
426 | 426 | * Disks with data cluster count < 65525 are FAT16. |
427 | | * The rest is FAT32 (no FAT128 available yet :-) |
| 427 | * The rest is FAT32 (no FAT128 available yet :-) |
428 | 428 | * |
429 | | * The number of data clusters is the |
430 | | * total capacity |
| 429 | * The number of data clusters is the |
| 430 | * total capacity |
431 | 431 | * minus reserved sectors |
432 | 432 | * minus root directory ares |
433 | 433 | * minus storage needed for the FAT (and its copy/copies). |
434 | | * |
| 434 | * |
435 | 435 | * The last item once again depends on the FAT type and the cluster count. |
436 | | * |
| 436 | * |
437 | 437 | * So here is what we do in this formatter: |
438 | 438 | * - If a FAT type is requested from the caller, we try to modify |
439 | 439 | * the cluster size, until the data cluster count is in range |
440 | | * - If no FAT type is given, we estimate a useful FAT type from |
| 440 | * - If no FAT type is given, we estimate a useful FAT type from |
441 | 441 | * the disk capacity and then adapt the cluster size |
442 | | */ |
| 442 | */ |
443 | 443 | |
444 | 444 | /* |
… |
… |
|
451 | 451 | /* |
452 | 452 | * determine FAT type and sectors per cluster |
453 | | * depends on |
| 453 | * depends on |
454 | 454 | */ |
455 | 455 | if (ret_val == 0) { |
456 | 456 | fmt_params->sectors_per_cluster = 1; |
457 | | if ((rqdata != NULL) && |
| 457 | if ((rqdata != NULL) && |
458 | 458 | (rqdata->fattype == MSDOS_FMT_FAT12)) { |
459 | 459 | fmt_params->fattype = FAT_FAT12; |
460 | 460 | } |
461 | | else if ((rqdata != NULL) && |
| 461 | else if ((rqdata != NULL) && |
462 | 462 | (rqdata->fattype == MSDOS_FMT_FAT16)) { |
463 | 463 | fmt_params->fattype = FAT_FAT16; |
464 | 464 | } |
465 | | else if ((rqdata != NULL) && |
| 465 | else if ((rqdata != NULL) && |
466 | 466 | (rqdata->fattype == MSDOS_FMT_FAT32)) { |
467 | 467 | fmt_params->fattype = FAT_FAT32; |
… |
… |
|
478 | 478 | * are a compromise concerning capacity and efficency |
479 | 479 | */ |
480 | | if (fmt_params->totl_sector_cnt |
| 480 | if (fmt_params->totl_sector_cnt |
481 | 481 | < ((uint32_t)FAT_FAT12_MAX_CLN)*8) { |
482 | 482 | fmt_params->fattype = FAT_FAT12; |
483 | 483 | /* start trying with small clusters */ |
484 | | fmt_params->sectors_per_cluster = 2; |
| 484 | fmt_params->sectors_per_cluster = 2; |
485 | 485 | } |
486 | | else if (fmt_params->totl_sector_cnt |
| 486 | else if (fmt_params->totl_sector_cnt |
487 | 487 | < ((uint32_t)FAT_FAT16_MAX_CLN)*32) { |
488 | 488 | fmt_params->fattype = FAT_FAT16; |
489 | 489 | /* start trying with small clusters */ |
490 | | fmt_params->sectors_per_cluster = 2; |
| 490 | fmt_params->sectors_per_cluster = 2; |
491 | 491 | } |
492 | 492 | else { |
… |
… |
|