summaryrefslogtreecommitdiffabout
path: root/lib
authorMichael Krelin <hacker@klever.net>2008-06-29 16:08:01 (UTC)
committer Michael Krelin <hacker@klever.net>2008-06-29 16:11:44 (UTC)
commit12837594b705ad10fdadfd0ba1bfc2249b3b1264 (patch) (side-by-side diff)
treee0502e678b09668ec59828237ebf5972014d0ce0 /lib
parent362678728b8232c9490e14ba14ff323d9a92d6be (diff)
downloadlibopkele-12837594b705ad10fdadfd0ba1bfc2249b3b1264.zip
libopkele-12837594b705ad10fdadfd0ba1bfc2249b3b1264.tar.gz
libopkele-12837594b705ad10fdadfd0ba1bfc2249b3b1264.tar.bz2
Fixed w3c to unix timestamp conversion for FreeBSD
Thanks to Göran Löwkrantz for pointing both to the problem and possible solution. Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (limited to 'lib') (more/less context) (show whitespace changes)
-rw-r--r--lib/util.cc21
1 files changed, 18 insertions, 3 deletions
diff --git a/lib/util.cc b/lib/util.cc
index d979502..a46ba2a 100644
--- a/lib/util.cc
+++ b/lib/util.cc
@@ -77,123 +77,138 @@ namespace opkele {
throw;
}
}
/*
* big numerics
*/
BIGNUM *base64_to_bignum(const string& b64) {
vector<unsigned char> bin;
decode_base64(b64,bin);
BIGNUM *rv = BN_bin2bn(&(bin.front()),bin.size(),0);
if(!rv)
throw failed_conversion(OPKELE_CP_ "failed to BN_bin2bn()");
return rv;
}
BIGNUM *dec_to_bignum(const string& dec) {
BIGNUM *rv = 0;
if(!BN_dec2bn(&rv,dec.c_str()))
throw failed_conversion(OPKELE_CP_ "failed to BN_dec2bn()");
return rv;
}
string bignum_to_base64(const BIGNUM *bn) {
vector<unsigned char> bin(BN_num_bytes(bn)+1);
unsigned char *binptr = &(bin.front())+1;
int l = BN_bn2bin(bn,binptr);
if(l && (*binptr)&0x80){
(*(--binptr)) = 0; ++l;
}
return encode_base64(binptr,l);
}
/*
* w3c times
*/
string time_to_w3c(time_t t) {
struct tm tm_t;
if(!gmtime_r(&t,&tm_t))
throw failed_conversion(OPKELE_CP_ "failed to BN_dec2bn()");
char rv[25];
if(!strftime(rv,sizeof(rv)-1,"%Y-%m-%dT%H:%M:%SZ",&tm_t))
throw failed_conversion(OPKELE_CP_ "failed to strftime()");
return rv;
}
+#ifndef HAVE_TIMEGM
+ static time_t timegm(struct tm *t) {
+ char *tz = getenv("TZ");
+ setenv("TZ","",1); tzset();
+ time_t rv = mktime(t);
+ if(tz)
+ setenv("TZ",tz,1);
+ else
+ unsetenv("TZ");
+ tzset();
+ return rv;
+ }
+# define timegm opkele::util::timegm
+#endif /* HAVE_TIMEGM */
+
time_t w3c_to_time(const string& w) {
int fraction;
struct tm tm_t;
memset(&tm_t,0,sizeof(tm_t));
if( (
sscanf(
w.c_str(),
"%04d-%02d-%02dT%02d:%02d:%02dZ",
&tm_t.tm_year,&tm_t.tm_mon,&tm_t.tm_mday,
&tm_t.tm_hour,&tm_t.tm_min,&tm_t.tm_sec
) != 6
) && (
sscanf(
w.c_str(),
"%04d-%02d-%02dT%02d:%02d:%02d.%03dZ",
&tm_t.tm_year,&tm_t.tm_mon,&tm_t.tm_mday,
&tm_t.tm_hour,&tm_t.tm_min,&tm_t.tm_sec,
&fraction
) != 7
) )
throw failed_conversion(OPKELE_CP_ "failed to sscanf()");
tm_t.tm_mon--;
tm_t.tm_year-=1900;
- time_t rv = mktime(&tm_t);
+ time_t rv = timegm(&tm_t);
if(rv==(time_t)-1)
- throw failed_conversion(OPKELE_CP_ "failed to mktime()");
- return rv-timezone;
+ throw failed_conversion(OPKELE_CP_ "failed to gmtime()");
+ return rv;
}
/*
*
*/
static inline bool isrfc3986unreserved(int c) {
if(c<'-') return false;
if(c<='.') return true;
if(c<'0') return false; if(c<='9') return true;
if(c<'A') return false; if(c<='Z') return true;
if(c<'_') return false;
if(c=='_') return true;
if(c<'a') return false; if(c<='z') return true;
if(c=='~') return true;
return false;
}
struct __url_encoder : public unary_function<char,void> {
public:
string& rv;
__url_encoder(string& r) : rv(r) { }
result_type operator()(argument_type c) {
if(isrfc3986unreserved(c))
rv += c;
else{
char tmp[4];
snprintf(tmp,sizeof(tmp),"%%%02X",
(c&0xff));
rv += tmp;
}
}
};
string url_encode(const string& str) {
string rv;
for_each(str.begin(),str.end(),
__url_encoder(rv));
return rv;
}
string url_decode(const string& str) {
string rv;
back_insert_iterator<string> ii(rv);
for(string::const_iterator i=str.begin(),ie=str.end();
i!=ie;++i) {