📄 sys.cpp
字号:
// ------------------------------------------------// File : sys.cpp// Date: 4-apr-2002// Author: giles// Desc: // Sys is a base class for all things systemy, like starting threads, creating sockets etc..// Lock is a very basic cross platform CriticalSection class //// (c) 2002 peercast.org// ------------------------------------------------// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.// ------------------------------------------------#include "common.h"#include "sys.h"#include "socket.h"#include "gnutella.h"#include <stdlib.h>#include <time.h>// -----------------------------------const char *LogBuffer::logTypes[]={ "", "DBUG", "EROR", "GNET", "CHAN",};// -----------------------------------// base64 encode/decode taken from ices2 source.. static char base64table[64] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'};#if 0// -----------------------------------static char *util_base64_encode(char *data){ int len = strlen(data); char *out = malloc(len*4/3 + 4); char *result = out; int chunk; while(len > 0) { chunk = (len >3)?3:len; *out++ = base64table[(*data & 0xFC)>>2]; *out++ = base64table[((*data & 0x03)<<4) | ((*(data+1) & 0xF0) >> 4)]; switch(chunk) { case 3: *out++ = base64table[((*(data+1) & 0x0F)<<2) | ((*(data+2) & 0xC0)>>6)]; *out++ = base64table[(*(data+2)) & 0x3F]; break; case 2: *out++ = base64table[((*(data+1) & 0x0F)<<2)]; *out++ = '='; break; case 1: *out++ = '='; *out++ = '='; break; } data += chunk; len -= chunk; } return result;}#endif// -----------------------------------static int base64chartoval(char input){ if(input >= 'A' && input <= 'Z') return input - 'A'; else if(input >= 'a' && input <= 'z') return input - 'a' + 26; else if(input >= '0' && input <= '9') return input - '0' + 52; else if(input == '+') return 62; else if(input == '/') return 63; else if(input == '=') return -1; else return -2;}// -----------------------------------static char *util_base64_decode(char *input){ return NULL;}// ------------------------------------------Sys::Sys(){ idleSleepTime = 10; logBuf = new LogBuffer(1000,100);}// ------------------------------------------void Sys::sleepIdle(){ sleep(idleSleepTime);}// ------------------------------------------void Host::toResolvedName(char *str){ char hostName[128]; if (ClientSocket::getHostname(hostName,ip)) sprintf(str,"%s:%d",hostName,port); else toStr(str);}// ------------------------------------------bool Host::isLocalhost(){ return loopbackIP(); }// ------------------------------------------void Host::fromStr(char *str){ unsigned int ipb[4]; unsigned int ipp; if (strstr(str,":")) { if (sscanf(str,"%03d.%03d.%03d.%03d:%d",&ipb[0],&ipb[1],&ipb[2],&ipb[3],&ipp) == 5) { ip = ((ipb[0]&0xff) << 24) | ((ipb[1]&0xff) << 16) | ((ipb[2]&0xff) << 8) | ((ipb[3]&0xff)); port = ipp; }else { ip = 0; port = 0; } }else{ if (sscanf(str,"%03d.%03d.%03d.%03d",&ipb[0],&ipb[1],&ipb[2],&ipb[3]) == 4) ip = ((ipb[0]&0xff) << 24) | ((ipb[1]&0xff) << 16) | ((ipb[2]&0xff) << 8) | ((ipb[3]&0xff)); else ip = 0; }}// -----------------------------------bool Host::isMemberOf(Host &h){ if (h.ip==0) return false; if( h.ip0() != 255 && ip0() != h.ip0() ) return false; if( h.ip1() != 255 && ip1() != h.ip1() ) return false; if( h.ip2() != 255 && ip2() != h.ip2() ) return false; if( h.ip3() != 255 && ip3() != h.ip3() ) return false;/* removed for endieness compatibility for(int i=0; i<4; i++) if (h.ipByte[i] != 255) if (ipByte[i] != h.ipByte[i]) return false;*/ return true;}// -----------------------------------char *trimstr(char *s1){ while (*s1) { if ((*s1 == ' ') || (*s1 == '\t')) s1++; else break; } char *s = s1; s1 = s1+strlen(s1); while (*--s1) if ((*s1 != ' ') && (*s1 != '\t')) break; s1[1] = 0; return s;}// -----------------------------------char *stristr(const char *s1, const char *s2){ while (*s1) { if (TOUPPER(*s1) == TOUPPER(*s2)) { const char *c1 = s1; const char *c2 = s2; while (*c1 && *c2) { if (TOUPPER(*c1) != TOUPPER(*c2)) break; c1++; c2++; } if (*c2==0) return (char *)s1; } s1++; } return NULL;}// -----------------------------------bool String::isValidURL(){ return (strnicmp(data,"http://",7)==0) || (strnicmp(data,"mailto:",7)==0);}// -----------------------------------void String::setFromTime(unsigned int t){ char *p = ctime((time_t*)&t); if (p) strcpy(data,p); else strcpy(data,"-"); type = T_ASCII;}// -----------------------------------void String::setFromStopwatch(unsigned int t){ unsigned int sec,min,hour,day; sec = t%60; min = (t/60)%60; hour = (t/3600)%24; day = (t/86400); if (day) sprintf(data,"%d day, %d hour",day,hour); else if (hour) sprintf(data,"%d hour, %d min",hour,min); else if (min) sprintf(data,"%d min, %d sec",min,sec); else if (sec) sprintf(data,"%d sec",sec); else sprintf(data,"-"); type = T_ASCII;}// -----------------------------------void String::setFromString(const char *str, TYPE t){ int cnt=0; bool quote=false; while (*str) { bool add=true; if (*str == '\"') { if (quote) break; else quote = true; add = false; }else if (*str == ' ') { if (!quote) { if (cnt) break; else add = false; } } if (add) { data[cnt++] = *str++; if (cnt >= (MAX_LEN-1)) break; }else str++; } data[cnt] = 0; type = t;}// -----------------------------------int String::base64WordToChars(char *out,const char *input){ char *start = out; signed char vals[4]; vals[0] = base64chartoval(*input++); vals[1] = base64chartoval(*input++); vals[2] = base64chartoval(*input++); vals[3] = base64chartoval(*input++); if(vals[0] < 0 || vals[1] < 0 || vals[2] < -1 || vals[3] < -1) return 0; *out++ = vals[0]<<2 | vals[1]>>4; if(vals[2] >= 0) *out++ = ((vals[1]&0x0F)<<4) | (vals[2]>>2); else *out++ = 0; if(vals[3] >= 0) *out++ = ((vals[2]&0x03)<<6) | (vals[3]); else *out++ = 0; return out-start;}// -----------------------------------void String::BASE642ASCII(const char *input){ char *out = data; int len = strlen(input); while(len >= 4) { out += base64WordToChars(out,input); input += 4; len -= 4; } *out = 0;}// -----------------------------------void String::ASCII2HTML(const char *in){ char *op = data; char *oe = data+MAX_LEN-10; unsigned char c; const char *p = in; while (c = *p++) { if (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) { *op++ = c; }else { sprintf(op,"&#x%02X;",(int)c); op+=6; } if (op >= oe) break; } *op = 0;}// -----------------------------------void String::ASCII2ESC(const char *in, bool safe){ char *op = data; char *oe = data+MAX_LEN-10; const char *p = in; unsigned char c; while (c = *p++) { if (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))) *op++ = c; else { *op++ = '%'; if (safe) *op++ = '%'; *op=0; sprintf(op,"%02X",(int)c); op+=2; } if (op >= oe) break; } *op=0;}// -----------------------------------void String::HTML2ASCII(const char *in){ unsigned char c; char *o = data; char *oe = data+MAX_LEN-10; const char *p = in; while (c = *p++) { if ((c == '&') && (p[0] == '#')) { p++; char code[8]; char *cp = code; char ec = *p++; // hex/dec while (c=*p++) { if (c!=';') *cp++ = c; else break; } *cp = 0; c = (unsigned char)strtoul(code,NULL,ec=='x'?16:10); } *o++ = c; if (o >= oe) break; } *o=0;}// -----------------------------------void String::ESC2ASCII(const char *in){ unsigned char c; char *o = data; char *oe = data+MAX_LEN-10; const char *p = in; while (c = *p++) { if (c == '+') c = ' '; else if (c == '%') { if (p[0] == '%') p++; char hi = TOUPPER(p[0]); char lo = TOUPPER(p[1]); c = (TONIBBLE(hi)<<4) | TONIBBLE(lo); p+=2; } *o++ = c; if (o >= oe) break; } *o=0;}// -----------------------------------void String::ASCII2META(const char *in, bool safe){ char *op = data; char *oe = data+MAX_LEN-10; const char *p = in; unsigned char c; while (c = *p++) { switch (c) { case '%': if (safe) *op++='%'; break; case ';': c = ':'; break; } *op++=c; if (op >= oe) break; } *op=0;}// -----------------------------------void String::convertTo(TYPE t){ if (t != type) { String tmp = *this; // convert to ASCII switch (type) { case T_NONE: case T_ASCII: break; case T_HTML: tmp.HTML2ASCII(data); break; case T_ESC: case T_ESCSAFE: tmp.ESC2ASCII(data); break; case T_META: case T_METASAFE: //tmp.META2ASCII(tmp.data,data); break; case T_BASE64: tmp.BASE642ASCII(data); break; } // convert to new format switch (t) { case T_NONE: case T_ASCII: strcpy(data,tmp.data); break; case T_HTML: ASCII2HTML(tmp.data); break; case T_ESC: ASCII2ESC(tmp.data,false); break; case T_ESCSAFE: ASCII2ESC(tmp.data,true); break; case T_META: ASCII2META(tmp.data,false); break; case T_METASAFE: ASCII2META(tmp.data,true); break; } type = t; }}// -----------------------------------void LogBuffer::write(const char *str, TYPE t){ lock.on(); unsigned int len = strlen(str); int cnt=0; while (len) { unsigned int rlen = len; if (rlen > (lineLen-1)) rlen = lineLen-1; int i = currLine % maxLines; int bp = i*lineLen; strncpy(&buf[bp],str,rlen); buf[bp+rlen] = 0; if (cnt==0) { times[i] = sys->getTime(); types[i] = t; }else { times[i] = 0; types[i] = T_NONE; } currLine++; str += rlen; len -= rlen; cnt++; } lock.off();}// -----------------------------------char *getCGIarg(char *str, char *arg){ if (!str) return NULL; char *s = strstr(str,arg); if (!s) return NULL; s += strlen(arg); return s;}// -----------------------------------bool cmpCGIarg(char *str, char *arg, char *value){ if ((!str) || (!strlen(value))) return false; char *s = strstr(str,arg); if (!s) return false; s += strlen(arg); return strncmp(s,value,strlen(value))==0;}// -----------------------------------bool hasCGIarg(char *str, char *arg){ if (!str) return false; char *s = strstr(str,arg); if (!s) return false; return true;}// ---------------------------void GnuID::encode(Host *h, const char *salt1, const char *salt2, unsigned char salt3){ int s1=0,s2=0; for(int i=0; i<16; i++) { unsigned char ipb = id[i]; // encode with IP address if (h) ipb ^= ((unsigned char *)&h->ip)[i&3]; // add a bit of salt if (salt1) { if (salt1[s1]) ipb ^= salt1[s1++]; else s1=0; } // and some more if (salt2) { if (salt2[s2]) ipb ^= salt2[s2++]; else s2=0; } // plus some pepper ipb ^= salt3; id[i] = ipb; }}// ---------------------------void GnuID::toStr(char *str){ str[0] = 0; for(int i=0; i<16; i++) { char tmp[8]; unsigned char ipb = id[i]; sprintf(tmp,"%02X",ipb); strcat(str,tmp); }}// ---------------------------void GnuID::fromStr(const char *str){ clear(); if (strlen(str) < 32) return; char buf[8]; buf[2] = 0; for(int i=0; i<16; i++) { buf[0] = str[i*2]; buf[1] = str[i*2+1]; id[i] = (unsigned char)strtoul(buf,NULL,16); }}// ---------------------------void GnuID::generate(){ clear(); for(int i=0; i<16; i++) id[i] = sys->rnd(); // its a nasty hack, but it just might work jim. // insert a 6 digit code in the bottom of the ID string // so that we can tell what versions are out there. // also used to detect version changes/fixes in packets. MemoryStream mem(id,16); mem.skip(12); mem.writeLong(PEERCAST_PACKETID);}// ---------------------------int GnuID::getVersion(){ MemoryStream mem(id,16); mem.skip(12); int pid = mem.readLong(); int ver = pid&0xfffff; return ver;}// ---------------------------void GnuIDList::init(int max){ ids = new GnuID[max]; maxID = max; for(int i=0; i<maxID; i++) ids[i].clear();}// ---------------------------bool GnuIDList::contains(GnuID &id){ for(int i=0; i<maxID; i++) if (ids[i].isSame(id)) return true; return false;}// ---------------------------int GnuIDList::numUsed(){ int cnt=0; for(int i=0; i<maxID; i++) if (ids[i].storeTime) cnt++; return cnt;}// ---------------------------unsigned int GnuIDList::getOldest(){ unsigned int t=(unsigned int)-1; for(int i=0; i<maxID; i++) if (ids[i].storeTime) if (ids[i].storeTime < t) t = ids[i].storeTime; return t;}// ---------------------------void GnuIDList::addGnuID(GnuID &id){ unsigned int minTime = (unsigned int) -1; int minIndex = 0; // find oldest for(int i=0; i<maxID; i++) if (ids[i].storeTime <= minTime) { minTime = ids[i].storeTime; minIndex = i; } ids[minIndex] = id; ids[minIndex].storeTime = sys->getTime(); return;}// ---------------------------void GnuIDList::clearAll(){ for(int i=0; i<maxID; i++) ids[i].clear();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -