error.c
上传用户:lampled
上传日期:2007-01-07
资源大小:94k
文件大小:11k
源码类别:

Web服务器

开发平台:

Unix_Linux

  1. #include "config.h"
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <stdlib.h>
  7. #include <pwd.h>
  8. #include "local.h"
  9. #include "setenv.h"
  10. #include "string.h"
  11. #include "path.h"
  12. #ifndef NOFORWARDS
  13. extern VOID error PROTO((const char *));
  14. extern VOID redirect PROTO((const char *, int));
  15. extern VOID server_error PROTO((const char *, const char *));
  16. static int difference PROTO((const char *, const char *));
  17. static int check_user PROTO((const struct passwd *));
  18. static VOID user_unknown PROTO((void));
  19. static VOID post_on_non_cgi PROTO((void));
  20. static VOID invalid_path PROTO((void));
  21. static VOID dir_not_avail PROTO((void));
  22. static VOID not_regular PROTO((void));
  23. static VOID permission PROTO((void));
  24. static VOID not_found PROTO((void));
  25. static VOID no_relative_urls PROTO((void));
  26. static VOID unknown_method PROTO((void));
  27. static VOID unauthorized PROTO((void));
  28. static VOID local_no_page PROTO((void));
  29. static VOID local_invalid_link PROTO((void));
  30. #endif /* NOFORWARDS */
  31. typedef struct
  32. {
  33. char username[32];
  34. int rank;
  35. } userinfo;
  36. static const char *error_code, *error_readable, *error_url,
  37. *error_url_escaped, *error_url_expanded,
  38. *local_mode_str;
  39. static char buffer[BUFSIZ], *temp;
  40. char rootdir[XS_PATH_MAX];
  41. int localmode;
  42. extern VOID
  43. error DECL1C(char *, what)
  44. {
  45. printf("Content-type: text/htmlrnrn");
  46. printf("<HTML><HEAD><TITLE>500 Error occurred</TITLE></HEADn");
  47. printf("<BODY><H1>500 Error occurred</H1>n");
  48. printf("The <TT>error</TT> utility encountered the followingn");
  49. printf("error: <B>%s</B></BODY></HTML>n", what);
  50. exit(0);
  51. }
  52. extern VOID
  53. redirect DECL2C_(char *, redir, int, code)
  54. {
  55. printf("[redirect() called - transform_user_dir() is broken]n");
  56. }
  57. extern VOID
  58. server_error DECL2CC(char *, readable, char *, code)
  59. {
  60. printf("[server_error() called - transform_user_dir() is broken]n");
  61. }
  62. static int
  63. difference DECL2CC(char *, what1, char *, what2)
  64. {
  65. int rank;
  66. const char *search, *follow;
  67. char ch;
  68. rank = 0;
  69. for (search = what1, follow = what2; (ch = *search); search++)
  70. {
  71. if (ch == *follow)
  72. rank--;
  73. else if (!strchr(what2, ch))
  74. rank += 5;
  75. else
  76. rank += 2;
  77. if (*follow)
  78. follow++;
  79. }
  80. rank += strlen(follow);
  81. if (rank < 0)
  82. rank = 0;
  83. return(rank);
  84. }
  85. static int
  86. check_user DECL1C(struct passwd *, userinfo)
  87. {
  88. char dirname[XS_PATH_MAX], *end;
  89. if (transform_user_dir(dirname, userinfo, 0))
  90. return(0);
  91. strcat(dirname, "/");
  92. end = dirname + strlen(dirname);
  93. strcpy(end, INDEX_HTML);
  94. if (!access(dirname, F_OK))
  95. return(1);
  96. strcpy(end, INDEX_HTML_2);
  97. if (!access(dirname, F_OK))
  98. return(1);
  99. return(0);
  100. }
  101. static VOID
  102. user_unknown DECL0
  103. {
  104. userinfo top[10];
  105. const struct passwd *user;
  106. int count, count2, rank, said;
  107. char filename[XS_PATH_MAX];
  108. strcpy(buffer, error_url_escaped + 2);
  109. if ((temp = strchr(buffer, '/')))
  110. *temp = 0;
  111. printf("The user <B>%s</B> is unknown to this system.<P>n", buffer);
  112. strcpy(buffer, error_url + 2);
  113. if ((temp = strchr(buffer, '/')))
  114. *(temp++) = 0;
  115. for (count = 0; count < 10; count++)
  116. {
  117. top[count].username[0] = 0;
  118. top[count].rank = 10000;
  119. }
  120. while ((user = getpwent()))
  121. {
  122. rank = difference(buffer, user->pw_name);
  123. count = 0;
  124. while ((count < 10) && (top[count].rank < rank))
  125. count++;
  126. if (count < 10)
  127. {
  128. if (!check_user(user))
  129. continue;
  130. for (count2 = 9; count2 > count; count2--)
  131. top[count2] = top[count2 - 1];
  132. top[count].rank = rank;
  133. strcpy(top[count].username, user->pw_name);
  134. }
  135. }
  136. said = 0;
  137. for (count = 0; (count < 10) && (top[count].rank <= 20); count++)
  138. {
  139. if (!said)
  140. {
  141. printf("There are a few usernames that look similarn");
  142. printf("to what you typed. Perhaps you meant one ofn");
  143. printf("these users:n<UL>n");
  144. said = 1;
  145. }
  146. printf("<LI><A HREF="/%%7E%s/">%s</A>n",
  147. top[count].username, top[count].username);
  148. }
  149. if (said)
  150. printf("</UL>n");
  151. else
  152. {
  153. printf("There are no usernames here that even look liken");
  154. printf("what you typed...<P>n");
  155. }
  156. printf("You may look at the <A HREF="/">main index page</A>");
  157. sprintf(filename, "%s/users.html", HTTPD_DOCUMENT_ROOT);
  158. if (!access(calcpath(filename), F_OK))
  159. printf(" or the <A HREF="/users.html">user list</A>n");
  160. printf(".n");
  161. }
  162. static VOID
  163. post_on_non_cgi DECL0
  164. {
  165. printf("You or your browser has attempted to use the <B>POST</B>n");
  166. printf("method on something that is not a CGI binary. <B>POST</B>n");
  167. printf("may only be used on CGI binaries. You can try using then");
  168. printf("<B>GET</B> and/or <B>HEAD</B> methods instead.<P>n");
  169. printf("<A HREF="/">Get out of here!</A>n");
  170. }
  171. static VOID
  172. invalid_path DECL0
  173. {
  174. printf("You have asked for a URL that the server does not like.n");
  175. printf("In particular, the server does not accept paths withn");
  176. printf("<B>..</B> in them. Please retry using another URL.<P>n");
  177. printf("<A HREF="/">Get out of here!</A>n");
  178. }
  179. static VOID
  180. not_found DECL0
  181. {
  182. char prefix[BUFSIZ], base[XS_PATH_MAX], filename[XS_PATH_MAX];
  183. const char *begin, *match;
  184. int len;
  185. struct stat statbuf;
  186. printf("The file <B>%s</B> does not exist on this server.n",
  187. error_url_escaped);
  188. if (error_url[1] == '~')
  189. {
  190. match = error_url + 2;
  191. while (*match && (*match != '/'))
  192. match++;
  193. begin = match;
  194. strcpy(prefix, error_url);
  195. prefix[match - error_url] = 0;
  196. strcpy(base, error_url_expanded);
  197. base[(strlen(error_url_expanded) - strlen(error_url) +
  198. (match - error_url))] = 0;
  199. strcat(base, "/");
  200. } else
  201. {
  202. prefix[0] = 0;
  203. sprintf(base, "%s/%s/", HTTPD_ROOT, HTTPD_DOCUMENT_ROOT);
  204. begin = error_url;
  205. }
  206. len = strlen(begin);
  207. while (len >= 0)
  208. {
  209. sprintf(buffer, "%s%*.*s", base, -len, len, begin);
  210. if (!stat(buffer, &statbuf))
  211. {
  212. if (S_ISREG(statbuf.st_mode))
  213. {
  214. sprintf(buffer, "%s%*.*s", prefix,
  215. -len, len, begin);
  216. break;
  217. }
  218. if (!(S_ISDIR(statbuf.st_mode)))
  219. continue;
  220. sprintf(buffer, "%s%*.*s%s%s", base, -len, len, begin,
  221. (begin[len-1] == '/') ? "" : "/", INDEX_HTML);
  222. if (!stat(buffer, &statbuf) && S_ISREG(statbuf.st_mode))
  223. {
  224. sprintf(buffer, "%s%*.*s%s", prefix,
  225. -len, len, begin,
  226. (begin[len - 1] == '/') ? "" : "/");
  227. break;
  228. }
  229. sprintf(buffer, "%s%*.*s%s%s", base, -len, len, begin,
  230. (begin[len-1] == '/') ? "" : "/", INDEX_HTML_2);
  231. if (!stat(buffer, &statbuf) && S_ISREG(statbuf.st_mode))
  232. {
  233. sprintf(buffer, "%s%*.*s%s", prefix,
  234. -len, len, begin,
  235. (begin[len - 1] == '/') ? "" : "/");
  236. break;
  237. }
  238. }
  239. len--;
  240. }
  241. if ((len >= 0) && strcmp(buffer, error_url) && strcmp(buffer, "/"))
  242. {
  243. printf("The path does seem to partially exist.n");
  244. printf("Perhaps the path <A HREF="%s">%s</A> will help.n",
  245. buffer, buffer);
  246. printf("<P>Alternatively, y");
  247. } else
  248. printf("Y");
  249. printf("ou may take a look at <A HREF="/">the main index</A>");
  250. sprintf(filename, "%s/users.html", HTTPD_DOCUMENT_ROOT);
  251. if (!access(calcpath(filename), F_OK))
  252. printf(" or the <A HREF="/users.html">user list</A>n");
  253. printf(".n");
  254. }
  255. static VOID
  256. not_regular DECL0
  257. {
  258. printf("What you requested is neither a directory nor a file.n");
  259. printf("This error should never occur. Please notify then");
  260. printf("system administration of this machine.n");
  261. }
  262. static VOID
  263. permission DECL0
  264. {
  265. printf("The file <B>%s</B>, which you tried to retrieve fromn",
  266. error_url_escaped);
  267. printf("this server, is protected. You are not allowed ton");
  268. printf("retrieve it. If this seems to be in error, pleasen");
  269. printf("contact the person that created the file.n");
  270. printf("<P><A HREF="/">Get out of here!</A>n");
  271. }
  272. static VOID
  273. dir_not_avail DECL0
  274. {
  275. printf("The directory in which the file <B>%s</B> is locatedn",
  276. error_url_escaped);
  277. printf("is currently not available for retrieval. Perhaps youn");
  278. printf("can try later.n");
  279. printf("<P><A HREF="/">Get out of here!</A>n");
  280. }
  281. static VOID
  282. no_relative_urls DECL0
  283. {
  284. printf("Your browser has made a <EM>relative</EM> request ton");
  285. printf("this server. This server, however, does not supportn");
  286. printf("relative URLs.n");
  287. printf("<P><A HREF="/">Get out of here!</A>n");
  288. }
  289. static VOID
  290. unknown_method DECL0
  291. {
  292. const char *env;
  293. env = getenv("REQUEST_METHOD");
  294. printf("Your browser has used a retrieval method other thann");
  295. printf("<B>GET</B>, <B>POST</B> and <B>HEAD</B>. In fact itn");
  296. printf("used the method <B>%s</B>, which this server does notn",
  297. env ? env : "(unknown)");
  298. printf("understand.n");
  299. printf("<P><A HREF="/">Get out of here!</A>n");
  300. }
  301. static VOID
  302. unauthorized DECL0
  303. {
  304. printf("You have entered a usercode/password combinationn");
  305. printf("which is not valid for the URL that you have requestedn");
  306. printf("Please try again with another usercode and/or password.n");
  307. }
  308. static VOID
  309. local_no_page DECL0
  310. {
  311. const char *env;
  312. char filename[XS_PATH_MAX];
  313. strcpy(buffer, error_url_escaped + 2);
  314. if ((temp = strchr(buffer, '/')))
  315. *temp = 0;
  316. printf("The user <B>%s</B>, whom you specified in your URL,n", buffer);
  317. printf("exists on this system, but has no home page.n");
  318. if ((env = getenv("REMOTE_ADDR")) && !strncmp(env, "131.155.140.", 12))
  319. {
  320. printf("If you would like to start a home page,n");
  321. printf("please mail to <A HREF="mailto:");
  322. printf("www-request@stack.nl">");
  323. printf("www-request@stack.nl</A>.n");
  324. }
  325. printf("<P>Perhaps you meant somebody else; in this case, pleasen");
  326. printf("have a look at the <A HREF="/">main index</A>");
  327. sprintf(filename, "%s/users.html", HTTPD_DOCUMENT_ROOT);
  328. if (!access(calcpath(filename), F_OK))
  329. printf(" or the <A HREF="/users.html">user list</A>n");
  330. printf(".n");
  331. }
  332. static VOID
  333. local_invalid_link DECL0
  334. {
  335. strcpy(buffer, error_url_escaped + 2);
  336. if ((temp = strchr(buffer, '/')))
  337. *temp = 0;
  338. printf("An error has been made in linking <B>/www/%s</B> ton", buffer);
  339. printf("a correct location. Please contactn");
  340. printf("<A HREF="mailto:www-request@stack.nl">");
  341. printf("www-request@stack.nl</A>.n");
  342. printf("The problem will then be corrected as soon as possible.n");
  343. }
  344. extern int
  345. main DECL2(int, argc, char **, argv)
  346. {
  347. if (getenv("HTTPD_ROOT"))
  348. strcpy(rootdir, getenv("HTTPD_ROOT"));
  349. else
  350. strcpy(rootdir, HTTPD_ROOT);
  351. alarm(240);
  352. if (!(error_code = getenv("ERROR_CODE")) ||
  353. !(error_readable = getenv("ERROR_READABLE")) ||
  354. !(error_url = getenv("ERROR_URL")) ||
  355. !(error_url_expanded = getenv("ERROR_URL_EXPANDED")) ||
  356. !(error_url_escaped = getenv("ERROR_URL_ESCAPED")) ||
  357. !(local_mode_str = getenv("LOCALMODE")))
  358. error("Not called properly - the server must call me");
  359. localmode = atoi(local_mode_str);
  360. printf("Content-type: text/htmlrn");
  361. printf("Status: %srnrn", error_readable);
  362. printf("<HTML><HEAD><TITLE>%s</TITLE></HEAD>", error_readable);
  363. printf("<BODY><H1>%s</H1>n", error_readable);
  364. if (!strcmp(error_code, "USER_UNKNOWN"))
  365. user_unknown();
  366. else if (!strcmp(error_code, "POST_ON_NON_CGI"))
  367. post_on_non_cgi();
  368. else if (!strcmp(error_code, "INVALID_PATH"))
  369. invalid_path();
  370. else if (!strcmp(error_code, "DIR_NOT_AVAIL"))
  371. dir_not_avail();
  372. else if (!strcmp(error_code, "NOT_REGULAR"))
  373. not_regular();
  374. else if (!strcmp(error_code, "PERMISSION"))
  375. permission();
  376. else if (!strcmp(error_code, "NOT_FOUND"))
  377. not_found();
  378. else if (!strcmp(error_code, "NO_RELATIVE_URLS"))
  379. no_relative_urls();
  380. else if (!strcmp(error_code, "UNKNOWN_METHOD"))
  381. unknown_method();
  382. else if (!strcmp(error_code, "UNAUTHORIZED"))
  383. unauthorized();
  384. else if (!strcmp(error_code, "LOCAL_NO_PAGE"))
  385. local_no_page();
  386. else if (!strcmp(error_code, "LOCAL_INVALID_LINK"))
  387. local_invalid_link();
  388. printf("</BODY></HTML>n");
  389. exit(0);
  390. }