/* * This file is a part of CMSLU -- Content Management System like Unix * and is not publicly distributed * * Copyright (c) 2008-2009, Tomasz Sowa * All rights reserved. * */ #include #include #include "misc.h" #include "log.h" #include "data.h" void ToString(std::string & s, int value) { static char buffer[50]; sprintf(buffer, "%d", value); s = buffer; } void ToString(std::string & s, long value) { static char buffer[50]; sprintf(buffer, "%ld", value); s = buffer; } bool CorrectUrlChar(char c) { if( (c >= 'a' && c <='z') || (c >= 'A' && c <='Z') || (c >= '0' && c <='9') || (c == '(' || c == ')' || c == '.' || c == ',' || c == '_' ) ) { return true; } return false; } // this function checks how many dots there are in the url // if there are more than one (last) dot then the first dots will be changed into '_' void CorrectUrlDots(std::string & url) { size_t i = url.size(); bool was_dot = false; while( i-- > 0 ) { if( url[i] == '.' ) { if( was_dot ) // only one dot is allowed url[i] = '_'; was_dot = true; } } } void CorrectUrlChars(std::string & url) { std::string::iterator i; for(i=url.begin(); i != url.end() ; ++i) { if( !CorrectUrlChar(*i) ) { int c = ChangeLocalChar(*i); if( CorrectUrlChar(c) ) *i = c; else *i = '_'; } } } void CorrectUrlOnlyAllowedChar(std::string & url) { CorrectUrlDots(url); CorrectUrlChars(url); ToSmall(url); Trim(url, '_'); if( url.empty() || url == "." ) { if( data.item_url_empty.empty() ) url = "unnamed"; else { url = data.item_url_empty; CorrectUrlDots(url); CorrectUrlChars(url); ToSmall(url); // we don't trim here and the string will not be empty } } if( url[0] >= '0' && url[0] <= '9' ) // url must begin with a letter url.insert(url.begin(), '_'); } int polish_letters_simple[] = { 'a', 'A', 'c', 'C', 's', 'S', 'e', 'E', 'l', 'L', 'o', 'O', 'z', 'Z', 'z', 'Z', 'n', 'N', 0 }; // 0 - terminating int polish_letters_iso88592[] = { 0xb1, 0xa1, 0xe6, 0xc6, 0xb6, 0xa6, 0xea, 0xca, 0xb3, 0xa3, 0xf3, 0xd3, 0xbf, 0xaf, 0xbc, 0xac, 0xf1, 0xd1, 0 }; int ChangeLocalChar(unsigned char c) { // if( language == polish_iso88592 ) for(int i = 0 ; polish_letters_iso88592[i] ; ++i) { if( polish_letters_simple[i] == 0 ) { log << log1 << "localization tables don't have the same size" << logend; return c; } if( polish_letters_iso88592[i] == c ) return polish_letters_simple[i]; } return c; } bool HtmlTryChar(std::ostringstream & out, int c) { if( c == '<' ) { out << "<"; return true; } else if( c == '>' ) { out << ">"; return true; } else if( c == '&' ) { out << "&"; return true; } return false; } void HtmlEscape(std::ostringstream & out, const std::string & in) { std::string::const_iterator i; for(i = in.begin() ; i != in.end() ; ++i) { if( !HtmlTryChar(out, *i) ) out << *i; } } std::string HtmlEscape(const std::string & in) { std::ostringstream out; HtmlEscape(out, in); return out.str(); } void HtmlEscapeFormTxt(std::ostringstream & out, const std::string & in) { std::string::const_iterator i; int was_enter = 0; // how many enteres there were before if( in.empty() ) return; out << "

"; // skipping first new line characters for(i = in.begin() ; i != in.end() && (*i==13 || *i==10) ; ++i); for( ; i != in.end() ; ++i ) { if( *i == 13 ) // skipping stupid characters (\r\n\ in dos mode) continue; if( *i == 10 ) { ++was_enter; } else { if( was_enter == 1 ) out << "
\n"; else if( was_enter > 1 ) out << "

\n

"; was_enter = 0; } if( !HtmlTryChar(out, *i) ) out << *i; } out << "

