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

Web服务器

开发平台:

Unix_Linux

  1. /* Copyright (C) 1995, 1996 by Sven Berkvens (sven@stack.nl) */
  2. #include "config.h"
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. #ifdef HAVE_MEMORY_H
  9. #include <memory.h>
  10. #endif /* HAVE_MEMORY_H */
  11. #include <errno.h>
  12. #include <fcntl.h>
  13. #include "string.h"
  14. #ifdef PATH_PPMTOGIF
  15. #ifndef NOFORWARDS
  16. static VOID error PROTO((const char *, const char *));
  17. static VOID loaddigit PROTO((int));
  18. static VOID loadfont PROTO((void));
  19. static VOID buildpicture PROTO((void));
  20. #endif /* NOFORWARDS */
  21. typedef struct
  22. {
  23. int size_x, size_y;
  24. char *fontdata;
  25. } font;
  26. static const char *pathtranslated, *querystring;
  27. static char dirname[XS_PATH_MAX], filename[XS_PATH_MAX];
  28. static font digit[10];
  29. static int max_x, max_y;
  30. static VOID
  31. error DECL2CC(char *, status, char *, message)
  32. {
  33. printf("Status: %srn", status);
  34. printf("Content-type: text/htmlrnrn");
  35. printf("<HTML><HEAD><TITLE>%s</TITLE></HEAD>n", status);
  36. printf("<BODY><H1>%s</H1>n%sn", status, message);
  37. printf("</BODY></HTML>n");
  38. exit(1);
  39. }
  40. static VOID
  41. loaddigit DECL1(int, num)
  42. {
  43. FILE *file;
  44. char buffer[BUFSIZ], words[4][BUFSIZ], *search;
  45. int word, size;
  46. sprintf(filename, "%s%c.ppm", dirname, num + '0');
  47. if (!(file = fopen(filename, "r")))
  48. {
  49. sprintf(buffer, "Could not read digit from file `%s': %s",
  50. filename, strerror(errno));
  51. error("404 Could not read font data", buffer);
  52. }
  53. word = 0; words[0][0] = words[1][0] = words[2][0] = words[3][0] = 0;
  54. while (word < 4)
  55. {
  56. if (!fgets(buffer, BUFSIZ, file))
  57. {
  58. sprintf(buffer, "Font data in file `%s' is corrupt",
  59. filename);
  60. error("500 Could not read font data", buffer);
  61. }
  62. if ((search = strchr(buffer, '#')))
  63. *search = 0;
  64. search = buffer + strlen(buffer);
  65. while ((search > buffer) && (*(search - 1) <= ' '))
  66. *(--search) = 0;
  67. if (search == buffer)
  68. continue;
  69. search = buffer;
  70. while ((*search == ' ') || (*search == 't'))
  71. search++;
  72. while (*search)
  73. {
  74. sprintf(words[word], "%s%c", words[word], *search);
  75. if ((*search == ' ') || (*search == 't'))
  76. {
  77. search++; word++;
  78. while ((*search == ' ') || (*search == 't'))
  79. search++;
  80. } else
  81. search++;
  82. }
  83. word++;
  84. }
  85. if (strcmp("P6", words[0]))
  86. {
  87. sprintf(buffer, "The image in file `%s' is not a PPM file",
  88. filename);
  89. error("500 Invalid image type", buffer);
  90. }
  91. if ((digit[num].size_x = atoi(words[1])) <= 0)
  92. {
  93. sprintf(buffer, "The image in file `%s' has an invalid X size",
  94. filename);
  95. error("500 Corrupt image X header", buffer);
  96. }
  97. if ((digit[num].size_y = atoi(words[2])) <= 0)
  98. {
  99. sprintf(buffer, "The image in file `%s' has an invalid Y size",
  100. filename);
  101. error("500 Corrupt image Y header", buffer);
  102. }
  103. if (strcmp("255", words[3]))
  104. {
  105. sprintf(buffer, "The image in file `%s' has an invalid depth",
  106. filename);
  107. error("500 Corrupt image depth header", buffer);
  108. }
  109. size = digit[num].size_x * digit[num].size_y * 3;
  110. if (!(digit[num].fontdata = (char *)malloc(size)))
  111. error("500 Out of memory",
  112. "There was not enough memory to load the images");
  113. if (fread(digit[num].fontdata, size, 1, file) != 1)
  114. error("500 Error reading actual font data",
  115. "The image body could not be successfully read");
  116. fclose(file);
  117. }
  118. static VOID
  119. loadfont DECL0
  120. {
  121. int number;
  122. const char *search;
  123. max_x = max_y = 0;
  124. for (number = 0; number < 10; number++)
  125. {
  126. digit[number].size_x = digit[number].size_y = 0;
  127. digit[number].fontdata = NULL;
  128. }
  129. for (search = querystring; *search; search++)
  130. {
  131. number = *search - '0';
  132. if ((number < 0) || (number > 9))
  133. error("403 Incorrect usage",
  134. "Non-digits encountered in argument");
  135. if (!digit[number].fontdata)
  136. {
  137. loaddigit(number);
  138. if (max_y < digit[number].size_y)
  139. max_y = digit[number].size_y;
  140. }
  141. max_x += digit[number].size_x;
  142. }
  143. }
  144. static VOID
  145. buildpicture DECL0
  146. {
  147. const char *search;
  148. char *data, header[1024];
  149. int number, pos_x, y, font_width, fd, p[2];
  150. if (!(data = (char *)malloc(max_x * max_y * 3)))
  151. error("500 Out of memory",
  152. "Not enough memory to build picture");
  153. bzero(data, max_x * max_y * 3);
  154. pos_x = 0;
  155. for (search = querystring; *search; search++)
  156. {
  157. number = *search - '0';
  158. font_width = digit[number].size_x;
  159. for (y = 0; y < digit[number].size_y; y++)
  160. {
  161. bcopy(digit[number].fontdata + (3 * y * font_width),
  162. data + 3 * ((y * max_x) + pos_x),
  163. 3 * font_width);
  164. }
  165. pos_x += font_width;
  166. }
  167. fflush(stdout);
  168. if (pipe(p))
  169. error("500 Could not create pipe",
  170. "Could not create pipe for interprocess communication");
  171. switch(fork())
  172. {
  173. case -1:
  174. error("500 Could not fork()",
  175. "Could not create new process to make GIF file");
  176. case 0:
  177. close(p[1]); dup2(p[0], 0);
  178. if (p[0] != 0)
  179. close(p[0]);
  180. if ((fd = open(BITBUCKETNAME, O_WRONLY, S_IWUSR | S_IRUSR)) < 0)
  181. error("500 Cannot open temp file",
  182. "Could not open temporary file");
  183. if (fd != 2)
  184. {
  185. if (dup2(fd, 2) == -1)
  186. error("500 dup2() failed",
  187. "Could not duplicate file descriptor");
  188. close(fd);
  189. }
  190. printf("Content-type: image/gifrnrn");
  191. fflush(stdout);
  192. execl(PATH_PPMTOGIF, "ppmtogif", "-transparent", "#000000",
  193. NULL);
  194. error("500 Could not start ppmtogif",
  195. "Could not start PPM to GIF converter");
  196. default:
  197. close(p[0]);
  198. sprintf(header, "P6n%d %dn255n", max_x, max_y);
  199. write(p[1], header, strlen(header));
  200. write(p[1], data, max_x * max_y * 3);
  201. }
  202. exit(0);
  203. }
  204. extern int
  205. main DECL2(int, argc, char **, argv)
  206. {
  207. struct stat statbuf;
  208. char buffer[XS_PATH_MAX];
  209. alarm(240);
  210. pathtranslated = getenv("PATH_TRANSLATED");
  211. strcpy(dirname, pathtranslated ? pathtranslated : "");
  212. if (!dirname[0])
  213. sprintf(dirname, "%s/gfxcount/digital", HTTPD_ROOT);
  214. if (!strncmp(dirname, "/fonts/", 7))
  215. {
  216. sprintf(buffer, "%s/gfxcount/%s", HTTPD_ROOT, dirname + 7);
  217. strcpy(dirname, buffer);
  218. }
  219. if (dirname[0] && (dirname[strlen(dirname) - 1] != '/'))
  220. {
  221. if (!stat(dirname, &statbuf) && (S_ISDIR(statbuf.st_mode)))
  222. strcat(dirname, "/");
  223. }
  224. if (!(querystring = getenv("QUERY_STRING")) || !(*querystring))
  225. error("403 Illegal calling method",
  226. "You must supply a number as a query argument");
  227. loadfont();
  228. buildpicture();
  229. exit(0);
  230. }
  231. #else /* Not PATH_PPMTOGIF */
  232. extern int
  233. main DECL2(int, argc, char **, argv)
  234. {
  235. printf("Content-type: text/htmlrnrn");
  236. printf("<HTML><HEAD><TITLE>No can do</TITLE></HEAD>n");
  237. printf("<H1>No can do</H1>Regrettably, this operationn");
  238. printf("can not (yet) be performed, because the system lacksn");
  239. printf("some necessary programs.</BODY></HTML>n");
  240. exit(1);
  241. }
  242. #endif /* PATH_PPMTOGIF */