Kagera uHTTP Daemon
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

dateparse.c 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /**
  2. * @PROJECT Kagera uHTTP Daemon
  3. * @COPYRIGHT See COPYING in the top level directory
  4. * @FILE dateparse.c
  5. * @PURPOSE Parses string dates into internal form
  6. * @DEVELOPERS Rafal Kupiec <belliash@asiotec.eu.org>
  7. * Jef Poskanzer <jef@acme.com>
  8. */
  9. #include <sys/types.h>
  10. #include <ctype.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <time.h>
  15. #include "dateparse.h"
  16. time_t dateparse(char* str) {
  17. struct tm tm;
  18. char* cp;
  19. char str_mon[500], str_wday[500];
  20. int tm_sec, tm_min, tm_hour, tm_mday, tm_year;
  21. long tm_mon, tm_wday;
  22. (void) memset((char*) &tm, 0, sizeof(struct tm));
  23. for(cp = str; *cp == ' ' || *cp == '\t'; ++cp) {
  24. continue;
  25. }
  26. if(sscanf(cp, "%d-%400[a-zA-Z]-%d %d:%d:%d GMT", &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, &tm_sec) == 6 && scan_mon(str_mon, &tm_mon)) {
  27. tm.tm_mday = tm_mday;
  28. tm.tm_mon = tm_mon;
  29. tm.tm_year = tm_year;
  30. tm.tm_hour = tm_hour;
  31. tm.tm_min = tm_min;
  32. tm.tm_sec = tm_sec;
  33. } else if(sscanf(cp, "%d %400[a-zA-Z] %d %d:%d:%d GMT", &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, &tm_sec) == 6 && scan_mon(str_mon, &tm_mon)) {
  34. tm.tm_mday = tm_mday;
  35. tm.tm_mon = tm_mon;
  36. tm.tm_year = tm_year;
  37. tm.tm_hour = tm_hour;
  38. tm.tm_min = tm_min;
  39. tm.tm_sec = tm_sec;
  40. } else if(sscanf(cp, "%d:%d:%d GMT %d-%400[a-zA-Z]-%d", &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon, &tm_year) == 6 && scan_mon(str_mon, &tm_mon)) {
  41. tm.tm_hour = tm_hour;
  42. tm.tm_min = tm_min;
  43. tm.tm_sec = tm_sec;
  44. tm.tm_mday = tm_mday;
  45. tm.tm_mon = tm_mon;
  46. tm.tm_year = tm_year;
  47. } else if(sscanf(cp, "%d:%d:%d GMT %d %400[a-zA-Z] %d", &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon, &tm_year) == 6 && scan_mon(str_mon, &tm_mon)) {
  48. tm.tm_hour = tm_hour;
  49. tm.tm_min = tm_min;
  50. tm.tm_sec = tm_sec;
  51. tm.tm_mday = tm_mday;
  52. tm.tm_mon = tm_mon;
  53. tm.tm_year = tm_year;
  54. } else if(sscanf(cp, "%400[a-zA-Z], %d-%400[a-zA-Z]-%d %d:%d:%d GMT", str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, &tm_sec) == 7 && scan_wday(str_wday, &tm_wday) && scan_mon(str_mon, &tm_mon)) {
  55. tm.tm_wday = tm_wday;
  56. tm.tm_mday = tm_mday;
  57. tm.tm_mon = tm_mon;
  58. tm.tm_year = tm_year;
  59. tm.tm_hour = tm_hour;
  60. tm.tm_min = tm_min;
  61. tm.tm_sec = tm_sec;
  62. } else if(sscanf(cp, "%400[a-zA-Z], %d %400[a-zA-Z] %d %d:%d:%d GMT", str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min, &tm_sec) == 7 && scan_wday(str_wday, &tm_wday) && scan_mon(str_mon, &tm_mon)) {
  63. tm.tm_wday = tm_wday;
  64. tm.tm_mday = tm_mday;
  65. tm.tm_mon = tm_mon;
  66. tm.tm_year = tm_year;
  67. tm.tm_hour = tm_hour;
  68. tm.tm_min = tm_min;
  69. tm.tm_sec = tm_sec;
  70. } else if(sscanf(cp, "%400[a-zA-Z] %400[a-zA-Z] %d %d:%d:%d GMT %d", str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec, &tm_year) == 7 && scan_wday(str_wday, &tm_wday) && scan_mon(str_mon, &tm_mon)) {
  71. tm.tm_wday = tm_wday;
  72. tm.tm_mon = tm_mon;
  73. tm.tm_mday = tm_mday;
  74. tm.tm_hour = tm_hour;
  75. tm.tm_min = tm_min;
  76. tm.tm_sec = tm_sec;
  77. tm.tm_year = tm_year;
  78. } else {
  79. return (time_t) -1;
  80. }
  81. if(tm.tm_year > 1900) {
  82. tm.tm_year -= 1900;
  83. } else if(tm.tm_year < 70) {
  84. tm.tm_year += 100;
  85. }
  86. return tm_to_time(&tm);
  87. }
  88. static int is_leap(int year) {
  89. return year % 400? (year % 100 ? (year % 4 ? 0 : 1) : 0) : 1;
  90. }
  91. static void pound_case(char* str) {
  92. for(; *str != '\0'; ++str) {
  93. if(isupper((int) *str)) {
  94. *str = tolower((int) *str);
  95. }
  96. }
  97. }
  98. static int scan_mon(char* str_mon, long* tm_monP) {
  99. static struct strlong mon_tab[] = {
  100. { "jan", 0 }, { "january", 0 },
  101. { "feb", 1 }, { "february", 1 },
  102. { "mar", 2 }, { "march", 2 },
  103. { "apr", 3 }, { "april", 3 },
  104. { "may", 4 },
  105. { "jun", 5 }, { "june", 5 },
  106. { "jul", 6 }, { "july", 6 },
  107. { "aug", 7 }, { "august", 7 },
  108. { "sep", 8 }, { "september", 8 },
  109. { "oct", 9 }, { "october", 9 },
  110. { "nov", 10 }, { "november", 10 },
  111. { "dec", 11 }, { "december", 11 },
  112. };
  113. static int sorted = 0;
  114. if(!sorted) {
  115. (void) qsort(mon_tab, sizeof(mon_tab) / sizeof(struct strlong), sizeof(struct strlong), (int(*)(const void*, const void*)) strlong_compare);
  116. sorted = 1;
  117. }
  118. pound_case(str_mon);
  119. return strlong_search(str_mon, mon_tab, sizeof(mon_tab) / sizeof(struct strlong), tm_monP);
  120. }
  121. static int scan_wday(char* str_wday, long* tm_wdayP) {
  122. static struct strlong wday_tab[] = {
  123. { "sun", 0 }, { "sunday", 0 },
  124. { "mon", 1 }, { "monday", 1 },
  125. { "tue", 2 }, { "tuesday", 2 },
  126. { "wed", 3 }, { "wednesday", 3 },
  127. { "thu", 4 }, { "thursday", 4 },
  128. { "fri", 5 }, { "friday", 5 },
  129. { "sat", 6 }, { "saturday", 6 },
  130. };
  131. static int sorted = 0;
  132. if(!sorted) {
  133. (void) qsort(wday_tab, sizeof(wday_tab) / sizeof(struct strlong), sizeof(struct strlong), (int(*)(const void*, const void*)) strlong_compare);
  134. sorted = 1;
  135. }
  136. pound_case(str_wday);
  137. return strlong_search(str_wday, wday_tab, sizeof(wday_tab) / sizeof(struct strlong), tm_wdayP);
  138. }
  139. static int strlong_compare(char *v1, char *v2) {
  140. return strcmp(((struct strlong*) v1)->s, ((struct strlong*) v2)->s);
  141. }
  142. static int strlong_search(char* str, struct strlong* tab, int n, long* lP) {
  143. int i, h, l, r;
  144. l = 0;
  145. h = n - 1;
  146. for(;;) {
  147. i = (h + l) / 2;
  148. r = strcmp(str, tab[i].s);
  149. if(r < 0) {
  150. h = i - 1;
  151. } else if(r > 0) {
  152. l = i + 1;
  153. } else {
  154. *lP = tab[i].l;
  155. return 1;
  156. }
  157. if(h < l) {
  158. return 0;
  159. }
  160. }
  161. }
  162. static time_t tm_to_time(struct tm* tmP) {
  163. time_t t;
  164. static int monthtab[12] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  165. t = (tmP->tm_year - 70) * 365;
  166. t += (tmP->tm_year - 69) / 4;
  167. t += monthtab[tmP->tm_mon];
  168. if(tmP->tm_mon >= 2 && is_leap(tmP->tm_year + 1900)) {
  169. ++t;
  170. }
  171. t += tmP->tm_mday - 1;
  172. t = t * 24 + tmP->tm_hour;
  173. t = t * 60 + tmP->tm_min;
  174. t = t * 60 + tmP->tm_sec;
  175. return t;
  176. }