\n"; } std::string HtmlEscapeFormTxt(const std::string & in) { std::ostringstream out; HtmlEscapeFormTxt(out, in); return out.str(); } const char * DateToStr(int year, int month, int day) { static const char * month_letter[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII" }; static char buffer[100]; --month; if( month < 0 ) month = 0; if( month > 11 ) month = 11; if( year == 0 ) sprintf(buffer, "%s %02d", month_letter[month], day); else sprintf(buffer, "%02d %s %02d", year, month_letter[month], day); // warning: not thread safe (we do not use threads) return buffer; } const char * DateToStr(int year, int month, int day, int hour, int min, int sec) { static const char * month_letter[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII" }; static char buffer[100]; --month; if( month < 0 ) month = 0; if( month > 11 ) month = 11; if( year == 0 ) sprintf(buffer, "%s %02d %02d:%02d:%02d", month_letter[month], day, hour, min, sec); else sprintf(buffer, "%02d %s %02d %02d:%02d:%02d", year, month_letter[month], day, hour, min, sec); // warning: not thread safe (we do not use threads) return buffer; } const char * DateToStr(tm * ptm) { return DateToStr(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); } const char * DateToStr(time_t t) { tm * ptm = std::localtime(&t); return DateToStr(ptm); } // this format is used with cookies const char * DateToStrCookie(int year, int month, int day, int hour, int min, int sec) { static const char * month_str[]={ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static char buffer[100]; --month; if( month < 0 ) month = 0; if( month > 11 ) month = 11; sprintf(buffer, "%02d-%s-%04d %02d:%02d:%02d", day, month_str[month], year, hour, min, sec); return buffer; } const char * DateToStrCookie(tm * ptm) { return DateToStrCookie(ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); } const char * DateToStrCookie(time_t t) { tm * ptm = std::localtime(&t); return DateToStrCookie(ptm); } const char * IpToStr(unsigned int ip_) { static char buffer[100]; union { unsigned int ip; unsigned char c[4]; } ip; ip.ip = ip_; sprintf(buffer, "%u.%u.%u.%u", (int)ip.c[0], (int)ip.c[1], (int)ip.c[2], (int)ip.c[3]); return buffer; } const char * ToStr(int value) { static char buffer[100]; sprintf(buffer, "%d", value); return buffer; } bool IsWhite(int s) { if( s==' ' || s=='\t' || s==13 ) return true; return false; } void TrimWhite(std::string & s) { std::string::size_type i; if( s.empty() ) return; // looking for white characters at the end for(i=s.size()-1 ; i>0 && IsWhite(s[i]) ; --i); if( i==0 && IsWhite(s[i]) ) { // the whole string has white characters s.clear(); return; } // deleting white characters at the end if( i != s.size() - 1 ) s.erase(i+1, std::string::npos); // looking for white characters at the beginning for(i=0 ; i0 && s[i]==c ; --i); if( i==0 && s[i]==c ) { // the whole string has the 'c' characters s.clear(); return; } // deleting 'c' characters at the end if( i != s.size() - 1 ) s.erase(i+1, std::string::npos); // looking for the 'c' characters at the beginning for(i=0 ; i='A' && c<='Z' ) c = c - 'A' + 'a'; return c; } void ToSmall(std::string & s) { std::string::size_type i; for(i=0 ; i= 'A' && email[i]<='Z') || (email[i] >= 'a' && email[i]<='z') || (email[i] >= '0' && email[i]<='9') ) { correct = true; } else { for(size_t a=0 ; a < sizeof(allowed_chars)-1 ; ++a) { if( email[i] == allowed_chars[a] ) { correct = true; break; } } } if( email[i] == '@' ) ++at; } if( at != 1 ) return false; return correct; } bool IsFile(const char * file) { struct stat sb; return (stat(file, &sb) == 0); } bool IsFile(const std::string & file) { return IsFile(file.c_str()); } bool CreateDir(const char * dir, int priv) { if( !IsFile(dir) ) { if( mkdir(dir, priv) < 0 ) { log << log1 << "Can't create a directory on fs: " << dir << logend; return false; } } return true; } bool CreateDir(const std::string & dir, int priv) { return CreateDir(dir.c_str(), priv); } // if there is not an extension it returns a pointer to the last '\0' character const char * GetFileExt(const char * name) { size_t i, ilast; // looking for the end of the name for(i=0 ; name[i] != 0 ; ++i); if( i == 0 ) return name; // ops, the name is empty // remember the end of the string ilast = i; // looking for the last dot for(--i ; i>0 && name[i] != '.' ; --i); if( name[i] != '.' ) return name + ilast; // ops, there is not a dot // the extensions starts from i+1 // and can be empty (if the last character is a dot) return name + i + 1; } Item::StaticAuth SelectFileType(const char * file_name) { const char * ext = GetFileExt(file_name); // as an image we're using only those types which can be rendered // by a web browser if( EqualNoCase(ext, "jpg") || EqualNoCase(ext, "gif") || EqualNoCase(ext, "png") ) return Item::static_image; if( EqualNoCase(ext, "pdf") || EqualNoCase(ext, "doc") || EqualNoCase(ext, "xls") || EqualNoCase(ext, "txt") || EqualNoCase(ext, "ods") || EqualNoCase(ext, "odt") ) return Item::static_document; return Item::static_other; }