goahead.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. /*
  2. goahead.c -- Main program for GoAhead
  3. Usage: goahead [options] [documents] [IP][:port] ...
  4. Options:
  5. --auth authFile # User and role configuration
  6. --background # Run as a Linux daemon
  7. --home directory # Change to directory to run
  8. --log logFile:level # Log to file file at verbosity level
  9. --route routeFile # Route configuration file
  10. --verbose # Same as --log stdout:2
  11. --version # Output version information
  12. Copyright (c) All Rights Reserved. See details at the end of the file.
  13. */
  14. /********************************* Includes ***********************************/
  15. #include "goahead.h"
  16. /********************************* Defines ************************************/
  17. static int finished = 0;
  18. /********************************* Forwards ***********************************/
  19. static void initPlatform(void);
  20. static void logHeader(void);
  21. static void usage(void);
  22. #if WINDOWS
  23. static void windowsClose();
  24. static int windowsInit();
  25. static LRESULT CALLBACK websWindProc(HWND hwnd, UINT msg, UINT wp, LPARAM lp);
  26. #endif
  27. #if ME_UNIX_LIKE
  28. static void sigHandler(int signo);
  29. #endif
  30. static void buy(Webs *wp);
  31. static void actionTest(Webs *wp);
  32. static void personInfoAction(Webs *wp);
  33. typedef struct PERSON
  34. {
  35. char *name;
  36. int age;
  37. char *gender;
  38. }Person;
  39. static void personInfoAction(Webs *wp)
  40. {
  41. logmsg(2, "-----------------------111----------------------");
  42. int i;
  43. Person person[2];
  44. person[0].name = "kangkang";
  45. person[0].age = 12;
  46. person[0].gender = "male";
  47. person[1].name = "Jane";
  48. person[1].age = 14;
  49. person[1].gender = "female";
  50. websSetStatus(wp, 200);
  51. websWriteHeaders(wp, -1, 0);
  52. websWriteEndHeaders(wp);
  53. websWrite(wp, "[");
  54. for (i = 0;i < 2; i++)
  55. {
  56. websWrite(wp, " {\"name\":\"%s\",\"age\":\"%d\",\"gender\":\"%s\"}",
  57. person[i].name, person[i].age, person[i].gender);
  58. if (i != 1)
  59. {
  60. websWrite(wp, ",");
  61. }
  62. }
  63. websWrite(wp, "]");
  64. websDone(wp);
  65. }
  66. static void buy(Webs *wp)
  67. {
  68. char *name, *age;
  69. name = websGetVar(wp, "name", NULL);
  70. age = websGetVar(wp, "age", NULL);
  71. logmsg(2, "---------------------------------------------");
  72. logmsg(2, "name value is : %s", name );
  73. logmsg(2, "age value is : %s", age );
  74. websSetStatus(wp, 200);
  75. websWriteHeaders(wp, 0, 0);
  76. websWriteEndHeaders(wp);
  77. websWrite(wp, "Name %s", name);
  78. websWrite(wp, "Age %s", age);
  79. websFlush(wp, 0);
  80. websDone(wp);
  81. }
  82. /*
  83. Implement /action/actionTest. Parse the form variables: name, address and echo back.
  84. */
  85. static void actionTest(Webs *wp)
  86. {
  87. cchar *name, *address;
  88. name = websGetVar(wp, "name", NULL);
  89. address = websGetVar(wp, "address", NULL);
  90. websSetStatus(wp, 200);
  91. websWriteHeaders(wp, -1, 0);
  92. websWriteEndHeaders(wp);
  93. websWrite(wp, "<html><body><h2>name: %s, address: %s</h2></body></html>\n", name, address);
  94. websFlush(wp, 0);
  95. websDone(wp);
  96. }
  97. /*********************************** Code *************************************/
  98. MAIN(goahead, int argc, char **argv, char **envp)
  99. {
  100. char *argp, *home, *documents, *endpoints, *endpoint, *route, *auth, *tok, *lspec;
  101. int argind;
  102. logmsg(2, "---> log1\n");
  103. error("---> log1\n");
  104. #if WINDOWS
  105. if (windowsInit() < 0) {
  106. return 0;
  107. }
  108. #endif
  109. route = "route.txt";
  110. auth = "auth.txt";
  111. error("---> main enter, argc = %d\n", argc);
  112. for (argind = 1; argind < argc; argind++) {
  113. argp = argv[argind];
  114. error("---> argp = %s\n", argp);
  115. if (*argp != '-') {
  116. break;
  117. } else if (smatch(argp, "--auth") || smatch(argp, "-a")) {
  118. if (argind >= argc) usage();
  119. auth = argv[++argind];
  120. #if ME_UNIX_LIKE && !MACOSX
  121. } else if (smatch(argp, "--background") || smatch(argp, "-b")) {
  122. websSetBackground(1);
  123. #endif
  124. } else if (smatch(argp, "--debugger") || smatch(argp, "-d") || smatch(argp, "-D")) {
  125. websSetDebug(1);
  126. } else if (smatch(argp, "--home")) {
  127. if (argind >= argc) usage();
  128. home = argv[++argind];
  129. if (chdir(home) < 0) {
  130. error("Cannot change directory to %s", home);
  131. exit(-1);
  132. }
  133. error("---> get home\n");
  134. } else if (smatch(argp, "--log") || smatch(argp, "-l")) {
  135. if (argind >= argc) usage();
  136. logSetPath(argv[++argind]);
  137. } else if (smatch(argp, "--verbose") || smatch(argp, "-v")) {
  138. logSetPath("stdout:2");
  139. error( "---> get -v\n");
  140. } else if (smatch(argp, "--route") || smatch(argp, "-r")) {
  141. route = argv[++argind];
  142. } else if (smatch(argp, "--version") || smatch(argp, "-V")) {
  143. printf("%s\n", ME_VERSION);
  144. exit(0);
  145. } else if (*argp == '-' && isdigit((uchar) argp[1])) {
  146. lspec = sfmt("stdout:%s", &argp[1]);
  147. logSetPath(lspec);
  148. wfree(lspec);
  149. } else {
  150. usage();
  151. }
  152. }
  153. documents = ME_GOAHEAD_DOCUMENTS;
  154. if (argc > argind) {
  155. documents = argv[argind++];
  156. }
  157. error("---> initPlatform\n");
  158. initPlatform();
  159. if (websOpen(documents, route) < 0) {
  160. error("Cannot initialize server. Exiting.");
  161. return -1;
  162. }
  163. #if ME_GOAHEAD_AUTH
  164. error("---> ME_GOAHEAD_AUTH: %d\n", ME_GOAHEAD_AUTH);
  165. if (websLoad(auth) < 0) {
  166. error("Cannot load %s", auth);
  167. return -1;
  168. }
  169. #endif
  170. logHeader();
  171. error("---> argind = %d, argc = %d\n", argind, argc);
  172. if (argind < argc) {
  173. while (argind < argc) {
  174. endpoint = argv[argind++];
  175. if (websListen(endpoint) < 0) {
  176. return -1;
  177. }
  178. }
  179. } else {
  180. endpoints = sclone(ME_GOAHEAD_LISTEN);
  181. for (endpoint = stok(endpoints, ", \t", &tok); endpoint; endpoint = stok(NULL, ", \t,", &tok)) {
  182. #if !ME_COM_SSL
  183. error("ME_COM_SSL %d\n", ME_COM_SSL);
  184. if (strstr(endpoint, "https")) continue;
  185. #endif
  186. if (websListen(endpoint) < 0) {
  187. wfree(endpoints);
  188. return -1;
  189. }
  190. }
  191. wfree(endpoints);
  192. }
  193. #if ME_ROM && KEEP
  194. /*
  195. If not using a route/auth config files, then manually create the routes like this:
  196. If custom matching is required, use websSetRouteMatch. If authentication is required, use websSetRouteAuth.
  197. */
  198. websAddRoute("/", "file", 0);
  199. #endif
  200. //add by lusa start
  201. websDefineAction("buy", buy);
  202. websDefineAction("test", actionTest);
  203. websDefineAction("person", personInfoAction);
  204. // add by lusa end
  205. #ifdef GOAHEAD_INIT
  206. /*
  207. Define your init function in main.me goahead.init, or
  208. configure with DFLAGS=GOAHEAD_INIT=myInitFunction
  209. */
  210. {
  211. extern int GOAHEAD_INIT();
  212. if (GOAHEAD_INIT() < 0) {
  213. exit(1);
  214. }
  215. }
  216. #endif
  217. #if ME_UNIX_LIKE && !MACOSX
  218. /*
  219. Service events till terminated
  220. */
  221. if (websGetBackground()) {
  222. if (daemon(0, 0) < 0) {
  223. error("Cannot run as daemon");
  224. return -1;
  225. }
  226. }
  227. #endif
  228. error( "---> websServiceEvents\n");
  229. websServiceEvents(&finished);
  230. logmsg(1, "Instructed to exit");
  231. websClose();
  232. #if WINDOWS
  233. windowsClose();
  234. #endif
  235. return 0;
  236. }
  237. static void logHeader(void)
  238. {
  239. char home[ME_GOAHEAD_LIMIT_STRING];
  240. getcwd(home, sizeof(home));
  241. logmsg(2, "Configuration for %s", ME_TITLE);
  242. logmsg(2, "---------------------------------------------");
  243. logmsg(2, "Version: %s", ME_VERSION);
  244. logmsg(2, "BuildType: %s", ME_DEBUG ? "Debug" : "Release");
  245. logmsg(2, "CPU: %s", ME_CPU);
  246. logmsg(2, "OS: %s", ME_OS);
  247. logmsg(2, "Host: %s", websGetServer());
  248. logmsg(2, "Directory: %s", home);
  249. logmsg(2, "Documents: %s", websGetDocuments());
  250. logmsg(2, "Configure: %s", ME_CONFIG_CMD);
  251. logmsg(2, "---------------------------------------------");
  252. }
  253. static void usage(void) {
  254. fprintf(stderr, "\n%s Usage:\n\n"
  255. " %s [options] [documents] [[IPaddress][:port] ...]\n\n"
  256. " Options:\n"
  257. #if ME_GOAHEAD_AUTH
  258. " --auth authFile # User and role configuration\n"
  259. #endif
  260. #if ME_UNIX_LIKE && !MACOSX
  261. " --background # Run as a Unix daemon\n"
  262. #endif
  263. " --debugger # Run in debug mode\n"
  264. " --home directory # Change to directory to run\n"
  265. " --log logFile:level # Log to file file at verbosity level\n"
  266. " --route routeFile # Route configuration file\n"
  267. " --verbose # Same as --log stdout:2\n"
  268. " --version # Output version information\n\n",
  269. ME_TITLE, ME_NAME);
  270. exit(-1);
  271. }
  272. static void initPlatform(void)
  273. {
  274. #if ME_UNIX_LIKE
  275. error("---> initPlatform, ME_OS: %s\n", ME_OS);
  276. signal(SIGTERM, sigHandler);
  277. #ifdef SIGPIPE
  278. error("---> define SIGPIPE\n");
  279. signal(SIGPIPE, SIG_IGN);
  280. #endif
  281. #elif ME_WIN_LIKE
  282. _fmode=_O_BINARY;
  283. #endif
  284. }
  285. #if ME_UNIX_LIKE
  286. static void sigHandler(int signo)
  287. {
  288. finished = 1;
  289. }
  290. #endif
  291. //#if WINDOWS
  292. ///*
  293. // Create a taskbar entry. Register the window class and create a window
  294. // */
  295. //static int windowsInit()
  296. //{
  297. // HINSTANCE inst;
  298. // WNDCLASS wc; /* Window class */
  299. // HMENU hSysMenu;
  300. // HWND hwnd;
  301. //
  302. // inst = websGetInst();
  303. // wc.style = CS_HREDRAW | CS_VREDRAW;
  304. // wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  305. // wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  306. // wc.cbClsExtra = 0;
  307. // wc.cbWndExtra = 0;
  308. // wc.hInstance = inst;
  309. // wc.hIcon = NULL;
  310. // wc.lpfnWndProc = (WNDPROC) websWindProc;
  311. // wc.lpszMenuName = wc.lpszClassName = ME_NAME;
  312. // if (! RegisterClass(&wc)) {
  313. // return -1;
  314. // }
  315. // /*
  316. // Create a window just so we can have a taskbar to close this web server
  317. // */
  318. // hwnd = CreateWindow(ME_NAME, ME_TITLE, WS_MINIMIZE | WS_POPUPWINDOW, CW_USEDEFAULT,
  319. // 0, 0, 0, NULL, NULL, inst, NULL);
  320. // if (hwnd == NULL) {
  321. // return -1;
  322. // }
  323. //
  324. // /*
  325. // Add the about box menu item to the system menu
  326. // */
  327. // hSysMenu = GetSystemMenu(hwnd, FALSE);
  328. // if (hSysMenu != NULL) {
  329. // AppendMenu(hSysMenu, MF_SEPARATOR, 0, NULL);
  330. // }
  331. // ShowWindow(hwnd, SW_SHOWNORMAL);
  332. // UpdateWindow(hwnd);
  333. // return 0;
  334. //}
  335. //
  336. //
  337. //static void windowsClose()
  338. //{
  339. // HINSTANCE inst;
  340. //
  341. // inst = websGetInst();
  342. // UnregisterClass(ME_NAME, inst);
  343. //}
  344. //
  345. //
  346. ///*
  347. // Main menu window message handler.
  348. // */
  349. //static LRESULT CALLBACK websWindProc(HWND hwnd, UINT msg, UINT wp, LPARAM lp)
  350. //{
  351. // switch (msg) {
  352. // case WM_DESTROY:
  353. // PostQuitMessage(0);
  354. // finished++;
  355. // return 0;
  356. //
  357. // case WM_SYSCOMMAND:
  358. // break;
  359. // }
  360. // return DefWindowProc(hwnd, msg, wp, lp);
  361. //}
  362. //
  363. //
  364. ///*
  365. // Check for Windows Messages
  366. // */
  367. //WPARAM checkWindowsMsgLoop()
  368. //{
  369. // MSG msg;
  370. //
  371. // if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
  372. // if (!GetMessage(&msg, NULL, 0, 0) || msg.message == WM_QUIT) {
  373. // return msg.wParam;
  374. // }
  375. // TranslateMessage(&msg);
  376. // DispatchMessage(&msg);
  377. // }
  378. // return 0;
  379. //}
  380. //
  381. //
  382. ///*
  383. // Windows message handler
  384. // */
  385. //static LRESULT CALLBACK websAboutProc(HWND hwndDlg, uint msg, uint wp, long lp)
  386. //{
  387. // LRESULT lResult;
  388. //
  389. // lResult = DefWindowProc(hwndDlg, msg, wp, lp);
  390. //
  391. // switch (msg) {
  392. // case WM_CREATE:
  393. // break;
  394. // case WM_DESTROY:
  395. // break;
  396. // case WM_COMMAND:
  397. // break;
  398. // }
  399. // return lResult;
  400. //}
  401. //
  402. //#endif
  403. /*
  404. Copyright (c) Embedthis Software. All Rights Reserved.
  405. This software is distributed under commercial and open source licenses.
  406. You may use the Embedthis GoAhead open source license or you may acquire
  407. a commercial license from Embedthis Software. You agree to be fully bound
  408. by the terms of either license. Consult the LICENSE.md distributed with
  409. this software for full details and other copyrights.
  410. */