|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include <time.h> 00006 00007 #include "resip/stack/DateCategory.hxx" 00008 #include "resip/stack/Transport.hxx" 00009 #include "rutil/Data.hxx" 00010 #include "rutil/DnsUtil.hxx" 00011 #include "rutil/Logger.hxx" 00012 #include "rutil/ParseBuffer.hxx" 00013 #include "rutil/Socket.hxx" 00014 //#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below 00015 00016 using namespace resip; 00017 using namespace std; 00018 00019 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP 00020 00021 //==================== 00022 // Date 00023 //==================== 00024 00025 Data resip::DayOfWeekData[] = 00026 { 00027 "Sun", 00028 "Mon", 00029 "Tue", 00030 "Wed", 00031 "Thu", 00032 "Fri", 00033 "Sat" 00034 }; 00035 00036 Data resip::MonthData[] = 00037 { 00038 "Jan", 00039 "Feb", 00040 "Mar", 00041 "Apr", 00042 "May", 00043 "Jun", 00044 "Jul", 00045 "Aug", 00046 "Sep", 00047 "Oct", 00048 "Nov", 00049 "Dec" 00050 }; 00051 00052 00053 DateCategory::DateCategory() 00054 : ParserCategory(), 00055 mDayOfWeek(Sun), 00056 mDayOfMonth(), 00057 mMonth(Jan), 00058 mYear(0), 00059 mHour(0), 00060 mMin(0), 00061 mSec(0) 00062 { 00063 time_t now; 00064 time(&now); 00065 if (now == ((time_t)-1)) 00066 { 00067 int e = getErrno(); 00068 DebugLog (<< "Failed to get time: " << strerror(e)); 00069 Transport::error(e); 00070 return; 00071 } 00072 00073 setDatetime(now); 00074 } 00075 00076 DateCategory::DateCategory(time_t datetime) 00077 : ParserCategory(), 00078 mDayOfWeek(Sun), 00079 mDayOfMonth(), 00080 mMonth(Jan), 00081 mYear(0), 00082 mHour(0), 00083 mMin(0), 00084 mSec(0) 00085 { 00086 setDatetime(datetime); 00087 } 00088 00089 DateCategory::DateCategory(const HeaderFieldValue& hfv, 00090 Headers::Type type, 00091 PoolBase* pool) 00092 : ParserCategory(hfv, type, pool), 00093 mDayOfWeek(Sun), 00094 mDayOfMonth(), 00095 mMonth(Jan), 00096 mYear(0), 00097 mHour(0), 00098 mMin(0), 00099 mSec(0) 00100 {} 00101 00102 DateCategory::DateCategory(const DateCategory& rhs, 00103 PoolBase* pool) 00104 : ParserCategory(rhs, pool), 00105 mDayOfWeek(rhs.mDayOfWeek), 00106 mDayOfMonth(rhs.mDayOfMonth), 00107 mMonth(rhs.mMonth), 00108 mYear(rhs.mYear), 00109 mHour(rhs.mHour), 00110 mMin(rhs.mMin), 00111 mSec(rhs.mSec) 00112 {} 00113 00114 DateCategory& 00115 DateCategory::operator=(const DateCategory& rhs) 00116 { 00117 if (this != &rhs) 00118 { 00119 ParserCategory::operator=(rhs); 00120 mDayOfWeek = rhs.mDayOfWeek; 00121 mDayOfMonth = rhs.mDayOfMonth; 00122 mMonth = rhs.mMonth; 00123 mYear = rhs.mYear; 00124 mHour = rhs.mHour; 00125 mMin = rhs.mMin; 00126 mSec = rhs.mSec; 00127 } 00128 return *this; 00129 } 00130 00131 bool 00132 DateCategory::setDatetime(time_t datetime) 00133 { 00134 struct tm gmt; 00135 #if defined(WIN32) || defined(__sun) 00136 struct tm *gmtp = gmtime(&datetime); 00137 if (gmtp == 0) 00138 { 00139 int e = getErrno(); 00140 DebugLog (<< "Failed to convert to gmt: " << strerror(e)); 00141 Transport::error(e); 00142 return false; 00143 } 00144 memcpy(&gmt,gmtp,sizeof(gmt)); 00145 #else 00146 if (gmtime_r(&datetime, &gmt) == 0) 00147 { 00148 int e = getErrno(); 00149 DebugLog (<< "Failed to convert to gmt: " << strerror(e)); 00150 Transport::error(e); 00151 return false; 00152 } 00153 #endif 00154 00155 mDayOfWeek = static_cast<DayOfWeek>(gmt.tm_wday); 00156 mDayOfMonth = gmt.tm_mday; 00157 mMonth = static_cast<Month>(gmt.tm_mon); 00158 mYear = gmt.tm_year + 1900; 00159 mHour = gmt.tm_hour; 00160 mMin = gmt.tm_min; 00161 mSec = gmt.tm_sec; 00162 DebugLog (<< "Set date: day=" << mDayOfWeek 00163 << " month=" << mMonth 00164 << " year=" << mYear 00165 << " " << mHour << ":" << mMin << ":" << mSec); 00166 return true; 00167 } 00168 00169 /* ANSI-C code produced by gperf version 2.7.2 */ 00170 /* Command-line: gperf -L ANSI-C -t -k '*' dayofweek.gperf */ 00174 struct days { char name[32]; DayOfWeek day; }; 00175 00176 #ifdef __GNUC__ 00177 __inline 00178 #else 00179 #ifdef __cplusplus 00180 inline 00181 #endif 00182 #endif 00183 static unsigned int 00184 dayofweek_hash (register const char *str, register unsigned int len) 00185 { 00186 static unsigned char asso_values[] = 00187 { 00188 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00189 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00190 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00191 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00192 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00193 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00194 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00195 1, 13, 13, 13, 13, 13, 13, 5, 13, 13, 00196 13, 13, 13, 2, 0, 13, 13, 7, 13, 13, 00197 13, 13, 13, 13, 13, 13, 13, 7, 13, 13, 00198 0, 0, 13, 13, 4, 0, 13, 13, 13, 13, 00199 0, 0, 13, 13, 0, 13, 0, 0, 13, 13, 00200 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00201 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00202 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00203 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00204 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00205 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00206 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00207 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00208 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00209 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00210 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00211 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00212 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 00213 13, 13, 13, 13, 13, 13 00214 }; 00215 register int hval = len; 00216 00217 switch (hval) 00218 { 00219 default: /*FALLTHRU*/ 00220 case 3: 00221 hval += asso_values[(unsigned char)str[2]]; 00222 /*FALLTHRU*/ 00223 case 2: 00224 hval += asso_values[(unsigned char)str[1]]; 00225 /*FALLTHRU*/ 00226 case 1: 00227 hval += asso_values[(unsigned char)str[0]]; 00228 break; 00229 } 00230 return hval; 00231 } 00232 00233 #ifdef __GNUC__ 00234 __inline 00235 #endif 00236 struct days * 00237 in_dayofweek_word_set (register const char *str, register unsigned int len) 00238 { 00239 static const unsigned int MIN_WORD_LENGTH = 3; 00240 static const unsigned int MAX_WORD_LENGTH = 3; 00241 static const int MAX_HASH_VALUE = 12; 00242 00243 static struct days wordlist[] = 00244 { 00245 {""}, {""}, {""}, 00246 {"Tue", Tue}, 00247 {"Fri", Fri}, 00248 {"Sun", Sun}, 00249 {""}, 00250 {"Thu", Thu}, 00251 {"Mon", Mon}, 00252 {""}, 00253 {"Wed", Wed}, 00254 {""}, 00255 {"Sat", Sat} 00256 }; 00257 00258 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 00259 { 00260 register int key = dayofweek_hash (str, len); 00261 00262 if (key <= MAX_HASH_VALUE && key >= 0) 00263 { 00264 register const char *s = wordlist[key].name; 00265 00266 if (*str == *s && !strcmp (str + 1, s + 1)) 00267 return &wordlist[key]; 00268 } 00269 } 00270 return 0; 00271 } 00272 00273 DayOfWeek 00274 DateCategory::DayOfWeekFromData(const Data& dow) 00275 { 00276 static const unsigned int MIN_WORD_LENGTH = 3; 00277 static const unsigned int MAX_WORD_LENGTH = 3; 00278 static const int MAX_HASH_VALUE = 12; 00279 00280 register const char *str = dow.data(); 00281 register Data::size_type len = dow.size(); 00282 00283 static struct days wordlist[] = 00284 { 00285 {""}, {""}, {""}, 00286 {"Tue", Tue}, 00287 {"Fri", Fri}, 00288 {"Sun", Sun}, 00289 {""}, 00290 {"Thu", Thu}, 00291 {"Mon", Mon}, 00292 {""}, 00293 {"Wed", Wed}, 00294 {""}, 00295 {"Sat", Sat} 00296 }; 00297 00298 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 00299 { 00300 register int key = dayofweek_hash (str, (unsigned int)len); 00301 00302 if (key <= MAX_HASH_VALUE && key >= 0) 00303 { 00304 register const char *s = wordlist[key].name; 00305 00306 if (*str == *s && !strncmp (str+1, s+1, len-1)) 00307 { 00308 return wordlist[key].day; 00309 } 00310 } 00311 } 00312 return Sun; 00313 } 00314 00315 /* ANSI-C code produced by gperf version 2.7.2 */ 00316 /* Command-line: gperf -L ANSI-C -t -k '*' month.gperf */ 00320 struct months { char name[32]; Month type; }; 00321 00322 /* maximum key range = 31, duplicates = 0 */ 00323 00324 #ifdef __GNUC__ 00325 __inline 00326 #else 00327 #ifdef __cplusplus 00328 inline 00329 #endif 00330 #endif 00331 static unsigned int 00332 month_hash (register const char *str, register unsigned int len) 00333 { 00334 static unsigned char asso_values[] = 00335 { 00336 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00337 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00338 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00339 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00340 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00341 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00342 34, 34, 34, 34, 34, 15, 34, 34, 8, 34, 00343 5, 34, 34, 34, 0, 34, 34, 10, 3, 14, 00344 34, 34, 34, 9, 34, 34, 34, 34, 34, 34, 00345 34, 34, 34, 34, 34, 34, 34, 10, 0, 0, 00346 34, 0, 34, 10, 34, 34, 34, 34, 4, 34, 00347 0, 0, 0, 34, 0, 34, 0, 0, 0, 34, 00348 34, 10, 34, 34, 34, 34, 34, 34, 34, 34, 00349 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00350 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00351 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00352 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00353 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00354 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00355 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00356 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00357 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00358 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00359 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00360 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 00361 34, 34, 34, 34, 34, 34 00362 }; 00363 register int hval = len; 00364 00365 switch (hval) 00366 { 00367 default: /*FALLTHRU*/ 00368 case 3: 00369 hval += asso_values[(unsigned char)str[2]]; 00370 /*FALLTHRU*/ 00371 case 2: 00372 hval += asso_values[(unsigned char)str[1]]; 00373 /*FALLTHRU*/ 00374 case 1: 00375 hval += asso_values[(unsigned char)str[0]]; 00376 break; 00377 } 00378 return hval; 00379 } 00380 00381 Month 00382 DateCategory::MonthFromData(const Data& mon) 00383 { 00384 static const unsigned int MIN_WORD_LENGTH = 3; 00385 static const unsigned int MAX_WORD_LENGTH = 3; 00386 static const int MAX_HASH_VALUE = 33; 00387 00388 register const char *str = mon.data(); 00389 register Data::size_type len = mon.size(); 00390 00391 static struct months wordlist[] = 00392 { 00393 {""}, {""}, {""}, 00394 {"Jun", Jun}, 00395 {""}, {""}, 00396 {"Nov", Nov}, 00397 {"Jul", Jul}, 00398 {"Feb", Feb}, 00399 {""}, {""}, 00400 {"Dec", Dec}, 00401 {"Sep", Sep}, 00402 {"Jan", Jan}, 00403 {""}, {""}, {""}, 00404 {"Oct", Oct}, 00405 {"Apr", Apr}, 00406 {""}, {""}, {""}, {""}, 00407 {"Mar", Mar}, 00408 {""}, {""}, {""}, {""}, 00409 {"Aug", Aug}, 00410 {""}, {""}, {""}, {""}, 00411 {"May", May} 00412 }; 00413 00414 if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) 00415 { 00416 register int key = month_hash (str, (unsigned int)len); 00417 00418 if (key <= MAX_HASH_VALUE && key >= 0) 00419 { 00420 register const char *s = wordlist[key].name; 00421 00422 if (*str == *s && !strncmp (str + 1, s + 1, mon.size()-1)) 00423 return wordlist[key].type; 00424 } 00425 } 00426 return Jan; 00427 } 00428 00429 const DayOfWeek& 00430 DateCategory::dayOfWeek() const 00431 { 00432 checkParsed(); 00433 return mDayOfWeek; 00434 } 00435 00436 int& 00437 DateCategory::dayOfMonth() 00438 { 00439 checkParsed(); 00440 return mDayOfMonth; 00441 } 00442 00443 int 00444 DateCategory::dayOfMonth() const 00445 { 00446 checkParsed(); 00447 return mDayOfMonth; 00448 } 00449 00450 Month& 00451 DateCategory::month() 00452 { 00453 checkParsed(); 00454 return mMonth; 00455 } 00456 00457 Month 00458 DateCategory::month() const 00459 { 00460 checkParsed(); 00461 return mMonth; 00462 } 00463 00464 int& 00465 DateCategory::year() 00466 { 00467 checkParsed(); 00468 return mYear; 00469 } 00470 00471 int 00472 DateCategory::year() const 00473 { 00474 checkParsed(); 00475 return mYear; 00476 } 00477 00478 int& 00479 DateCategory::hour() 00480 { 00481 checkParsed(); 00482 return mHour; 00483 } 00484 00485 int 00486 DateCategory::hour() const 00487 { 00488 checkParsed(); 00489 return mHour; 00490 } 00491 00492 int& 00493 DateCategory::minute() 00494 { 00495 checkParsed(); 00496 return mMin; 00497 } 00498 00499 int 00500 DateCategory::minute() const 00501 { 00502 checkParsed(); 00503 return mMin; 00504 } 00505 00506 int& 00507 DateCategory::second() 00508 { 00509 checkParsed(); 00510 return mSec; 00511 } 00512 00513 int 00514 DateCategory::second() const 00515 { 00516 checkParsed(); 00517 return mSec; 00518 } 00519 00520 void 00521 DateCategory::parse(ParseBuffer& pb) 00522 { 00523 // Mon, 04 Nov 2002 17:34:15 GMT 00524 00525 const char* anchor = pb.skipWhitespace(); 00526 00527 pb.skipToChar(Symbols::COMMA[0]); 00528 Data dayOfWeek; 00529 pb.data(dayOfWeek, anchor); 00530 mDayOfWeek = DateCategory::DayOfWeekFromData(dayOfWeek); 00531 00532 pb.skipChar(Symbols::COMMA[0]); 00533 00534 pb.skipWhitespace(); 00535 00536 mDayOfMonth = pb.integer(); 00537 00538 anchor = pb.skipWhitespace(); 00539 pb.skipNonWhitespace(); 00540 00541 Data month; 00542 pb.data(month, anchor); 00543 mMonth = DateCategory::MonthFromData(month); 00544 00545 pb.skipWhitespace(); 00546 mYear = pb.integer(); 00547 00548 pb.skipWhitespace(); 00549 00550 mHour = pb.integer(); 00551 pb.skipChar(Symbols::COLON[0]); 00552 mMin = pb.integer(); 00553 pb.skipChar(Symbols::COLON[0]); 00554 mSec = pb.integer(); 00555 00556 pb.skipWhitespace(); 00557 pb.skipChar('G'); 00558 pb.skipChar('M'); 00559 pb.skipChar('T'); 00560 00561 pb.skipWhitespace(); 00562 pb.assertEof(); 00563 } 00564 00565 ParserCategory* 00566 DateCategory::clone() const 00567 { 00568 return new DateCategory(*this); 00569 } 00570 00571 ParserCategory* 00572 DateCategory::clone(void* location) const 00573 { 00574 return new (location) DateCategory(*this); 00575 } 00576 00577 ParserCategory* 00578 DateCategory::clone(PoolBase* pool) const 00579 { 00580 return new (pool) DateCategory(*this, pool); 00581 } 00582 00583 static void pad2(const int x, EncodeStream& str) 00584 { 00585 if (x < 10) 00586 { 00587 str << Symbols::ZERO[0]; 00588 } 00589 str << x; 00590 } 00591 00592 EncodeStream& 00593 DateCategory::encodeParsed(EncodeStream& str) const 00594 { 00595 str << DayOfWeekData[mDayOfWeek] // Mon 00596 << Symbols::COMMA[0] << Symbols::SPACE[0]; 00597 00598 pad2(mDayOfMonth, str); // 04 00599 00600 str << Symbols::SPACE[0] 00601 << MonthData[mMonth] << Symbols::SPACE[0] // Nov 00602 << mYear << Symbols::SPACE[0]; // 2002 00603 00604 pad2(mHour, str); 00605 str << Symbols::COLON[0]; 00606 pad2(mMin, str); 00607 str << Symbols::COLON[0]; 00608 pad2(mSec, str); 00609 str << " GMT"; 00610 00611 return str; 00612 } 00613 00614 00615 /* ==================================================================== 00616 * The Vovida Software License, Version 1.0 00617 * 00618 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00619 * 00620 * Redistribution and use in source and binary forms, with or without 00621 * modification, are permitted provided that the following conditions 00622 * are met: 00623 * 00624 * 1. Redistributions of source code must retain the above copyright 00625 * notice, this list of conditions and the following disclaimer. 00626 * 00627 * 2. Redistributions in binary form must reproduce the above copyright 00628 * notice, this list of conditions and the following disclaimer in 00629 * the documentation and/or other materials provided with the 00630 * distribution. 00631 * 00632 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00633 * and "Vovida Open Communication Application Library (VOCAL)" must 00634 * not be used to endorse or promote products derived from this 00635 * software without prior written permission. For written 00636 * permission, please contact vocal@vovida.org. 00637 * 00638 * 4. Products derived from this software may not be called "VOCAL", nor 00639 * may "VOCAL" appear in their name, without prior written 00640 * permission of Vovida Networks, Inc. 00641 * 00642 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00643 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00644 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00645 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00646 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00647 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00648 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00649 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00650 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00651 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00652 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00653 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00654 * DAMAGE. 00655 * 00656 * ==================================================================== 00657 * 00658 * This software consists of voluntary contributions made by Vovida 00659 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00660 * Inc. For more information on Vovida Networks, Inc., please see 00661 * <http://www.vovida.org/>. 00662 * 00663 */
1.7.5.1