OSDN Git Service

FLVの視聴・リレーに対応。
[peercast-im/PeerCastIM.git] / core / common / servmgr.cpp
1 // ------------------------------------------------
2 // File : servmgr.cpp
3 // Date: 4-apr-2002
4 // Author: giles
5 // Desc: 
6 //              Management class for handling multiple servent connections.
7 //
8 // (c) 2002 peercast.org
9 // ------------------------------------------------
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
14
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 // ------------------------------------------------
20
21 #include <stdlib.h>
22 #include "servent.h"
23 #include "servmgr.h"
24 #include "inifile.h"
25 #include "stats.h"
26 #include "peercast.h"
27 #include "pcp.h"
28 #include "atom.h"
29 #include "version2.h"
30 #ifdef _DEBUG
31 #include "chkMemoryLeak.h"
32 #define DEBUG_NEW new(__FILE__, __LINE__)
33 #define new DEBUG_NEW
34 #endif
35
36 ThreadInfo ServMgr::serverThread,ServMgr::idleThread;
37
38 // -----------------------------------
39 ServMgr::ServMgr()
40 {
41         validBCID = NULL;
42
43         authType = AUTH_COOKIE;
44         cookieList.init();
45
46         serventNum = 0;
47
48         startTime = sys->getTime();
49
50         allowServer1 = Servent::ALLOW_ALL;
51         allowServer2 = Servent::ALLOW_BROADCAST;
52
53         clearHostCache(ServHost::T_NONE);
54         password[0]=0;
55
56         allowGnutella = false;
57         useFlowControl = true;
58
59         maxServIn = 50;
60         minGnuIncoming = 10;
61         maxGnuIncoming = 20;
62
63         lastIncoming = 0;
64
65         maxBitrateOut = 540; //JP-Patch 0-> 540
66         maxRelays = MIN_RELAYS;
67         maxDirect = 0;
68         refreshHTML = 1800;
69
70         networkID.clear();
71
72         notifyMask = 0xffff;
73
74         tryoutDelay = 10;
75         numVersions = 0;
76
77         sessionID.generate();
78
79         isDisabled = false;
80         isRoot = false;
81
82         forceIP.clear();
83
84         strcpy(connectHost,"connect1.peercast.org");
85         strcpy(htmlPath,"html/ja");
86
87         rootHost = "yp.peercast.org";
88         rootHost2 = "";
89
90         serverHost.fromStrIP("127.0.0.1",DEFAULT_PORT);
91
92         firewalled = FW_UNKNOWN;                
93         allowDirect = true;
94         autoConnect = true;
95         forceLookup = true;
96         autoServe = true;
97         forceNormal = false;
98
99         maxControl = 3;
100
101         queryTTL = 7;
102
103         totalStreams = 0;
104         firewallTimeout = 30;
105         pauseLog = false;
106         showLog = 0;
107
108         shutdownTimer = 0;
109
110         downloadURL[0] = 0;
111         rootMsg.clear();
112
113
114         restartServer=false;
115
116         setFilterDefaults();
117
118         servents = NULL;
119
120         modulePath[0] = 0; //JP-EX
121         kickPushStartRelays = 1; //JP-EX
122         kickPushInterval = 60; //JP-EX
123         kickPushTime = 0; //JP-EX
124         autoRelayKeep = 2; //JP-EX
125         autoMaxRelaySetting = 0; //JP-EX
126         autoBumpSkipCount = 50; //JP-EX
127         enableGetName = 1; //JP-EX
128         allowConnectPCST = 0; //JP-EX
129         getModulePath = true; //JP-EX
130         clearPLS = false; //JP-EX
131         writeLogFile = false; //JP-EX
132
133         autoPort0Kick = false;
134         allowOnlyVP = false;
135         kickKeepTime = 0;
136         vpDebug = false;
137         saveIniChannel = true;
138         saveGuiPos = false;
139         keepDownstreams = true;
140
141         topmostGui = false;
142         startWithGui = false;
143         preventSS = false;
144         noVersionCheck = false;
145
146         // retrieve newest version number from DNS
147         // for windows ONLY. Linux or other OS is NOT supported.
148 #ifdef WIN32
149         {
150                 struct hostent *he;
151
152                 he = gethostbyname(PCP_CLIENT_VERSION_URL);
153                 if (he && he->h_addrtype == AF_INET)
154                 {
155                         versionDNS = ((struct in_addr*)he->h_addr_list[0])->S_un.S_un_b.s_b3;
156                 } else
157                         versionDNS = 0;
158         }
159 #else
160         versionDNS = 0;
161 #endif
162
163         // init gray/black-lists
164 #ifdef _WIN32
165         IP_graylist = new WTSVector<addrCont>();
166         IP_blacklist = new WTSVector<addrCont>();
167 #else
168         // TODO for linux
169 #endif
170         dosInterval = 30;
171         dosThreashold = 20;
172
173         chanLog="";
174
175         maxRelaysIndexTxt = 1;  // for PCRaw (relay)
176
177         { //JP-MOD
178 #ifdef WIN32
179                 guiSimpleChannelList = false;
180                 guiSimpleConnectionList = false;
181                 guiTopMost = false;
182
183                 guiChanListDisplays = 10;
184                 guiConnListDisplays = 10;
185
186                 guiTitleModify = false;
187                 guiTitleModifyNormal = "PeerCast \8eó\90M:%rx.kbits.1%kbps \91\97\90M:%tx.kbits.1%kbps";
188                 guiTitleModifyMinimized = "R:%rx.kbytes%KB/s T:%tx.kbytes%KB/s";
189
190                 guiAntennaNotifyIcon = false;
191 #endif
192
193                 disableAutoBumpIfDirect = 1;
194                 asxDetailedMode = 1;
195         }
196
197         // start thread (graylist)
198         {
199                 ThreadInfo t;
200
201                 t.func = ServMgr::graylistThreadFunc;
202                 t.active = true;
203                 sys->startThread(&t);
204         }
205 }
206 // -----------------------------------
207 BCID *ServMgr::findValidBCID(int index)
208 {
209         int cnt = 0;
210         BCID *bcid = validBCID;
211         while (bcid)
212         {
213                 if (cnt == index)
214                         return bcid;
215                 cnt++;
216                 bcid=bcid->next;
217         }
218         return 0;
219 }
220 // -----------------------------------
221 BCID *ServMgr::findValidBCID(GnuID &id)
222 {
223         BCID *bcid = validBCID;
224         while (bcid)
225         {
226                 if (bcid->id.isSame(id))
227                         return bcid;
228                 bcid=bcid->next;
229         }
230         return 0;
231 }
232 // -----------------------------------
233 void ServMgr::removeValidBCID(GnuID &id)
234 {
235         BCID *bcid = validBCID,*prev=0;
236         while (bcid)
237         {
238                 if (bcid->id.isSame(id))
239                 {
240                         if (prev)
241                                 prev->next = bcid->next;
242                         else
243                                 validBCID = bcid->next;
244                         return;
245                 }
246                 prev = bcid;
247                 bcid=bcid->next;
248         }
249 }
250 // -----------------------------------
251 void ServMgr::addValidBCID(BCID *bcid)
252 {
253         removeValidBCID(bcid->id);
254
255         bcid->next = validBCID;
256         validBCID = bcid;
257 }
258
259 // -----------------------------------
260 void    ServMgr::connectBroadcaster()
261 {
262         if (!rootHost.isEmpty())
263         {
264                 if (!numUsed(Servent::T_COUT))
265                 {
266                         Servent *sv = allocServent();
267                         if (sv)
268                         {
269                                 sv->initOutgoing(Servent::T_COUT);
270                                 sys->sleep(3000);
271                         }
272                 }
273         }
274 }
275 // -----------------------------------
276 void    ServMgr::addVersion(unsigned int ver)
277 {
278         for(int i=0; i<numVersions; i++)
279                 if (clientVersions[i] == ver)
280                 {
281                         clientCounts[i]++;
282                         return;
283                 }
284
285         if (numVersions < MAX_VERSIONS)
286         {
287                 clientVersions[numVersions] = ver;
288                 clientCounts[numVersions] = 1;
289                 numVersions++;
290         }
291 }
292
293 // -----------------------------------
294 void ServMgr::setFilterDefaults()
295 {
296         numFilters = 0;
297
298         filters[numFilters].host.fromStrIP("255.255.255.255",0);
299 //      filters[numFilters].flags = ServFilter::F_NETWORK|ServFilter::F_DIRECT;
300         filters[numFilters].flags = ServFilter::F_NETWORK;
301
302         numFilters++;
303
304         LOG_DEBUG("numFilters = %d", numFilters);
305 }
306
307 // -----------------------------------
308 void    ServMgr::setPassiveSearch(unsigned int t)
309 {
310 //      if ((t > 0) && (t < 60))
311 //              t = 60;
312 //      passiveSearch = t;
313 }
314 // -----------------------------------
315 bool ServMgr::seenHost(Host &h, ServHost::TYPE type,unsigned int time)
316 {
317         time = sys->getTime()-time;
318
319         for(int i=0; i<MAX_HOSTCACHE; i++)
320                 if (hostCache[i].type == type)
321                         if (hostCache[i].host.ip == h.ip)
322                                 if (hostCache[i].time >= time)
323                                         return true;
324         return false;
325 }
326
327 // -----------------------------------
328 void ServMgr::addHost(Host &h, ServHost::TYPE type, unsigned int time)
329 {
330         int i;
331         if (!h.isValid())
332                 return;
333
334         ServHost *sh=NULL;
335
336         for(i=0; i<MAX_HOSTCACHE; i++)
337                 if (hostCache[i].type == type)
338                         if (hostCache[i].host.isSame(h))
339                         {
340                                 sh = &hostCache[i];
341                                 break;
342                         }
343
344         char str[64];
345         h.toStr(str);
346
347         if (!sh)
348                 LOG_DEBUG("New host: %s - %s",str,ServHost::getTypeStr(type));
349         else
350                 LOG_DEBUG("Old host: %s - %s",str,ServHost::getTypeStr(type));
351
352         h.value = 0;    // make sure dead count is zero
353         if (!sh)
354         {
355
356
357                 // find empty slot
358                 for(i=0; i<MAX_HOSTCACHE; i++)
359                         if (hostCache[i].type == ServHost::T_NONE)
360                         {
361                                 sh = &hostCache[i];
362                                 break;
363                         }
364
365                 // otherwise, find oldest host and replace
366                 if (!sh)
367                         for(i=0; i<MAX_HOSTCACHE; i++)
368                                 if (hostCache[i].type != ServHost::T_NONE)
369                                 {
370                                         if (sh)
371                                         {
372                                                 if (hostCache[i].time < sh->time)
373                                                         sh = &hostCache[i];
374                                         }else{
375                                                 sh = &hostCache[i];
376                                         }
377                                 }
378         }
379
380         if (sh)
381                 sh->init(h,type,time);
382 }
383
384 // -----------------------------------
385 void ServMgr::deadHost(Host &h,ServHost::TYPE t)
386 {
387         for(int i=0; i<MAX_HOSTCACHE; i++)
388                 if (hostCache[i].type == t)
389                         if (hostCache[i].host.ip == h.ip)
390                                 if (hostCache[i].host.port == h.port)
391                                         hostCache[i].init();
392 }
393 // -----------------------------------
394 void ServMgr::clearHostCache(ServHost::TYPE type)
395 {
396         for(int i=0; i<MAX_HOSTCACHE; i++)
397                 if ((hostCache[i].type == type) || (type == ServHost::T_NONE))
398                         hostCache[i].init();
399 }
400         
401 // -----------------------------------
402 unsigned int ServMgr::numHosts(ServHost::TYPE type)
403 {
404         unsigned int cnt = 0;
405         for(int i=0; i<MAX_HOSTCACHE; i++)
406                 if ((hostCache[i].type == type) || (type == ServHost::T_NONE))
407                         cnt++;
408         return cnt;
409 }
410 // -----------------------------------
411 int ServMgr::getNewestServents(Host *hl,int max,Host &rh)
412 {
413         int cnt=0;
414         for(int i=0; i<max; i++)
415         {
416                 // find newest host not in list
417                 ServHost *sh=NULL;
418                 for(int j=0; j<MAX_HOSTCACHE; j++)
419                 {
420                         // find newest servent
421                         if (hostCache[j].type == ServHost::T_SERVENT)
422                                 if (!(rh.globalIP() && !hostCache[j].host.globalIP()))
423                                 {
424                                         // and not in list already
425                                         bool found=false;
426                                         for(int k=0; k<cnt; k++)
427                                                 if (hl[k].isSame(hostCache[j].host))
428                                                 {
429                                                         found=true; 
430                                                         break;
431                                                 }
432
433                                         if (!found)
434                                         {
435                                                 if (!sh)
436                                                 {
437                                                         sh = &hostCache[j];
438                                                 }else{
439                                                         if (hostCache[j].time > sh->time)
440                                                                 sh = &hostCache[j];
441                                                 }
442                                         }
443                                 }
444                 }
445
446                 // add to list
447                 if (sh)
448                         hl[cnt++]=sh->host;
449         }
450         
451         return cnt;
452 }
453 // -----------------------------------
454 ServHost ServMgr::getOutgoingServent(GnuID &netid)
455 {
456         ServHost host;
457
458         Host lh(ClientSocket::getIP(NULL),0);
459
460         // find newest host not in list
461         ServHost *sh=NULL;
462         for(int j=0; j<MAX_HOSTCACHE; j++)
463         {
464                 ServHost *hc=&hostCache[j];
465                 // find newest servent not already connected.
466                 if (hc->type == ServHost::T_SERVENT)
467                 {
468                         if (!((lh.globalIP() && !hc->host.globalIP()) || lh.isSame(hc->host)))
469                         {
470 #if 0
471                                 if (!findServent(Servent::T_OUTGOING,hc->host,netid))
472                                 {
473                                         if (!sh)
474                                         {
475                                                 sh = hc;
476                                         }else{
477                                                 if (hc->time > sh->time)
478                                                         sh = hc;
479                                         }
480                                 }
481 #endif
482                         }
483                 }
484         }
485
486         if (sh)
487                 host = *sh;
488
489         return host;
490 }
491 // -----------------------------------
492 Servent *ServMgr::findOldestServent(Servent::TYPE type, bool priv)
493 {
494         Servent *oldest=NULL;
495
496         Servent *s = servents;
497         while (s)
498         {
499                 if (s->type == type)
500                         if (s->thread.active)
501                                 if (s->isOlderThan(oldest))
502                                         if (s->isPrivate() == priv)
503                                                 oldest = s;
504                 s=s->next;
505         }
506         return oldest;
507 }
508 // -----------------------------------
509 Servent *ServMgr::findServent(Servent::TYPE type, Host &host, GnuID &netid)
510 {
511         lock.on();
512         Servent *s = servents;
513         while (s)
514         {
515                 if (s->type == type)
516                 {
517                         Host h = s->getHost();
518                         if (h.isSame(host) && s->networkID.isSame(netid))
519                         {
520                                 lock.off();
521                                 return s;
522                         }
523                 }
524                 s=s->next;
525         }
526         lock.off();
527         return NULL;
528
529 }
530
531 // -----------------------------------
532 Servent *ServMgr::findServent(unsigned int ip, unsigned short port, GnuID &netid)
533 {
534         lock.on();
535         Servent *s = servents;
536         while (s)
537         {
538                 if (s->type != Servent::T_NONE)
539                 {
540                         Host h = s->getHost();
541                         if ((h.ip == ip) && (h.port == port) && (s->networkID.isSame(netid)))
542                         {
543                                 lock.off();
544                                 return s;
545                         }
546                 }
547                 s=s->next;
548         }
549         lock.off();
550         return NULL;
551
552 }
553
554 // -----------------------------------
555 Servent *ServMgr::findServent(Servent::TYPE t)
556 {
557         Servent *s = servents;
558         while (s)
559         {
560                 if (s->type == t)
561                         return s;
562                 s=s->next;
563         }
564         return NULL;
565 }
566 // -----------------------------------
567 Servent *ServMgr::findServentByIndex(int id)
568 {
569         Servent *s = servents;
570         int cnt=0;
571         while (s)
572         {
573                 if (cnt == id)
574                         return s;
575                         cnt++;
576                 s=s->next;
577         }
578         return NULL;
579 }
580
581 // -----------------------------------
582 Servent *ServMgr::findServentByServentID(int id)
583 {
584         Servent *s = servents;
585         while (s)
586         {
587                 if (id == s->servent_id){
588                         return s;
589                 }
590                 s=s->next;
591         }
592         return NULL;
593 }
594
595 // -----------------------------------
596 Servent *ServMgr::allocServent()
597 {
598         lock.on();
599
600         Servent *s = servents;
601         while (s)
602         {
603                 if (s->status == Servent::S_FREE)
604                         break;
605                 s=s->next;
606         }
607
608         if (!s)
609         {
610                 s = new Servent(++serventNum);
611                 s->next = servents;
612                 servents = s;
613
614                 LOG_DEBUG("allocated servent %d",serventNum);
615         }else
616                 LOG_DEBUG("reused servent %d",s->serventIndex);
617
618
619         s->reset();
620
621         lock.off();
622
623         return s;
624 }
625 // --------------------------------------------------
626 void    ServMgr::closeConnections(Servent::TYPE type)
627 {
628         Servent *sv = servents;
629         while (sv)
630         {
631                 if (sv->isConnected())
632                         if (sv->type == type)
633                                 sv->thread.active = false;
634                 sv=sv->next;
635         }
636 }
637
638 // -----------------------------------
639 unsigned int ServMgr::numConnected(int type,bool priv,unsigned int uptime)
640 {
641         unsigned int cnt=0;
642
643         unsigned int ctime=sys->getTime();
644         Servent *s = servents;
645         while (s)
646         {
647                 if (s->thread.active)
648                         if (s->isConnected())
649                                 if (s->type == type)
650                                         if (s->isPrivate()==priv)
651                                                 if ((ctime-s->lastConnect) >= uptime)
652                                                         cnt++;
653
654                 s=s->next;
655         }
656         return cnt;
657 }
658 // -----------------------------------
659 unsigned int ServMgr::numConnected()
660 {
661         unsigned int cnt=0;
662
663         Servent *s = servents;
664         while (s)
665         {
666                 if (s->thread.active)
667                         if (s->isConnected())
668                                 cnt++;
669
670                 s=s->next;
671         }
672         return cnt;
673 }
674 // -----------------------------------
675 unsigned int ServMgr::numServents()
676 {
677         unsigned int cnt=0;
678
679         Servent *s = servents;
680         while (s)
681         {
682                 cnt++;
683                 s=s->next;
684         }
685         return cnt;
686 }
687
688 // -----------------------------------
689 unsigned int ServMgr::numUsed(int type)
690 {
691         unsigned int cnt=0;
692
693         Servent *s = servents;
694         while (s)
695         {
696                 if (s->type == type)
697                         cnt++;
698                 s=s->next;
699         }
700         return cnt;
701 }
702 // -----------------------------------
703 unsigned int ServMgr::numActiveOnPort(int port)
704 {
705         unsigned int cnt=0;
706
707         Servent *s = servents;
708         while (s)
709         {
710                 if (s->thread.active && s->sock && (s->servPort == port))
711                         cnt++;
712                 s=s->next;
713         }
714         return cnt;
715 }
716 // -----------------------------------
717 unsigned int ServMgr::numActive(Servent::TYPE tp)
718 {
719         unsigned int cnt=0;
720
721         Servent *s = servents;
722         while (s)
723         {
724                 if (s->thread.active && s->sock && (s->type == tp))
725                         cnt++;
726                 s=s->next;
727         }
728         return cnt;
729 }
730
731 // -----------------------------------
732 unsigned int ServMgr::totalOutput(bool all)
733 {
734         unsigned int tot = 0;
735         Servent *s = servents;
736         while (s)
737         {
738                 if (s->isConnected())
739                         if (all || !s->isPrivate())
740                                 if (s->sock)
741                                         tot += s->sock->bytesOutPerSec;
742                 s=s->next;
743         }
744
745         return tot;
746 }
747
748 // -----------------------------------
749 unsigned int ServMgr::totalInput(bool all)
750 {
751         unsigned int tot = 0;
752         Servent *s = servents;
753         while (s)
754         {
755                 if (s->isConnected())
756                         if (all || !s->isPrivate())
757                                 if (s->sock)
758                                         tot += s->sock->bytesInPerSec;
759                 s=s->next;
760         }
761
762         return tot;
763 }
764
765 // -----------------------------------
766 unsigned int ServMgr::numOutgoing()
767 {
768         int cnt=0;
769
770         Servent *s = servents;
771         while (s)
772         {
773 //              if ((s->type == Servent::T_INCOMING) ||
774 //                  (s->type == Servent::T_OUTGOING)) 
775 //                      cnt++;
776                 s=s->next;
777         }
778         return cnt;
779 }
780
781 // -----------------------------------
782 bool ServMgr::seenPacket(GnuPacket &p)
783 {
784         Servent *s = servents;
785         while (s)
786         {
787                 if (s->isConnected())
788                         if (s->seenIDs.contains(p.id))
789                                 return true;
790                 s=s->next;
791         }
792         return false;
793 }
794
795 // -----------------------------------
796 void ServMgr::quit()
797 {
798         LOG_DEBUG("ServMgr is quitting..");
799
800         serverThread.shutdown();
801
802         idleThread.shutdown();
803
804         Servent *s = servents;
805         while (s)
806         {
807                 try
808                 {
809                         if (s->thread.active)
810                         {
811                                 s->thread.shutdown();
812                         }
813
814                 }catch(StreamException &)
815                 {
816                 }
817                 s=s->next;
818         }
819 }
820
821 // -----------------------------------
822 int ServMgr::broadcast(GnuPacket &pack,Servent *src)
823 {
824         int cnt=0;
825         if (pack.ttl)
826         {
827                 Servent *s = servents;
828                 while (s)
829                 {
830
831                         if (s != src)
832                                 if (s->isConnected())
833                                         if (s->type == Servent::T_PGNU)
834                                                 if (!s->seenIDs.contains(pack.id))
835                                                 {
836
837                                                         if (src)
838                                                                 if (!src->networkID.isSame(s->networkID))
839                                                                         continue;
840
841                                                         if (s->outputPacket(pack,false))
842                                                                 cnt++;
843                                                 }
844                         s=s->next;
845                 }
846         }
847
848         LOG_NETWORK("broadcast: %s (%d) to %d servents",GNU_FUNC_STR(pack.func),pack.ttl,cnt);
849
850         return cnt;
851 }
852 // -----------------------------------
853 int ServMgr::route(GnuPacket &pack, GnuID &routeID, Servent *src)
854 {
855         int cnt=0;
856         if (pack.ttl)
857         {
858                 Servent *s = servents;
859                 while (s)
860                 {
861                         if (s != src)
862                                 if (s->isConnected())
863                                         if (s->type == Servent::T_PGNU)
864                                                 if (!s->seenIDs.contains(pack.id))
865                                                         if (s->seenIDs.contains(routeID))
866                                                         {
867                                                                 if (src)
868                                                                         if (!src->networkID.isSame(s->networkID))
869                                                                                 continue;
870
871                                                                 if (s->outputPacket(pack,true))
872                                                                         cnt++;
873                                                         }
874                         s=s->next;
875                 }
876
877         }
878
879         LOG_NETWORK("route: %s (%d) to %d servents",GNU_FUNC_STR(pack.func),pack.ttl,cnt);
880         return cnt;
881 }
882 // -----------------------------------
883 bool ServMgr::checkForceIP()
884 {
885         if (!forceIP.isEmpty())
886         {
887                 unsigned int newIP = ClientSocket::getIP(forceIP.cstr());
888                 if (serverHost.ip != newIP)
889                 {
890                         serverHost.ip = newIP;
891                         char ipstr[64];
892                         serverHost.IPtoStr(ipstr);
893                         LOG_DEBUG("Server IP changed to %s",ipstr);
894                         return true;
895                 }
896         }
897         return false;
898 }
899
900 // -----------------------------------
901 void ServMgr::checkFirewall()
902 {
903         if ((getFirewall() == FW_UNKNOWN) && !servMgr->rootHost.isEmpty())
904         {
905
906                 LOG_DEBUG("Checking firewall..");
907                 Host host;
908                 host.fromStrName(servMgr->rootHost.cstr(),DEFAULT_PORT);
909
910                 ClientSocket *sock = sys->createSocket();
911                 if (!sock)
912                         throw StreamException("Unable to create socket");
913                 sock->setReadTimeout(30000);
914                 sock->open(host);
915                 sock->connect();
916
917                 AtomStream atom(*sock);
918
919                 atom.writeInt(PCP_CONNECT,1);
920
921                 GnuID remoteID;
922                 String agent;
923                 Servent::handshakeOutgoingPCP(atom,sock->host,remoteID,agent,true);
924
925                 atom.writeInt(PCP_QUIT,PCP_ERROR_QUIT);
926
927                 sock->close();
928                 delete sock;
929         }
930 }
931
932 // -----------------------------------
933 void ServMgr::setFirewall(FW_STATE state)
934 {
935         if (firewalled != state)
936         {
937                 char *str;
938                 switch (state)
939                 {
940                         case FW_ON:
941                                 str = "ON";
942                                 break;
943                         case FW_OFF:
944                                 str = "OFF";
945                                 break;
946                         case FW_UNKNOWN:
947                         default:
948                                 str = "UNKNOWN";
949                                 break;
950                 }
951
952                 LOG_DEBUG("Firewall is set to %s",str);
953                 firewalled = state;
954         }
955 }
956 // -----------------------------------
957 bool ServMgr::isFiltered(int fl, Host &h)
958 {
959         for(int i=0; i<numFilters; i++)
960                 if (filters[i].flags & fl)
961                         if (h.isMemberOf(filters[i].host))
962                                 return true;
963
964         return false;
965 }
966
967 #if 0
968 // -----------------------------------
969 bool ServMgr::canServeHost(Host &h)
970 {
971         if (server)
972         {
973                 Host sh = server->getHost();
974
975                 if (sh.globalIP() || (sh.localIP() && h.localIP()))
976                         return true;            
977         }
978         return false;
979 }
980 #endif
981
982 // --------------------------------------------------
983 void writeServerSettings(IniFile &iniFile, unsigned int a)
984 {
985         iniFile.writeBoolValue("allowHTML",a & Servent::ALLOW_HTML);
986         iniFile.writeBoolValue("allowBroadcast",a & Servent::ALLOW_BROADCAST);
987         iniFile.writeBoolValue("allowNetwork",a & Servent::ALLOW_NETWORK);
988         iniFile.writeBoolValue("allowDirect",a & Servent::ALLOW_DIRECT);
989 }
990 // --------------------------------------------------
991 void writeFilterSettings(IniFile &iniFile, ServFilter &f)
992 {
993         char ipstr[64];
994         f.host.IPtoStr(ipstr);
995         iniFile.writeStrValue("ip",ipstr);
996         iniFile.writeBoolValue("private",f.flags & ServFilter::F_PRIVATE);
997         iniFile.writeBoolValue("ban",f.flags & ServFilter::F_BAN);
998         iniFile.writeBoolValue("network",f.flags & ServFilter::F_NETWORK);
999         iniFile.writeBoolValue("direct",f.flags & ServFilter::F_DIRECT);
1000 }
1001
1002 // --------------------------------------------------
1003 static void  writeServHost(IniFile &iniFile, ServHost &sh)
1004 {
1005         iniFile.writeSection("Host");
1006
1007         char ipStr[64];
1008         sh.host.toStr(ipStr);
1009         iniFile.writeStrValue("type",ServHost::getTypeStr(sh.type));
1010         iniFile.writeStrValue("address",ipStr);
1011         iniFile.writeIntValue("time",sh.time);
1012
1013         iniFile.writeLine("[End]");
1014 }
1015
1016 #ifdef WIN32
1017 extern bool guiFlg;
1018 extern WINDOWPLACEMENT winPlace;
1019 extern HWND guiWnd;
1020 #endif
1021
1022 // --------------------------------------------------
1023 void ServMgr::saveSettings(const char *fn)
1024 {
1025         IniFile iniFile;
1026         if (!iniFile.openWriteReplace(fn))
1027         {
1028                 LOG_ERROR("Unable to open ini file");
1029         }else{
1030                 LOG_DEBUG("Saving settings to:  %s",fn);
1031
1032                 char idStr[64];
1033
1034                 iniFile.writeSection("Server");
1035                 iniFile.writeIntValue("serverPort",servMgr->serverHost.port);
1036                 iniFile.writeBoolValue("autoServe",servMgr->autoServe);
1037                 iniFile.writeStrValue("forceIP",servMgr->forceIP);
1038                 iniFile.writeBoolValue("isRoot",servMgr->isRoot);
1039                 iniFile.writeIntValue("maxBitrateOut",servMgr->maxBitrateOut);
1040                 iniFile.writeIntValue("maxRelays",servMgr->maxRelays);
1041                 iniFile.writeIntValue("maxDirect",servMgr->maxDirect);
1042                 iniFile.writeIntValue("maxRelaysPerChannel",chanMgr->maxRelaysPerChannel);
1043                 iniFile.writeIntValue("firewallTimeout",firewallTimeout);
1044                 iniFile.writeBoolValue("forceNormal",forceNormal);
1045                 iniFile.writeStrValue("rootMsg",rootMsg.cstr());
1046                 iniFile.writeStrValue("authType",servMgr->authType==ServMgr::AUTH_COOKIE?"cookie":"http-basic");
1047                 iniFile.writeStrValue("cookiesExpire",servMgr->cookieList.neverExpire==true?"never":"session");
1048                 iniFile.writeStrValue("htmlPath",servMgr->htmlPath);
1049                 iniFile.writeIntValue("minPGNUIncoming",servMgr->minGnuIncoming);
1050                 iniFile.writeIntValue("maxPGNUIncoming",servMgr->maxGnuIncoming);
1051                 iniFile.writeIntValue("maxServIn",servMgr->maxServIn);
1052                 iniFile.writeStrValue("chanLog",servMgr->chanLog.cstr());
1053
1054                 networkID.toStr(idStr);
1055                 iniFile.writeStrValue("networkID",idStr);
1056
1057
1058                 iniFile.writeSection("Broadcast");
1059                 iniFile.writeIntValue("broadcastMsgInterval",chanMgr->broadcastMsgInterval);
1060                 iniFile.writeStrValue("broadcastMsg",chanMgr->broadcastMsg.cstr());
1061                 iniFile.writeIntValue("icyMetaInterval",chanMgr->icyMetaInterval);
1062                 chanMgr->broadcastID.toStr(idStr);
1063                 iniFile.writeStrValue("broadcastID",idStr);             
1064                 iniFile.writeIntValue("hostUpdateInterval",chanMgr->hostUpdateInterval);
1065                 iniFile.writeIntValue("maxControlConnections",servMgr->maxControl);
1066                 iniFile.writeStrValue("rootHost",servMgr->rootHost.cstr());
1067
1068                 iniFile.writeSection("Client");
1069                 iniFile.writeIntValue("refreshHTML",refreshHTML);
1070                 iniFile.writeIntValue("relayBroadcast",servMgr->relayBroadcast);
1071                 iniFile.writeIntValue("minBroadcastTTL",chanMgr->minBroadcastTTL);
1072                 iniFile.writeIntValue("maxBroadcastTTL",chanMgr->maxBroadcastTTL);
1073                 iniFile.writeIntValue("pushTries",chanMgr->pushTries);
1074                 iniFile.writeIntValue("pushTimeout",chanMgr->pushTimeout);
1075                 iniFile.writeIntValue("maxPushHops",chanMgr->maxPushHops);
1076                 iniFile.writeIntValue("autoQuery",chanMgr->autoQuery);
1077                 iniFile.writeIntValue("queryTTL",servMgr->queryTTL);
1078
1079
1080                 iniFile.writeSection("Privacy");
1081                 iniFile.writeStrValue("password",servMgr->password);
1082                 iniFile.writeIntValue("maxUptime",chanMgr->maxUptime);
1083
1084                 //JP-EX
1085                 iniFile.writeSection("Extend");
1086                 iniFile.writeIntValue("autoRelayKeep",servMgr->autoRelayKeep);
1087                 iniFile.writeIntValue("autoMaxRelaySetting",servMgr->autoMaxRelaySetting);
1088                 iniFile.writeIntValue("autoBumpSkipCount",servMgr->autoBumpSkipCount);
1089                 iniFile.writeIntValue("kickPushStartRelays",servMgr->kickPushStartRelays);
1090                 iniFile.writeIntValue("kickPushInterval",servMgr->kickPushInterval);
1091                 iniFile.writeIntValue("allowConnectPCST",servMgr->allowConnectPCST);
1092                 iniFile.writeIntValue("enableGetName",servMgr->enableGetName);
1093
1094                 iniFile.writeIntValue("maxRelaysIndexTxt", servMgr->maxRelaysIndexTxt); // for PCRaw (relay)
1095
1096                 { //JP-MOD
1097                         iniFile.writeIntValue("disableAutoBumpIfDirect",servMgr->disableAutoBumpIfDirect);
1098                         iniFile.writeIntValue("asxDetailedMode",servMgr->asxDetailedMode);
1099
1100                         iniFile.writeSection("PP");
1101 #ifdef WIN32
1102                         iniFile.writeBoolValue("ppClapSound", servMgr->ppClapSound);
1103                         iniFile.writeStrValue("ppClapSoundPath", servMgr->ppClapSoundPath.cstr());
1104 #endif
1105                 }
1106
1107                 //JP-EX
1108                 iniFile.writeSection("Windows");
1109                 iniFile.writeBoolValue("getModulePath",servMgr->getModulePath);
1110                 iniFile.writeBoolValue("clearPLS",servMgr->clearPLS);
1111                 iniFile.writeBoolValue("writeLogFile",servMgr->writeLogFile);
1112
1113                 //VP-EX
1114                 iniFile.writeStrValue("rootHost2",servMgr->rootHost2.cstr());
1115                 iniFile.writeBoolValue("autoPort0Kick",servMgr->autoPort0Kick);
1116                 iniFile.writeBoolValue("allowOnlyVP",servMgr->allowOnlyVP);
1117                 iniFile.writeIntValue("kickKeepTime",servMgr->kickKeepTime);
1118                 iniFile.writeBoolValue("vpDebug", servMgr->vpDebug);
1119                 iniFile.writeBoolValue("saveIniChannel", servMgr->saveIniChannel);
1120 #ifdef WIN32
1121                 iniFile.writeBoolValue("saveGuiPos", servMgr->saveGuiPos);
1122                 if (guiFlg){
1123                         GetWindowPlacement(guiWnd, &winPlace);
1124                         iniFile.writeIntValue("guiTop", winPlace.rcNormalPosition.top);
1125                         iniFile.writeIntValue("guiBottom", winPlace.rcNormalPosition.bottom);
1126                         iniFile.writeIntValue("guiLeft", winPlace.rcNormalPosition.left);
1127                         iniFile.writeIntValue("guiRight", winPlace.rcNormalPosition.right);
1128                 }
1129
1130                 { //JP-MOD
1131                         iniFile.writeBoolValue("guiSimpleChannelList", servMgr->guiSimpleChannelList);
1132                         iniFile.writeBoolValue("guiSimpleConnectionList", servMgr->guiSimpleConnectionList);
1133                         iniFile.writeBoolValue("guiTopMost", servMgr->guiTopMost);
1134
1135                         iniFile.writeIntValue("guiChanListDisplays", servMgr->guiChanListDisplays);
1136                         iniFile.writeIntValue("guiConnListDisplays", servMgr->guiConnListDisplays);
1137
1138                         iniFile.writeBoolValue("guiTitleModify", servMgr->guiTitleModify);
1139                         iniFile.writeStrValue("guiTitleModifyNormal", servMgr->guiTitleModifyNormal.cstr());
1140                         iniFile.writeStrValue("guiTitleModifyMinimized", servMgr->guiTitleModifyMinimized.cstr());
1141
1142                         iniFile.writeBoolValue("guiAntennaNotifyIcon", servMgr->guiAntennaNotifyIcon);
1143                 }
1144
1145                 iniFile.writeBoolValue("topmostGui", servMgr->topmostGui);
1146                 iniFile.writeBoolValue("startWithGui", servMgr->startWithGui);
1147                 iniFile.writeBoolValue("preventSS", servMgr->preventSS);
1148                 iniFile.writeBoolValue("noVersionCheck", servMgr->noVersionCheck);
1149 #endif
1150                 int i;
1151
1152                 for(i=0; i<servMgr->numFilters; i++)
1153                 {
1154                         iniFile.writeSection("Filter");
1155                                 writeFilterSettings(iniFile,servMgr->filters[i]);
1156                         iniFile.writeLine("[End]");
1157                 }
1158
1159                 iniFile.writeSection("Notify");
1160                         iniFile.writeBoolValue("PeerCast",notifyMask&NT_PEERCAST);
1161                         iniFile.writeBoolValue("Broadcasters",notifyMask&NT_BROADCASTERS);
1162                         iniFile.writeBoolValue("TrackInfo",notifyMask&NT_TRACKINFO);
1163                         iniFile.writeBoolValue("Applause",notifyMask&NT_APPLAUSE); //JP-MOD
1164                 iniFile.writeLine("[End]");
1165
1166
1167                 iniFile.writeSection("Server1");
1168                         writeServerSettings(iniFile,allowServer1);
1169                 iniFile.writeLine("[End]");
1170
1171                 iniFile.writeSection("Server2");
1172                         writeServerSettings(iniFile,allowServer2);
1173                 iniFile.writeLine("[End]");
1174
1175
1176
1177                 iniFile.writeSection("Debug");
1178                 iniFile.writeBoolValue("logDebug",(showLog&(1<<LogBuffer::T_DEBUG))!=0);
1179                 iniFile.writeBoolValue("logErrors",(showLog&(1<<LogBuffer::T_ERROR))!=0);
1180                 iniFile.writeBoolValue("logNetwork",(showLog&(1<<LogBuffer::T_NETWORK))!=0);
1181                 iniFile.writeBoolValue("logChannel",(showLog&(1<<LogBuffer::T_CHANNEL))!=0);
1182                 iniFile.writeBoolValue("pauseLog",pauseLog);
1183                 iniFile.writeIntValue("idleSleepTime",sys->idleSleepTime);
1184
1185
1186                 if (servMgr->validBCID)
1187                 {
1188                         BCID *bcid = servMgr->validBCID;
1189                         while (bcid)
1190                         {
1191                                 iniFile.writeSection("ValidBCID");
1192                                 char idstr[128];
1193                                 bcid->id.toStr(idstr);
1194                                 iniFile.writeStrValue("id",idstr);
1195                                 iniFile.writeStrValue("name",bcid->name.cstr());
1196                                 iniFile.writeStrValue("email",bcid->email.cstr());
1197                                 iniFile.writeStrValue("url",bcid->url.cstr());
1198                                 iniFile.writeBoolValue("valid",bcid->valid);
1199                                 iniFile.writeLine("[End]");
1200                                 
1201                                 bcid=bcid->next;
1202                         }
1203                 }
1204
1205                 if (servMgr->saveIniChannel){
1206                         Channel *c = chanMgr->channel;
1207                         while (c)
1208                         {
1209                                 char idstr[64];
1210                                 if (c->isActive() && c->stayConnected)
1211                                 {
1212                                         c->getIDStr(idstr);
1213
1214                                         iniFile.writeSection("RelayChannel");
1215                                         iniFile.writeStrValue("name",c->getName());
1216                                         iniFile.writeStrValue("genre",c->info.genre.cstr());
1217                                         if (!c->sourceURL.isEmpty())
1218                                                 iniFile.writeStrValue("sourceURL",c->sourceURL.cstr());
1219                                         iniFile.writeStrValue("sourceProtocol",ChanInfo::getProtocolStr(c->info.srcProtocol));
1220                                         iniFile.writeStrValue("contentType",c->info.getTypeStr());
1221                                         iniFile.writeIntValue("bitrate",c->info.bitrate);
1222                                         iniFile.writeStrValue("contactURL",c->info.url.cstr());
1223                                         iniFile.writeStrValue("id",idstr);
1224                                         iniFile.writeBoolValue("stayConnected",c->stayConnected);
1225
1226                                         ChanHitList *chl = chanMgr->findHitListByID(c->info.id);
1227                                         if (chl)
1228                                         {
1229
1230                                                 ChanHitSearch chs;
1231                                                 chs.trackersOnly = true;
1232                                                 if (chl->pickHits(chs))
1233                                                 {
1234                                                         char ipStr[64];
1235                                                         chs.best[0].host.toStr(ipStr);
1236                                                         iniFile.writeStrValue("tracker",ipStr);
1237                                                 }
1238                                         }
1239                                         iniFile.writeLine("[End]");
1240                                 }
1241                                 c=c->next;
1242                         }
1243                 }
1244                 
1245
1246                 
1247 #if 0
1248                 Servent *s = servents;
1249                 while (s)
1250                 {
1251                         if (s->type == Servent::T_OUTGOING)
1252                                 if (s->isConnected())
1253                                 {
1254                                         ServHost sh;
1255                                         Host h = s->getHost();
1256                                         sh.init(h,ServHost::T_SERVENT,0,s->networkID);
1257                                         writeServHost(iniFile,sh);
1258                                 }
1259                         s=s->next;
1260                 }
1261 #endif
1262
1263                 for(i=0; i<ServMgr::MAX_HOSTCACHE; i++)
1264                 {
1265                         ServHost *sh = &servMgr->hostCache[i];
1266                         if (sh->type != ServHost::T_NONE)
1267                                 writeServHost(iniFile,*sh);
1268                 }
1269
1270                 iniFile.close();
1271         }
1272 }
1273 // --------------------------------------------------
1274 unsigned int readServerSettings(IniFile &iniFile, unsigned int a)
1275 {
1276         while (iniFile.readNext())
1277         {
1278                 if (iniFile.isName("[End]"))
1279                         break;
1280                 else if (iniFile.isName("allowHTML"))
1281                         a = iniFile.getBoolValue()?a|Servent::ALLOW_HTML:a&~Servent::ALLOW_HTML;
1282                 else if (iniFile.isName("allowDirect"))
1283                         a = iniFile.getBoolValue()?a|Servent::ALLOW_DIRECT:a&~Servent::ALLOW_DIRECT;
1284                 else if (iniFile.isName("allowNetwork"))
1285                         a = iniFile.getBoolValue()?a|Servent::ALLOW_NETWORK:a&~Servent::ALLOW_NETWORK;
1286                 else if (iniFile.isName("allowBroadcast"))
1287                         a = iniFile.getBoolValue()?a|Servent::ALLOW_BROADCAST:a&~Servent::ALLOW_BROADCAST;
1288         }
1289         return a;
1290 }
1291 // --------------------------------------------------
1292 void readFilterSettings(IniFile &iniFile, ServFilter &sv)
1293 {
1294         sv.host.init();
1295
1296         while (iniFile.readNext())
1297         {
1298                 if (iniFile.isName("[End]"))
1299                         break;
1300                 else if (iniFile.isName("ip"))
1301                         sv.host.fromStrIP(iniFile.getStrValue(),0);
1302                 else if (iniFile.isName("private"))
1303                         sv.flags = (sv.flags & ~ServFilter::F_PRIVATE) | (iniFile.getBoolValue()?ServFilter::F_PRIVATE:0);
1304                 else if (iniFile.isName("ban"))
1305                         sv.flags = (sv.flags & ~ServFilter::F_BAN) | (iniFile.getBoolValue()?ServFilter::F_BAN:0);
1306                 else if (iniFile.isName("allow") || iniFile.isName("network"))
1307                         sv.flags = (sv.flags & ~ServFilter::F_NETWORK) | (iniFile.getBoolValue()?ServFilter::F_NETWORK:0);
1308                 else if (iniFile.isName("direct"))
1309                         sv.flags = (sv.flags & ~ServFilter::F_DIRECT) | (iniFile.getBoolValue()?ServFilter::F_DIRECT:0);
1310         }
1311
1312 }
1313 // --------------------------------------------------
1314 void ServMgr::loadSettings(const char *fn)
1315 {
1316         IniFile iniFile;
1317
1318         if (!iniFile.openReadOnly(fn))
1319                 saveSettings(fn);
1320
1321
1322         servMgr->numFilters = 0;
1323         showLog = 0;
1324
1325         if (iniFile.openReadOnly(fn))
1326         {
1327                 while (iniFile.readNext())
1328                 {
1329                         // server settings
1330                         if (iniFile.isName("serverPort"))
1331                                 servMgr->serverHost.port = iniFile.getIntValue();
1332                         else if (iniFile.isName("autoServe"))
1333                                 servMgr->autoServe = iniFile.getBoolValue();
1334                         else if (iniFile.isName("autoConnect"))
1335                                 servMgr->autoConnect = iniFile.getBoolValue();
1336                         else if (iniFile.isName("icyPassword"))         // depreciated
1337                                 strcpy(servMgr->password,iniFile.getStrValue());
1338                         else if (iniFile.isName("forceIP"))
1339                                 servMgr->forceIP = iniFile.getStrValue();
1340                         else if (iniFile.isName("isRoot"))
1341                                 servMgr->isRoot = iniFile.getBoolValue();
1342                         else if (iniFile.isName("broadcastID"))
1343                         {
1344                                 chanMgr->broadcastID.fromStr(iniFile.getStrValue());
1345                                 chanMgr->broadcastID.id[0] = PCP_BROADCAST_FLAGS;                       // hacky, but we need to fix old clients
1346
1347                         }else if (iniFile.isName("htmlPath"))
1348                                 strcpy(servMgr->htmlPath,iniFile.getStrValue());
1349                         else if (iniFile.isName("maxPGNUIncoming"))
1350                                 servMgr->maxGnuIncoming = iniFile.getIntValue();
1351                         else if (iniFile.isName("minPGNUIncoming"))
1352                                 servMgr->minGnuIncoming = iniFile.getIntValue();
1353
1354                         else if (iniFile.isName("maxControlConnections"))
1355                         {
1356                                 servMgr->maxControl = iniFile.getIntValue();
1357
1358                         }
1359                         else if (iniFile.isName("maxBitrateOut"))
1360                                 servMgr->maxBitrateOut = iniFile.getIntValue();
1361
1362                         else if (iniFile.isName("maxStreamsOut"))               // depreciated
1363                                 servMgr->setMaxRelays(iniFile.getIntValue());
1364                         else if (iniFile.isName("maxRelays"))           
1365                                 servMgr->setMaxRelays(iniFile.getIntValue());
1366                         else if (iniFile.isName("maxDirect"))           
1367                                 servMgr->maxDirect = iniFile.getIntValue();
1368
1369                         else if (iniFile.isName("maxStreamsPerChannel"))                // depreciated
1370                                 chanMgr->maxRelaysPerChannel = iniFile.getIntValue();
1371                         else if (iniFile.isName("maxRelaysPerChannel"))
1372                                 chanMgr->maxRelaysPerChannel = iniFile.getIntValue();
1373
1374                         else if (iniFile.isName("firewallTimeout"))
1375                                 firewallTimeout = iniFile.getIntValue();
1376                         else if (iniFile.isName("forceNormal"))
1377                                 forceNormal = iniFile.getBoolValue();
1378                         else if (iniFile.isName("broadcastMsgInterval"))
1379                                 chanMgr->broadcastMsgInterval = iniFile.getIntValue();
1380                         else if (iniFile.isName("broadcastMsg"))
1381                                 chanMgr->broadcastMsg.set(iniFile.getStrValue(),String::T_ASCII);
1382                         else if (iniFile.isName("hostUpdateInterval"))
1383                                 chanMgr->hostUpdateInterval = iniFile.getIntValue();
1384                         else if (iniFile.isName("icyMetaInterval"))
1385                                 chanMgr->icyMetaInterval = iniFile.getIntValue();
1386                         else if (iniFile.isName("maxServIn"))
1387                                 servMgr->maxServIn = iniFile.getIntValue();
1388                         else if (iniFile.isName("chanLog"))
1389                                 servMgr->chanLog.set(iniFile.getStrValue(),String::T_ASCII);
1390
1391                         else if (iniFile.isName("rootMsg"))
1392                                 rootMsg.set(iniFile.getStrValue());
1393                         else if (iniFile.isName("networkID"))
1394                                 networkID.fromStr(iniFile.getStrValue());
1395                         else if (iniFile.isName("authType"))
1396                         {
1397                                 char *t = iniFile.getStrValue();
1398                                 if (stricmp(t,"cookie")==0)
1399                                         servMgr->authType = ServMgr::AUTH_COOKIE;
1400                                 else if (stricmp(t,"http-basic")==0)
1401                                         servMgr->authType = ServMgr::AUTH_HTTPBASIC;
1402                         }else if (iniFile.isName("cookiesExpire"))
1403                         {
1404                                 char *t = iniFile.getStrValue();
1405                                 if (stricmp(t,"never")==0)
1406                                         servMgr->cookieList.neverExpire = true;
1407                                 else if (stricmp(t,"session")==0)
1408                                         servMgr->cookieList.neverExpire = false;
1409
1410
1411                         }
1412
1413                         // privacy settings
1414                         else if (iniFile.isName("password"))
1415                                 strcpy(servMgr->password,iniFile.getStrValue());
1416                         else if (iniFile.isName("maxUptime"))
1417                                 chanMgr->maxUptime = iniFile.getIntValue();
1418
1419                         // client settings
1420
1421                         else if (iniFile.isName("rootHost"))
1422                         {
1423                                 if (!PCP_FORCE_YP)
1424                                         servMgr->rootHost = iniFile.getStrValue();
1425
1426                         }else if (iniFile.isName("deadHitAge"))
1427                                 chanMgr->deadHitAge = iniFile.getIntValue();
1428                         else if (iniFile.isName("tryoutDelay"))
1429                                 servMgr->tryoutDelay = iniFile.getIntValue();
1430                         else if (iniFile.isName("refreshHTML"))
1431                                 refreshHTML = iniFile.getIntValue();
1432                         else if (iniFile.isName("relayBroadcast"))
1433                         {
1434                                 servMgr->relayBroadcast = iniFile.getIntValue();
1435                                 if (servMgr->relayBroadcast < 30)
1436                                         servMgr->relayBroadcast = 30;
1437                         }
1438                         else if (iniFile.isName("minBroadcastTTL"))
1439                                 chanMgr->minBroadcastTTL = iniFile.getIntValue();
1440                         else if (iniFile.isName("maxBroadcastTTL"))
1441                                 chanMgr->maxBroadcastTTL = iniFile.getIntValue();
1442                         else if (iniFile.isName("pushTimeout"))
1443                                 chanMgr->pushTimeout = iniFile.getIntValue();
1444                         else if (iniFile.isName("pushTries"))
1445                                 chanMgr->pushTries = iniFile.getIntValue();
1446                         else if (iniFile.isName("maxPushHops"))
1447                                 chanMgr->maxPushHops = iniFile.getIntValue();
1448                         else if (iniFile.isName("autoQuery"))
1449                         {
1450                                 chanMgr->autoQuery = iniFile.getIntValue();
1451                                 if ((chanMgr->autoQuery < 300) && (chanMgr->autoQuery > 0))
1452                                         chanMgr->autoQuery = 300;
1453                         }
1454                         else if (iniFile.isName("queryTTL"))
1455                         {
1456                                 servMgr->queryTTL = iniFile.getIntValue();
1457                         }
1458
1459                         //JP-Extend
1460                         else if (iniFile.isName("autoRelayKeep"))
1461                                 servMgr->autoRelayKeep = iniFile.getIntValue();
1462                         else if (iniFile.isName("autoMaxRelaySetting"))
1463                                 servMgr->autoMaxRelaySetting = iniFile.getIntValue();
1464                         else if (iniFile.isName("autoBumpSkipCount"))
1465                                 servMgr->autoBumpSkipCount = iniFile.getIntValue();
1466                         else if (iniFile.isName("kickPushStartRelays"))
1467                                 servMgr->kickPushStartRelays = iniFile.getIntValue();
1468                         else if (iniFile.isName("kickPushInterval"))
1469                         {
1470                                 servMgr->kickPushInterval = iniFile.getIntValue();
1471                                 if (servMgr->kickPushInterval < 60)
1472                                         servMgr->kickPushInterval = 0;
1473                         }
1474                         else if (iniFile.isName("allowConnectPCST"))
1475                                 servMgr->allowConnectPCST = iniFile.getIntValue();
1476                         else if (iniFile.isName("enableGetName"))
1477                                 servMgr->enableGetName = iniFile.getIntValue();
1478
1479                         else if (iniFile.isName("maxRelaysIndexTxt"))                   // for PCRaw (relay)
1480                                 servMgr->maxRelaysIndexTxt = iniFile.getIntValue();
1481
1482                         //JP-MOD
1483                         else if (iniFile.isName("disableAutoBumpIfDirect"))
1484                                 servMgr->disableAutoBumpIfDirect = iniFile.getIntValue();
1485                         else if (iniFile.isName("asxDetailedMode"))
1486                                 servMgr->asxDetailedMode = iniFile.getIntValue();
1487
1488 #ifdef WIN32
1489                         else if (iniFile.isName("ppClapSound"))
1490                                 servMgr->ppClapSound = iniFile.getBoolValue();
1491                         else if (iniFile.isName("ppClapSoundPath"))
1492                                 servMgr->ppClapSoundPath.set(iniFile.getStrValue(),String::T_ASCII);
1493 #endif
1494
1495                         //JP-Windows
1496                         else if (iniFile.isName("getModulePath"))
1497                                 servMgr->getModulePath = iniFile.getBoolValue();
1498                         else if (iniFile.isName("clearPLS"))
1499                                 servMgr->clearPLS = iniFile.getBoolValue();
1500                         else if (iniFile.isName("writeLogFile"))
1501                                 servMgr->writeLogFile = iniFile.getBoolValue();
1502
1503                         //VP-EX
1504                         else if (iniFile.isName("rootHost2"))
1505                         {
1506                                 if (!PCP_FORCE_YP)
1507                                         servMgr->rootHost2 = iniFile.getStrValue();
1508                         }
1509                         else if (iniFile.isName("autoPort0Kick"))
1510                                 servMgr->autoPort0Kick = iniFile.getBoolValue();
1511                         else if (iniFile.isName("allowOnlyVP"))
1512                                 servMgr->allowOnlyVP = iniFile.getBoolValue();
1513                         else if (iniFile.isName("kickKeepTime"))
1514                                 servMgr->kickKeepTime = iniFile.getIntValue();
1515                         else if (iniFile.isName("vpDebug"))
1516                                 servMgr->vpDebug = iniFile.getBoolValue();
1517                         else if (iniFile.isName("saveIniChannel"))
1518                                 servMgr->saveIniChannel = iniFile.getBoolValue();
1519 #ifdef WIN32
1520                         else if (iniFile.isName("saveGuiPos"))
1521                                 servMgr->saveGuiPos = iniFile.getBoolValue();
1522                         else if (iniFile.isName("guiTop"))
1523                                 winPlace.rcNormalPosition.top = iniFile.getIntValue();
1524                         else if (iniFile.isName("guiBottom"))
1525                                 winPlace.rcNormalPosition.bottom = iniFile.getIntValue();
1526                         else if (iniFile.isName("guiLeft"))
1527                                 winPlace.rcNormalPosition.left = iniFile.getIntValue();
1528                         else if (iniFile.isName("guiRight")){
1529                                 winPlace.rcNormalPosition.right = iniFile.getIntValue();
1530                                 winPlace.length = sizeof(winPlace);
1531                                 winPlace.flags = 0;
1532                                 winPlace.showCmd = 1;
1533                                 winPlace.ptMinPosition.x = -1;
1534                                 winPlace.ptMinPosition.y = -1;
1535                                 winPlace.ptMaxPosition.x = -1;
1536                                 winPlace.ptMaxPosition.y = -1;
1537                                 if (servMgr->saveGuiPos){
1538                                         guiFlg = true;
1539                                 }
1540                         }else if (iniFile.isName("guiSimpleChannelList")) //JP-MOD
1541                                 servMgr->guiSimpleChannelList = iniFile.getBoolValue();
1542                         else if (iniFile.isName("guiSimpleConnectionList")) //JP-MOD
1543                                 servMgr->guiSimpleConnectionList = iniFile.getBoolValue();
1544                         else if (iniFile.isName("guiTopMost")) //JP-MOD
1545                                 servMgr->guiTopMost = iniFile.getBoolValue();
1546                         else if (iniFile.isName("guiChanListDisplays")) //JP-MOD
1547                                 servMgr->guiChanListDisplays = iniFile.getIntValue();
1548                         else if (iniFile.isName("guiConnListDisplays")) //JP-MOD
1549                                 servMgr->guiConnListDisplays = iniFile.getIntValue();
1550                         else if (iniFile.isName("guiTitleModify")) //JP-MOD
1551                                 servMgr->guiTitleModify = iniFile.getBoolValue();
1552                         else if (iniFile.isName("guiTitleModifyNormal")) //JP-MOD
1553                                 servMgr->guiTitleModifyNormal.set(iniFile.getStrValue(),String::T_ASCII);
1554                         else if (iniFile.isName("guiTitleModifyMinimized")) //JP-MOD
1555                                 servMgr->guiTitleModifyMinimized.set(iniFile.getStrValue(),String::T_ASCII);
1556                         else if (iniFile.isName("guiAntennaNotifyIcon")) //JP-MOD
1557                                 servMgr->guiAntennaNotifyIcon = iniFile.getBoolValue();
1558
1559                         else if (iniFile.isName("topmostGui"))
1560                                 servMgr->topmostGui = iniFile.getBoolValue();
1561                         else if (iniFile.isName("startWithGui"))
1562                                 servMgr->startWithGui = iniFile.getBoolValue();
1563                         else if (iniFile.isName("preventSS"))
1564                                 servMgr->preventSS = iniFile.getBoolValue();
1565                         else if (iniFile.isName("noVersionCheck"))
1566                                 servMgr->noVersionCheck = iniFile.getBoolValue();
1567 #endif
1568
1569                         // debug
1570                         else if (iniFile.isName("logDebug"))
1571                                 showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_DEBUG:0;
1572                         else if (iniFile.isName("logErrors"))
1573                                 showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_ERROR:0;
1574                         else if (iniFile.isName("logNetwork"))
1575                                 showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_NETWORK:0;
1576                         else if (iniFile.isName("logChannel"))
1577                                 showLog |= iniFile.getBoolValue() ? 1<<LogBuffer::T_CHANNEL:0;
1578                         else if (iniFile.isName("pauseLog"))
1579                                 pauseLog = iniFile.getBoolValue();
1580                         else if (iniFile.isName("idleSleepTime"))
1581                                 sys->idleSleepTime = iniFile.getIntValue();
1582                         else if (iniFile.isName("[Server1]"))
1583                                 allowServer1 = readServerSettings(iniFile,allowServer1);
1584                         else if (iniFile.isName("[Server2]"))
1585                                 allowServer2 = readServerSettings(iniFile,allowServer2);
1586                         else if (iniFile.isName("[Filter]"))
1587                         {
1588                                 readFilterSettings(iniFile,filters[numFilters]);
1589
1590                                 if (numFilters < (MAX_FILTERS-1))
1591                                         numFilters++;
1592                                 LOG_DEBUG("*** numFilters = %d", numFilters);
1593                         }
1594                         else if (iniFile.isName("[Notify]"))
1595                         {
1596                                 notifyMask = NT_UPGRADE;
1597                                 while (iniFile.readNext())
1598                                 {
1599                                         if (iniFile.isName("[End]"))
1600                                                 break;
1601                                         else if (iniFile.isName("PeerCast"))
1602                                                 notifyMask |= iniFile.getBoolValue()?NT_PEERCAST:0;
1603                                         else if (iniFile.isName("Broadcasters"))
1604                                                 notifyMask |= iniFile.getBoolValue()?NT_BROADCASTERS:0;
1605                                         else if (iniFile.isName("TrackInfo"))
1606                                                 notifyMask |= iniFile.getBoolValue()?NT_TRACKINFO:0;
1607                                         else if (iniFile.isName("Applause")) //JP-MOD
1608                                                 notifyMask |= iniFile.getBoolValue()?NT_APPLAUSE:0;
1609                                 }
1610
1611                         }
1612                         else if (iniFile.isName("[RelayChannel]"))
1613                         {
1614                                 ChanInfo info;
1615                                 bool stayConnected=false;
1616                                 String sourceURL;
1617                                 while (iniFile.readNext())
1618                                 {
1619                                         if (iniFile.isName("[End]"))
1620                                                 break;
1621                                         else if (iniFile.isName("name"))
1622                                                 info.name.set(iniFile.getStrValue());
1623                                         else if (iniFile.isName("id"))
1624                                                 info.id.fromStr(iniFile.getStrValue());
1625                                         else if (iniFile.isName("sourceType"))
1626                                                 info.srcProtocol = ChanInfo::getProtocolFromStr(iniFile.getStrValue());
1627                                         else if (iniFile.isName("contentType"))
1628                                                 info.contentType = ChanInfo::getTypeFromStr(iniFile.getStrValue());
1629                                         else if (iniFile.isName("stayConnected"))
1630                                                 stayConnected = iniFile.getBoolValue();
1631                                         else if (iniFile.isName("sourceURL"))
1632                                                 sourceURL.set(iniFile.getStrValue());
1633                                         else if (iniFile.isName("genre"))
1634                                                 info.genre.set(iniFile.getStrValue());
1635                                         else if (iniFile.isName("contactURL"))
1636                                                 info.url.set(iniFile.getStrValue());
1637                                         else if (iniFile.isName("bitrate"))
1638                                                 info.bitrate = atoi(iniFile.getStrValue());
1639                                         else if (iniFile.isName("tracker"))
1640                                         {
1641                                                 ChanHit hit;
1642                                                 hit.init();
1643                                                 hit.tracker = true;
1644                                                 hit.host.fromStrName(iniFile.getStrValue(),DEFAULT_PORT);
1645                                                 hit.rhost[0] = hit.host;
1646                                                 hit.rhost[1] = hit.host;
1647                                                 hit.chanID = info.id;
1648                                                 hit.recv = true;
1649                                                 chanMgr->addHit(hit);
1650                                         }
1651
1652                                 }
1653                                 if (sourceURL.isEmpty())
1654                                 {
1655                                         chanMgr->createRelay(info,stayConnected);
1656                                 }else
1657                                 {
1658                                         info.bcID = chanMgr->broadcastID;
1659                                         Channel *c = chanMgr->createChannel(info,NULL);
1660                                         if (c)
1661                                                 c->startURL(sourceURL.cstr());
1662                                 }
1663                         } else if (iniFile.isName("[Host]"))
1664                         {
1665                                 Host h;
1666                                 ServHost::TYPE type=ServHost::T_NONE;
1667                                 bool firewalled=false;
1668                                 unsigned int time=0;
1669                                 while (iniFile.readNext())
1670                                 {
1671                                         if (iniFile.isName("[End]"))
1672                                                 break;
1673                                         else if (iniFile.isName("address"))
1674                                                 h.fromStrIP(iniFile.getStrValue(),DEFAULT_PORT);
1675                                         else if (iniFile.isName("type"))
1676                                                 type = ServHost::getTypeFromStr(iniFile.getStrValue());
1677                                         else if (iniFile.isName("time"))
1678                                                 time = iniFile.getIntValue();
1679                                 }
1680                                 servMgr->addHost(h,type,time);
1681
1682                         } else if (iniFile.isName("[ValidBCID]"))
1683                         {
1684                                 BCID *bcid = new BCID();
1685                                 while (iniFile.readNext())
1686                                 {
1687                                         if (iniFile.isName("[End]"))
1688                                                 break;
1689                                         else if (iniFile.isName("id"))
1690                                                 bcid->id.fromStr(iniFile.getStrValue());
1691                                         else if (iniFile.isName("name"))
1692                                                 bcid->name.set(iniFile.getStrValue());
1693                                         else if (iniFile.isName("email"))
1694                                                 bcid->email.set(iniFile.getStrValue());
1695                                         else if (iniFile.isName("url"))
1696                                                 bcid->url.set(iniFile.getStrValue());
1697                                         else if (iniFile.isName("valid"))
1698                                                 bcid->valid = iniFile.getBoolValue();
1699                                 }
1700                                 servMgr->addValidBCID(bcid);
1701                         }
1702                 }       
1703         }
1704
1705         if (!numFilters)
1706                 setFilterDefaults();
1707
1708         LOG_DEBUG("numFilters = %d", numFilters);
1709 }
1710
1711 // --------------------------------------------------
1712 unsigned int ServMgr::numStreams(GnuID &cid, Servent::TYPE tp, bool all)
1713 {
1714         int cnt = 0;
1715         Servent *sv = servents;
1716         while (sv)
1717         {
1718                 if (sv->isConnected())
1719                         if (sv->type == tp)
1720                                 if (sv->chanID.isSame(cid))
1721                                         if (all || !sv->isPrivate())
1722                                                 cnt++;
1723                 sv=sv->next;
1724         }
1725         return cnt;
1726 }
1727 // --------------------------------------------------
1728 unsigned int ServMgr::numStreams(Servent::TYPE tp, bool all)
1729 {
1730         int cnt = 0;
1731         Servent *sv = servents;
1732         while (sv)
1733         {
1734                 if (sv->isConnected())
1735                         if (sv->type == tp)
1736                                 if (all || !sv->isPrivate())
1737                                 {
1738                                         // for PCRaw (relay) start.
1739                                         if(tp == Servent::T_RELAY)
1740                                         {
1741                                                 Channel *ch = chanMgr->findChannelByID(sv->chanID);
1742
1743                                                 // index.txt\82Í\83J\83E\83\93\83g\82µ\82È\82¢
1744                                                 if(!isIndexTxt(ch))
1745                                                         cnt++;
1746                                         }
1747                                         else
1748                                         // for PCRaw (relay) end.
1749                                         {
1750                                                 cnt++;
1751                                         }
1752                                 }
1753                 sv=sv->next;
1754         }
1755         return cnt;
1756 }
1757
1758 // --------------------------------------------------
1759 bool ServMgr::getChannel(char *str,ChanInfo &info, bool relay)
1760 {
1761         // remove file extension (only added for winamp)
1762         //char *ext = strstr(str,".");
1763         //if (ext) *ext = 0;
1764
1765         procConnectArgs(str,info);
1766
1767         WLockBlock wb(&(chanMgr->channellock));
1768
1769         wb.on();
1770         Channel *ch;
1771
1772         ch = chanMgr->findChannelByNameID(info);
1773         if (ch && ch->thread.active)
1774         {
1775
1776                 if (!ch->isPlaying())
1777                 {
1778                         if (relay)
1779                         {
1780                                 ch->info.lastPlayStart = 0; // force reconnect 
1781                                 ch->info.lastPlayEnd = 0; 
1782                         }else
1783                                 return false;
1784                 }
1785                 
1786                 info = ch->info;        // get updated channel info 
1787
1788                 return true;
1789         } else if (ch && ch->thread.finish)
1790         {
1791                 // wait until deleting channel
1792                 do
1793                 {
1794                         sys->sleep(500);
1795                         ch = chanMgr->findChannelByNameID(info);
1796                 } while (ch);
1797
1798                 // same as else block
1799                 if (relay)
1800                 {
1801                         wb.off();
1802                         ch = chanMgr->findAndRelay(info);
1803                         if (ch)
1804                         {
1805                                 // \81«Exception point
1806                                 info = ch->info; //get updated channel info 
1807                                 return true;
1808                         }
1809                 }
1810         }else
1811         {
1812                 if (relay)
1813                 {
1814                         wb.off();
1815                         ch = chanMgr->findAndRelay(info);
1816                         if (ch)
1817                         {
1818                                 // \81«Exception point
1819                                 info = ch->info; //get updated channel info 
1820                                 return true;
1821                         }
1822                 }
1823         }
1824
1825         return false;
1826 }
1827 // --------------------------------------------------
1828 int ServMgr::findChannel(ChanInfo &info)
1829 {
1830 #if 0
1831         char idStr[64];
1832         info.id.toStr(idStr);
1833
1834
1835         if (info.id.isSet())
1836         {
1837                 // if we have an ID then try and connect to known hosts carrying channel.
1838                 ServHost sh = getOutgoingServent(info.id);
1839                 addOutgoing(sh.host,info.id,true);
1840         }
1841
1842         GnuPacket pack;
1843
1844         XML xml;
1845         XML::Node *n = info.createQueryXML();
1846         xml.setRoot(n);
1847         pack.initFind(NULL,&xml,servMgr->queryTTL);
1848
1849         addReplyID(pack.id);
1850         int cnt = broadcast(pack,NULL);
1851
1852         LOG_NETWORK("Querying network: %s %s - %d servents",info.name.cstr(),idStr,cnt);
1853
1854         return cnt;
1855 #endif
1856         return 0;
1857 }
1858 // --------------------------------------------------
1859 // add outgoing network connection from string (ip:port format)
1860 bool ServMgr::addOutgoing(Host h, GnuID &netid, bool pri)
1861 {
1862 #if 0
1863         if (h.ip)
1864         {
1865                 if (!findServent(h.ip,h.port,netid))
1866                 {
1867                         Servent *sv = allocServent();
1868                         if (sv)
1869                         {
1870                                 if (pri)
1871                                         sv->priorityConnect = true;
1872                                 sv->networkID = netid;
1873                                 sv->initOutgoing(h,Servent::T_OUTGOING);
1874                                 return true;
1875                         }
1876                 }
1877         }
1878 #endif
1879         return false;
1880 }
1881 // --------------------------------------------------
1882 Servent *ServMgr::findConnection(Servent::TYPE t,GnuID &sid)
1883 {
1884         Servent *sv = servents;
1885         while (sv)
1886         {
1887                 if (sv->isConnected())
1888                         if (sv->type == t)
1889                                 if (sv->remoteID.isSame(sid))                           
1890                                         return sv;
1891                 sv=sv->next;
1892         }
1893         return NULL;
1894 }
1895
1896 // --------------------------------------------------
1897 void ServMgr::procConnectArgs(char *str,ChanInfo &info)
1898 {
1899         char arg[MAX_CGI_LEN];
1900         char curr[MAX_CGI_LEN];
1901
1902         char *args = strstr(str,"?");
1903         if (args)
1904                 *args++=0;
1905
1906         info.initNameID(str);
1907
1908         if (args)
1909         {
1910
1911                 while (args=nextCGIarg(args,curr,arg))
1912                 {
1913                         LOG_DEBUG("cmd: %s, arg: %s",curr,arg);
1914
1915                         if (strcmp(curr,"sip")==0)
1916                         // sip - add network connection to client with channel
1917                         {
1918                                 Host h;
1919                                 h.fromStrName(arg,DEFAULT_PORT);
1920                                 if (addOutgoing(h,servMgr->networkID,true))
1921                                         LOG_NETWORK("Added connection: %s",arg);
1922
1923                         }else if (strcmp(curr,"pip")==0)
1924                         // pip - add private network connection to client with channel
1925                         {
1926                                 Host h;
1927                                 h.fromStrName(arg,DEFAULT_PORT);
1928                                 if (addOutgoing(h,info.id,true))
1929                                         LOG_NETWORK("Added private connection: %s",arg);
1930                         }else if (strcmp(curr,"ip")==0)
1931                         // ip - add hit
1932                         {
1933                                 Host h;
1934                                 h.fromStrName(arg,DEFAULT_PORT);
1935                                 ChanHit hit;
1936                                 hit.init();
1937                                 hit.host = h; 
1938                                 hit.rhost[0] = h;
1939                                 hit.rhost[1].init();
1940                                 hit.chanID = info.id;
1941                                 hit.recv = true;
1942
1943                                 chanMgr->addHit(hit);
1944                         }else if (strcmp(curr,"tip")==0)
1945                         // tip - add tracker hit
1946                         {
1947                                 Host h;
1948                                 h.fromStrName(arg,DEFAULT_PORT);
1949                                 chanMgr->hitlistlock.on();
1950                                 chanMgr->addHit(h,info.id,true);
1951                                 chanMgr->hitlistlock.off();
1952
1953                         }
1954
1955
1956                 }
1957         }
1958 }
1959
1960 // --------------------------------------------------
1961 bool ServMgr::start()
1962 {
1963         char idStr[64];
1964
1965
1966         const char *priv;
1967 #if PRIVATE_BROADCASTER
1968         priv = "(private)";
1969 #else
1970         priv = "";
1971 #endif
1972         if (version_ex)
1973         {
1974                 LOG_DEBUG("Peercast %s, %s %s",PCX_VERSTRING_EX,peercastApp->getClientTypeOS(),priv);
1975         } else
1976         {
1977                 LOG_DEBUG("Peercast %s, %s %s",PCX_VERSTRING,peercastApp->getClientTypeOS(),priv);
1978         }
1979
1980         sessionID.toStr(idStr);
1981         LOG_DEBUG("SessionID: %s",idStr);
1982
1983         chanMgr->broadcastID.toStr(idStr);
1984         LOG_DEBUG("BroadcastID: %s",idStr);
1985         checkForceIP();
1986
1987
1988         serverThread.func = ServMgr::serverProc;
1989         if (!sys->startThread(&serverThread))
1990                 return false;
1991
1992         idleThread.func = ServMgr::idleProc;
1993         if (!sys->startThread(&idleThread))
1994                 return false;
1995
1996         return true;
1997 }
1998 // --------------------------------------------------
1999 int ServMgr::clientProc(ThreadInfo *thread)
2000 {
2001 #if 0
2002         thread->lock();
2003
2004         GnuID netID;
2005         netID = servMgr->networkID;
2006
2007         while(thread->active)
2008         {
2009                 if (servMgr->autoConnect)
2010                 {
2011                         if (servMgr->needConnections() || servMgr->forceLookup)
2012                         {
2013                                 if (servMgr->needHosts() || servMgr->forceLookup)
2014                                 {
2015                                         // do lookup to find some hosts
2016
2017                                         Host lh;
2018                                         lh.fromStrName(servMgr->connectHost,DEFAULT_PORT);
2019
2020
2021                                         if (!servMgr->findServent(lh.ip,lh.port,netID))
2022                                         {
2023                                                 Servent *sv = servMgr->allocServent();
2024                                                 if (sv)
2025                                                 {
2026                                                         LOG_DEBUG("Lookup: %s",servMgr->connectHost);
2027                                                         sv->networkID = netID;
2028                                                         sv->initOutgoing(lh,Servent::T_LOOKUP);
2029                                                         servMgr->forceLookup = false;
2030                                                 }
2031                                         }
2032                                 }
2033
2034                                 for(int i=0; i<MAX_TRYOUT; i++)
2035                                 {
2036                                         if (servMgr->outUsedFull())
2037                                                 break;
2038                                         if (servMgr->tryFull())
2039                                                 break;
2040
2041
2042                                         ServHost sh = servMgr->getOutgoingServent(netID);
2043
2044                                         if (!servMgr->addOutgoing(sh.host,netID,false))
2045                                                 servMgr->deadHost(sh.host,ServHost::T_SERVENT);
2046                                         sys->sleep(servMgr->tryoutDelay);
2047                                         break;
2048                                 }
2049                         }
2050                 }else{
2051 #if 0
2052                         Servent *s = servMgr->servents;
2053                         while (s)
2054                         {
2055
2056                                 if (s->type == Servent::T_OUTGOING) 
2057                                         s->thread.active = false;
2058                                 s=s->next;
2059                         }
2060 #endif
2061                 }
2062                 sys->sleepIdle();
2063         }
2064         thread->unlock();
2065 #endif
2066         return 0;
2067 }
2068 // -----------------------------------
2069 bool    ServMgr::acceptGIV(ClientSocket *sock)
2070 {
2071         Servent *sv = servents;
2072         while (sv)
2073         {
2074                 if (sv->type == Servent::T_COUT)
2075                 {
2076                         if (sv->acceptGIV(sock))
2077                                 return true;
2078                 }
2079                 sv=sv->next;
2080         }
2081         return false;
2082 }
2083
2084 // -----------------------------------
2085 int ServMgr::broadcastPushRequest(ChanHit &hit, Host &to, GnuID &chanID, Servent::TYPE type)
2086 {
2087         ChanPacket pack;
2088         MemoryStream pmem(pack.data,sizeof(pack.data));
2089         AtomStream atom(pmem);
2090
2091 #ifndef VERSION_EX
2092                 atom.writeParent(PCP_BCST,8);
2093 #else
2094                 atom.writeParent(PCP_BCST,10);
2095 #endif
2096                 atom.writeChar(PCP_BCST_GROUP,PCP_BCST_GROUP_ALL);
2097                 atom.writeChar(PCP_BCST_HOPS,0);
2098                 atom.writeChar(PCP_BCST_TTL,7);
2099                 atom.writeBytes(PCP_BCST_DEST,hit.sessionID.id,16);
2100                 atom.writeBytes(PCP_BCST_FROM,servMgr->sessionID.id,16);
2101                 atom.writeInt(PCP_BCST_VERSION,PCP_CLIENT_VERSION);
2102                 atom.writeInt(PCP_BCST_VERSION_VP,PCP_CLIENT_VERSION_VP);
2103                 if (version_ex)
2104                 {
2105                         atom.writeBytes(PCP_BCST_VERSION_EX_PREFIX,PCP_CLIENT_VERSION_EX_PREFIX,2);
2106                         atom.writeShort(PCP_BCST_VERSION_EX_NUMBER,PCP_CLIENT_VERSION_EX_NUMBER);
2107                 }
2108                 atom.writeParent(PCP_PUSH,3);
2109                         atom.writeInt(PCP_PUSH_IP,to.ip);
2110                         atom.writeShort(PCP_PUSH_PORT,to.port);
2111                         atom.writeBytes(PCP_PUSH_CHANID,chanID.id,16);
2112
2113
2114         pack.len = pmem.pos;
2115         pack.type = ChanPacket::T_PCP;
2116
2117
2118         GnuID noID;
2119         noID.clear();
2120
2121         return servMgr->broadcastPacket(pack,noID,servMgr->sessionID,hit.sessionID,type);
2122 }
2123
2124 // --------------------------------------------------
2125 void ServMgr::writeRootAtoms(AtomStream &atom, bool getUpdate)
2126 {
2127         atom.writeParent(PCP_ROOT,5 + (getUpdate?1:0));
2128                 atom.writeInt(PCP_ROOT_UPDINT,chanMgr->hostUpdateInterval);
2129                 atom.writeString(PCP_ROOT_URL,"download.php");
2130                 atom.writeInt(PCP_ROOT_CHECKVER,PCP_ROOT_VERSION);
2131                 atom.writeInt(PCP_ROOT_NEXT,chanMgr->hostUpdateInterval);
2132                 atom.writeString(PCP_MESG_ASCII,rootMsg.cstr());
2133                 if (getUpdate)
2134                         atom.writeParent(PCP_ROOT_UPDATE,0);
2135
2136 }
2137 // --------------------------------------------------
2138 void ServMgr::broadcastRootSettings(bool getUpdate)
2139 {
2140         if (isRoot)
2141         {
2142
2143                 ChanPacket pack;
2144                 MemoryStream mem(pack.data,sizeof(pack.data));
2145                 AtomStream atom(mem);
2146                 if (version_ex == 0)
2147                 {
2148                         atom.writeParent(PCP_BCST,7);
2149                 } else
2150                 {
2151                         atom.writeParent(PCP_BCST,9);
2152                 }
2153                 atom.writeChar(PCP_BCST_GROUP,PCP_BCST_GROUP_TRACKERS);
2154                 atom.writeChar(PCP_BCST_HOPS,0);
2155                 atom.writeChar(PCP_BCST_TTL,7);
2156                 atom.writeBytes(PCP_BCST_FROM,sessionID.id,16);
2157                 atom.writeInt(PCP_BCST_VERSION,PCP_CLIENT_VERSION);
2158                 atom.writeInt(PCP_BCST_VERSION_VP,PCP_CLIENT_VERSION_VP);
2159                 if (version_ex)
2160                 {
2161                         atom.writeBytes(PCP_BCST_VERSION_EX_PREFIX,PCP_CLIENT_VERSION_EX_PREFIX,2);
2162                         atom.writeShort(PCP_BCST_VERSION_EX_NUMBER,PCP_CLIENT_VERSION_EX_NUMBER);
2163                 }
2164                 writeRootAtoms(atom,getUpdate);
2165
2166                 mem.len = mem.pos;
2167                 mem.rewind();
2168                 pack.len = mem.len;
2169
2170                 GnuID noID;
2171                 noID.clear();
2172
2173                 broadcastPacket(pack,noID,servMgr->sessionID,noID,Servent::T_CIN);
2174         }
2175 }
2176 // --------------------------------------------------
2177 int ServMgr::broadcastPacket(ChanPacket &pack,GnuID &chanID,GnuID &srcID, GnuID &destID, Servent::TYPE type)
2178 {
2179         int cnt=0;
2180         
2181         Servent *sv = servents;
2182         while (sv)
2183         {
2184                 if (sv->sendPacket(pack,chanID,srcID,destID,type))
2185                         cnt++;
2186                 sv=sv->next;
2187         }
2188         return cnt;
2189 }
2190
2191 // --------------------------------------------------
2192 int ServMgr::idleProc(ThreadInfo *thread)
2193 {
2194
2195 //      thread->lock();
2196
2197         unsigned int lastPasvFind=0;
2198         unsigned int lastBroadcast=0;
2199
2200
2201         // nothing much to do for the first couple of seconds, so just hang around.
2202         sys->sleep(2000);       
2203
2204         unsigned int lastBWcheck=0;
2205         unsigned int bytesIn=0,bytesOut=0;
2206
2207         unsigned int lastBroadcastConnect = 0;
2208         unsigned int lastRootBroadcast = 0;
2209
2210         unsigned int lastForceIPCheck = 0;
2211
2212         while(thread->active)
2213         {
2214                 stats.update();
2215
2216
2217
2218                 unsigned int ctime = sys->getTime();
2219
2220
2221                 if (!servMgr->forceIP.isEmpty())
2222                 {
2223                         if ((ctime-lastForceIPCheck) > 60)
2224                         {
2225                                 if (servMgr->checkForceIP())
2226                                 {
2227                                         GnuID noID;
2228                                         noID.clear();
2229                                         chanMgr->broadcastTrackerUpdate(noID,true);
2230                                 }
2231                                 lastForceIPCheck = ctime;
2232                         }
2233                 }
2234
2235
2236                 if (chanMgr->isBroadcasting())
2237                 {
2238                         if ((ctime-lastBroadcastConnect) > 30)
2239                         {
2240                                 servMgr->connectBroadcaster();
2241                                 lastBroadcastConnect = ctime;
2242                         }
2243                 }
2244
2245                 if (servMgr->isRoot)
2246                 {
2247                         if ((servMgr->lastIncoming) && ((ctime-servMgr->lastIncoming) > 60*60))
2248                         {
2249                                 peercastInst->saveSettings();
2250                                 sys->exit();
2251                         }
2252
2253                         if ((ctime-lastRootBroadcast) > chanMgr->hostUpdateInterval)
2254                         {
2255                                 servMgr->broadcastRootSettings(true);
2256                                 lastRootBroadcast = ctime;
2257                         }
2258                 }
2259
2260
2261                 // clear dead hits
2262                 chanMgr->clearDeadHits(true);
2263
2264                 if (servMgr->kickPushStartRelays && servMgr->kickPushInterval) //JP-EX
2265                 {
2266                         servMgr->banFirewalledHost();
2267                 }
2268
2269                 if (servMgr->shutdownTimer)
2270                 {
2271                         if (--servMgr->shutdownTimer <= 0)
2272                         {
2273                                 peercastInst->saveSettings();
2274                                 sys->exit();
2275                         }
2276                 }
2277
2278                 // shutdown idle channels
2279                 if (chanMgr->numIdleChannels() > ChanMgr::MAX_IDLE_CHANNELS)
2280                         chanMgr->closeOldestIdle();
2281
2282
2283                 sys->sleep(500);
2284         }
2285
2286         sys->endThread(thread);
2287 //      thread->unlock();
2288         return 0;
2289 }
2290
2291 // --------------------------------------------------
2292 int ServMgr::serverProc(ThreadInfo *thread)
2293 {
2294
2295 //      thread->lock();
2296
2297         Servent *serv = servMgr->allocServent();
2298         Servent *serv2 = servMgr->allocServent();
2299
2300         unsigned int lastLookupTime=0;
2301
2302
2303         while (thread->active)
2304         {
2305
2306                 if (servMgr->restartServer)
2307                 {
2308                         serv->abort();          // force close
2309                         serv2->abort();         // force close
2310                         servMgr->quit();
2311
2312                         servMgr->restartServer = false;
2313                 }
2314
2315                 if (servMgr->autoServe)
2316                 {
2317                         serv->allow = servMgr->allowServer1;
2318                         serv2->allow = servMgr->allowServer2;
2319
2320
2321                         if ((!serv->sock) || (!serv2->sock))
2322                         {
2323                                 LOG_DEBUG("Starting servers");
2324 //                              servMgr->forceLookup = true;
2325
2326                                 //if (servMgr->serverHost.ip != 0)
2327                                 {
2328
2329                                         if (servMgr->forceNormal)
2330                                                 servMgr->setFirewall(ServMgr::FW_OFF);
2331                                         else
2332                                                 servMgr->setFirewall(ServMgr::FW_UNKNOWN);
2333
2334                                         Host h = servMgr->serverHost;
2335
2336                                         if (!serv->sock)
2337                                                 serv->initServer(h);
2338
2339                                         h.port++;
2340                                         if (!serv2->sock)
2341                                                 serv2->initServer(h);
2342
2343
2344                                 }
2345                         }
2346                 }else{
2347                         // stop server
2348                         serv->abort();          // force close
2349                         serv2->abort();         // force close
2350
2351                         // cancel incoming connectuions
2352                         Servent *s = servMgr->servents;
2353                         while (s)
2354                         {
2355                                 if (s->type == Servent::T_INCOMING)
2356                                         s->thread.active = false;
2357                                 s=s->next;
2358                         }
2359
2360                         servMgr->setFirewall(ServMgr::FW_ON);
2361                 }
2362                         
2363                 sys->sleepIdle();
2364
2365         }
2366
2367         sys->endThread(thread);
2368 //      thread->unlock();
2369         return 0;
2370 }
2371
2372 // -----------------------------------
2373 void    ServMgr::setMaxRelays(int max)
2374 {
2375         if (max < MIN_RELAYS)
2376                 max = MIN_RELAYS;
2377         maxRelays = max;
2378 }
2379
2380 // -----------------------------------
2381 XML::Node *ServMgr::createServentXML()
2382 {
2383
2384         return new XML::Node("servent agent=\"%s\" ",PCX_AGENT);
2385 }
2386
2387 // --------------------------------------------------
2388 const char *ServHost::getTypeStr(TYPE t)
2389 {
2390         switch(t)
2391         {
2392                 case T_NONE: return "NONE";
2393                 case T_STREAM: return "STREAM";
2394                 case T_CHANNEL: return "CHANNEL";
2395                 case T_SERVENT: return "SERVENT";
2396                 case T_TRACKER: return "TRACKER";
2397         }
2398         return "UNKNOWN";
2399 }
2400 // --------------------------------------------------
2401 ServHost::TYPE ServHost::getTypeFromStr(const char *s)
2402 {
2403         if (stricmp(s,"NONE")==0)
2404                 return T_NONE;
2405         else if (stricmp(s,"SERVENT")==0)
2406                 return T_SERVENT;
2407         else if (stricmp(s,"STREAM")==0)
2408                 return T_STREAM;
2409         else if (stricmp(s,"CHANNEL")==0)
2410                 return T_CHANNEL;
2411         else if (stricmp(s,"TRACKER")==0)
2412                 return T_TRACKER;
2413
2414         return T_NONE;
2415 }
2416
2417
2418 // --------------------------------------------------
2419 bool    ServFilter::writeVariable(Stream &out, const String &var)
2420 {
2421         char buf[1024];
2422
2423         if (var == "network")
2424                 strcpy(buf,(flags & F_NETWORK)?"1":"0");
2425         else if (var == "private")
2426                 strcpy(buf,(flags & F_PRIVATE)?"1":"0");
2427         else if (var == "direct")
2428                 strcpy(buf,(flags & F_DIRECT)?"1":"0");
2429         else if (var == "banned")
2430                 strcpy(buf,(flags & F_BAN)?"1":"0");
2431         else if (var == "ip")
2432                 host.IPtoStr(buf);
2433         else
2434                 return false;
2435
2436
2437         out.writeString(buf);
2438         return true;
2439 }
2440 // --------------------------------------------------
2441 bool    BCID::writeVariable(Stream &out, const String &var)
2442 {
2443         char buf[1024];
2444
2445         if (var == "id")
2446                 id.toStr(buf);
2447         else if (var == "name")
2448                 strcpy(buf,name.cstr());
2449         else if (var == "email")
2450                 strcpy(buf,email.cstr());
2451         else if (var == "url")
2452                 strcpy(buf,url.cstr());
2453         else if (var == "valid")
2454                 strcpy(buf,valid?"Yes":"No");
2455         else
2456                 return false;
2457
2458
2459         out.writeString(buf);
2460         return true;
2461 }
2462
2463
2464 // --------------------------------------------------
2465 bool ServMgr::writeVariable(Stream &out, const String &var)
2466 {
2467         char buf[1024];
2468         String str;
2469
2470         if (var == "version")
2471                 if (version_ex)
2472                 {
2473                         strcpy(buf,PCX_VERSTRING_EX);
2474                 } else
2475                 {
2476                         strcpy(buf,PCX_VERSTRING);
2477                 }
2478         else if (var == "uptime")
2479         {
2480                 str.setFromStopwatch(getUptime());
2481                 str.convertTo(String::T_HTML);
2482                 strcpy(buf,str.cstr());
2483         }else if (var == "numRelays")
2484                 sprintf(buf,"%d",numStreams(Servent::T_RELAY,true));
2485         else if (var == "numDirect")
2486                 sprintf(buf,"%d",numStreams(Servent::T_DIRECT,true));
2487         else if (var == "totalConnected")
2488                 sprintf(buf,"%d",totalConnected());
2489         else if (var == "numServHosts")
2490                 sprintf(buf,"%d",numHosts(ServHost::T_SERVENT));                
2491         else if (var == "numServents")
2492                 sprintf(buf,"%d",numServents());                
2493         else if (var == "serverPort")
2494                 sprintf(buf,"%d",serverHost.port);              
2495         else if (var == "serverIP")
2496                 serverHost.IPtoStr(buf);
2497         else if (var == "ypAddress")
2498                 strcpy(buf,rootHost.cstr());
2499         else if (var == "password")
2500                 strcpy(buf,password);
2501         else if (var == "isFirewalled")
2502                 sprintf(buf,"%d",getFirewall()==FW_ON?1:0);
2503         else if (var == "firewallKnown")
2504                 sprintf(buf,"%d",getFirewall()==FW_UNKNOWN?0:1);
2505         else if (var == "rootMsg")
2506                 strcpy(buf,rootMsg);
2507         else if (var == "isRoot"){
2508                 LOG_DEBUG("isRoot = %d", isRoot);
2509                 sprintf(buf,"%d",isRoot?1:0);
2510         }
2511         else if (var == "isPrivate")
2512                 sprintf(buf,"%d",(PCP_BROADCAST_FLAGS&1)?1:0);
2513         else if (var == "forceYP")
2514                 sprintf(buf,"%d",PCP_FORCE_YP?1:0);
2515         else if (var == "refreshHTML")
2516                 sprintf(buf,"%d",refreshHTML?refreshHTML:0x0fffffff);
2517         else if (var == "maxRelays")
2518                 sprintf(buf,"%d",maxRelays);
2519         else if (var == "maxDirect")
2520                 sprintf(buf,"%d",maxDirect);
2521         else if (var == "maxBitrateOut")
2522                 sprintf(buf,"%d",maxBitrateOut);
2523         else if (var == "maxControlsIn")
2524                 sprintf(buf,"%d",maxControl);
2525         else if (var == "maxServIn")
2526                 sprintf(buf,"%d",maxServIn);
2527         else if (var == "numFilters") {
2528                 LOG_DEBUG("*-* numFilters = %d", numFilters);
2529                 sprintf(buf,"%d",numFilters+1);
2530         }
2531         else if (var == "maxPGNUIn")
2532                 sprintf(buf,"%d",maxGnuIncoming);
2533         else if (var == "minPGNUIn")
2534                 sprintf(buf,"%d",minGnuIncoming);
2535         else if (var == "numActive1")
2536                 sprintf(buf,"%d",numActiveOnPort(serverHost.port));
2537         else if (var == "numActive2")
2538                 sprintf(buf,"%d",numActiveOnPort(serverHost.port+1));
2539         else if (var == "numPGNU")
2540                 sprintf(buf,"%d",numConnected(Servent::T_PGNU));
2541         else if (var == "numCIN")
2542                 sprintf(buf,"%d",numConnected(Servent::T_CIN));
2543         else if (var == "numCOUT")
2544                 sprintf(buf,"%d",numConnected(Servent::T_COUT));
2545         else if (var == "numIncoming")
2546                 sprintf(buf,"%d",numActive(Servent::T_INCOMING));
2547         else if (var == "numValidBCID")
2548         {
2549                 int cnt = 0;
2550                 BCID *bcid = validBCID;
2551                 while (bcid)
2552                 {
2553                         cnt++;
2554                         bcid=bcid->next;
2555                 }
2556                 sprintf(buf,"%d",cnt);
2557         }
2558
2559         else if (var == "disabled")
2560                 sprintf(buf,"%d",isDisabled);
2561
2562         // JP-EX
2563         else if (var.startsWith("autoRelayKeep")) {
2564                 if (var == "autoRelayKeep.0")
2565                         strcpy(buf, (autoRelayKeep == 0) ? "1":"0");
2566                 else if (var == "autoRelayKeep.1")
2567                         strcpy(buf, (autoRelayKeep == 1) ? "1":"0");
2568                 else if (var == "autoRelayKeep.2")
2569                         strcpy(buf, (autoRelayKeep == 2) ? "1":"0");
2570         } else if (var == "autoMaxRelaySetting")
2571                 sprintf(buf,"%d",autoMaxRelaySetting);
2572         else if (var == "autoBumpSkipCount")
2573                 sprintf(buf,"%d",autoBumpSkipCount);
2574         else if (var == "kickPushStartRelays")
2575                 sprintf(buf,"%d",kickPushStartRelays);
2576         else if (var == "kickPushInterval")
2577                 sprintf(buf,"%d",kickPushInterval);
2578         else if (var == "allowConnectPCST")
2579                 strcpy(buf, (allowConnectPCST == 1) ? "1":"0");
2580         else if (var == "enableGetName")
2581                 strcpy(buf, (enableGetName == 1)? "1":"0");
2582
2583         //JP-MOD
2584         else if (var == "disableAutoBumpIfDirect")
2585                 strcpy(buf, (disableAutoBumpIfDirect == 1) ? "1":"0");
2586         else if (var.startsWith("asxDetailedMode"))
2587         {
2588                 if (var == "asxDetailedMode.0")
2589                         strcpy(buf, (asxDetailedMode == 0) ? "1":"0");
2590                 else if (var == "asxDetailedMode.1")
2591                         strcpy(buf, (asxDetailedMode == 1) ? "1":"0");
2592                 else if (var == "asxDetailedMode.2")
2593                         strcpy(buf, (asxDetailedMode == 2) ? "1":"0");
2594         }
2595
2596         // VP-EX
2597         else if (var == "ypAddress2")
2598                 strcpy(buf,rootHost2.cstr());
2599         else if (var.startsWith("autoPort0Kick")) {
2600                 if (var == "autoPort0Kick.0")
2601                         strcpy(buf, (autoPort0Kick == 0) ? "1":"0");
2602                 else if (var == "autoPort0Kick.1")
2603                         strcpy(buf, (autoPort0Kick == 1) ? "1":"0");
2604         }
2605         else if (var.startsWith("allowOnlyVP")) {
2606                 if (var == "allowOnlyVP.0")
2607                         strcpy(buf, (allowOnlyVP == 0) ? "1":"0");
2608                 else if (var == "allowOnlyVP.1")
2609                         strcpy(buf, (allowOnlyVP == 1) ? "1":"0");
2610         }
2611         else if (var == "kickKeepTime")
2612                 sprintf(buf, "%d",kickKeepTime);
2613
2614         else if (var == "serverPort1")
2615                 sprintf(buf,"%d",serverHost.port);
2616         else if (var == "serverLocalIP")
2617         {
2618                 Host lh(ClientSocket::getIP(NULL),0);
2619                 char ipStr[64];
2620                 lh.IPtoStr(ipStr);
2621                 strcpy(buf,ipStr);
2622         }else if (var == "upgradeURL")
2623                 strcpy(buf,servMgr->downloadURL);
2624         else if (var == "serverPort2")
2625                 sprintf(buf,"%d",serverHost.port+1);
2626         else if (var.startsWith("allow."))
2627         {
2628                 if (var == "allow.HTML1")
2629                         strcpy(buf,(allowServer1&Servent::ALLOW_HTML)?"1":"0");
2630                 else if (var == "allow.HTML2")
2631                         strcpy(buf,(allowServer2&Servent::ALLOW_HTML)?"1":"0");
2632                 else if (var == "allow.broadcasting1")
2633                         strcpy(buf,(allowServer1&Servent::ALLOW_BROADCAST)?"1":"0");
2634                 else if (var == "allow.broadcasting2")
2635                         strcpy(buf,(allowServer2&Servent::ALLOW_BROADCAST)?"1":"0");
2636                 else if (var == "allow.network1")
2637                         strcpy(buf,(allowServer1&Servent::ALLOW_NETWORK)?"1":"0");
2638                 else if (var == "allow.direct1")
2639                         strcpy(buf,(allowServer1&Servent::ALLOW_DIRECT)?"1":"0");
2640         }else if (var.startsWith("auth."))
2641         {
2642                 if (var == "auth.useCookies")
2643                         strcpy(buf,(authType==AUTH_COOKIE)?"1":"0");
2644                 else if (var == "auth.useHTTP")
2645                         strcpy(buf,(authType==AUTH_HTTPBASIC)?"1":"0");
2646                 else if (var == "auth.useSessionCookies")
2647                         strcpy(buf,(cookieList.neverExpire==false)?"1":"0");
2648
2649         }else if (var.startsWith("log."))
2650         {
2651                 if (var == "log.debug")
2652                         strcpy(buf,(showLog&(1<<LogBuffer::T_DEBUG))?"1":"0");
2653                 else if (var == "log.errors")
2654                         strcpy(buf,(showLog&(1<<LogBuffer::T_ERROR))?"1":"0");
2655                 else if (var == "log.gnet")
2656                         strcpy(buf,(showLog&(1<<LogBuffer::T_NETWORK))?"1":"0");
2657                 else if (var == "log.channel")
2658                         strcpy(buf,(showLog&(1<<LogBuffer::T_CHANNEL))?"1":"0");
2659                 else
2660                         return false;
2661         }else if (var == "test")
2662         {
2663                 out.writeUTF8(0x304b);          
2664                 out.writeUTF8(0x304d);          
2665                 out.writeUTF8(0x304f);          
2666                 out.writeUTF8(0x3051);          
2667                 out.writeUTF8(0x3053);  
2668
2669                 out.writeUTF8(0x0041);  
2670                 out.writeUTF8(0x0042);  
2671                 out.writeUTF8(0x0043);  
2672                 out.writeUTF8(0x0044);  
2673
2674                 out.writeChar('a');
2675                 out.writeChar('b');
2676                 out.writeChar('c');
2677                 out.writeChar('d');
2678                 return true;
2679
2680         }else if (var == "maxRelaysIndexTxt")           // for PCRaw (relay)
2681                 sprintf(buf, "%d", maxRelaysIndexTxt);
2682         else
2683                 return false;
2684
2685         out.writeString(buf);
2686         return true;
2687 }
2688 // --------------------------------------------------
2689 //JP-EX
2690 bool ServMgr::isCheckPushStream()
2691 {
2692         if (servMgr->kickPushStartRelays)
2693                 if (servMgr->numStreams(Servent::T_RELAY,false)>=(servMgr->kickPushStartRelays-1))
2694                                 return true;
2695
2696         return false;
2697 }
2698 // --------------------------------------------------
2699 //JP-EX
2700 void ServMgr::banFirewalledHost()
2701 {
2702         unsigned int kickpushtime = sys->getTime();
2703         if ((kickpushtime-servMgr->kickPushTime) > servMgr->kickPushInterval)
2704         {
2705                 servMgr->kickPushTime = kickpushtime;
2706                 Servent *s = servMgr->servents;
2707                 LOG_DEBUG("Servent scan start.");
2708                 while (s)
2709                 {
2710                         if (s->type != Servent::T_NONE)
2711                         {
2712                                 Host h = s->getHost();
2713                                 int ip = h.ip;
2714                                 int port = h.port;
2715                                 Host h2(ip,port);
2716                                 unsigned int tnum = 0;
2717
2718                                 if (s->lastConnect)
2719                                         tnum = sys->getTime() - s->lastConnect;
2720                                 if ((s->type==Servent::T_RELAY) && (s->status==Servent::S_CONNECTED) && (tnum>servMgr->kickPushInterval))
2721                                 {                                               
2722 /*                                      ChanHitList *hits[ChanMgr::MAX_HITLISTS];
2723                                         int numHits=0;
2724                                         for(int i=0; i<ChanMgr::MAX_HITLISTS; i++)
2725                                         {
2726                                                 ChanHitList *chl = &chanMgr->hitlists[i];
2727                                                 if (chl->isUsed())
2728                                                         hits[numHits++] = chl;
2729                                         }
2730
2731                                         bool isfw = false;
2732                                         int numRelay = 0;
2733                                         if (numHits) 
2734                                         {
2735                                                 for(int k=0; k<numHits; k++)
2736                                                 {
2737                                                         ChanHitList *chl = hits[k];
2738                                                         if (chl->isUsed())
2739                                                         {
2740                                                                 for (int j=0; j<ChanHitList::MAX_HITS; j++ )
2741                                                                 {
2742                                                                         ChanHit *hit = &chl->hits[j];
2743                                                                         if (hit->host.isValid() && (h2.ip == hit->host.ip))
2744                                                                         {
2745                                                                                 if (hit->firewalled)
2746                                                                                         isfw = true;
2747                                                                                 numRelay = hit->numRelays;
2748                                                                         }
2749                                                                 }
2750                                                         }
2751                                                 }
2752                                         }
2753                                         if ((isfw==true) && (numRelay==0))
2754                                         {
2755                                                 char hostName[256];
2756                                                 h2.toStr(hostName);
2757                                                 if (servMgr->isCheckPushStream())
2758                                                 {
2759                                                         s->thread.active = false;
2760                                                         LOG_ERROR("Stop firewalled Servent : %s",hostName);
2761                                                 }
2762                                         }*/
2763
2764                                         chanMgr->hitlistlock.on();
2765                                         ChanHitList *chl = chanMgr->findHitListByID(s->chanID);
2766                                         if (chl){
2767                                                 ChanHit *hit = chl->hit;
2768                                                 while(hit){
2769                                                         if ((hit->numHops == 1) && hit->host.isValid() && (h2.ip == hit->host.ip) && hit->firewalled /*&& !hit->numRelays*/)
2770                                                         {
2771                                                                 char hostName[256];
2772                                                                 h2.toStr(hostName);
2773                                                                 if (servMgr->isCheckPushStream())
2774                                                                 {
2775                                                                         s->thread.active = false;
2776                                                                         LOG_ERROR("Stop firewalled Servent : %s",hostName);
2777                                                                 }
2778                                                         }
2779                                                         hit = hit->next;
2780                                                 }
2781
2782                                         }
2783                                         chanMgr->hitlistlock.off();
2784
2785
2786                                 }
2787                         }
2788                         s=s->next;
2789                 }
2790                 LOG_DEBUG("Servent scan finished.");
2791         }
2792 }
2793
2794 // --------------------------------------------------
2795 #if 0
2796 static ChanHit *findServentHit(Servent *s)
2797 {
2798         ChanHitList *chl = chanMgr->findHitListByID(s->chanID);
2799         Host h = s->getHost();
2800
2801         if (chl)
2802         {
2803                 ChanHit *hit = chl->hit;
2804                 while (hit)
2805                 {
2806                         if ((hit->numHops == 1) && hit->host.isValid() && (h.ip == hit->host.ip))
2807                                 return hit;
2808                         hit = hit->next;
2809                 }
2810         }
2811         return NULL;
2812 }
2813 #endif
2814 // --------------------------------------------------
2815 int ServMgr::kickUnrelayableHost(GnuID &chid, ChanHit &sendhit)
2816 {
2817         Servent *ks = NULL;
2818         Servent *s = servMgr->servents;
2819
2820         while (s)
2821         {
2822                 if (s->type == Servent::T_RELAY && s->chanID.isSame(chid) && !s->isPrivate())
2823                 {
2824                         Host h = s->getHost();
2825
2826                         ChanHit hit = s->serventHit;
2827                         if (!hit.relay && hit.numRelays == 0 || hit.firewalled)
2828                         {
2829                                 char hostName[256];
2830                                 h.toStr(hostName);
2831                                 //s->thread.active = false;
2832                                 LOG_DEBUG("unrelayable Servent : %s",hostName);
2833                                 if (!ks || s->lastConnect < ks->lastConnect) // elder servent
2834                                         ks = s;
2835                         }
2836                 }
2837                 s = s->next;
2838         }
2839
2840         if (ks)
2841         {
2842                 if (sendhit.rhost[0].port)
2843                 {
2844                         ChanPacket pack;
2845                         MemoryStream mem(pack.data,sizeof(pack.data));
2846                         AtomStream atom(mem);
2847                         sendhit.writeAtoms(atom, chid);
2848                         pack.len = mem.pos;
2849                         pack.type = ChanPacket::T_PCP;
2850                         GnuID noID;
2851                         noID.clear();
2852
2853                         ks->sendPacket(pack, chid, noID, noID, Servent::T_RELAY);
2854                 }
2855
2856                 ks->setStatus(Servent::S_CLOSING);
2857                 ks->thread.active = false;
2858
2859                 char hostName[256];
2860                 ks->getHost().toStr(hostName);
2861
2862                 LOG_DEBUG("Stop unrelayable Servent : %s",hostName);
2863
2864                 return 1;
2865         }
2866
2867         return 0;
2868 }
2869
2870 int WINAPI ServMgr::graylistThreadFunc(ThreadInfo *t)
2871 {
2872         while (t->active)
2873         {
2874                 LOG_DEBUG("******************** check graylist: begin");
2875
2876                 servMgr->IP_graylist->lock();
2877                 servMgr->IP_blacklist->lock();
2878
2879
2880                 for (size_t i=0; i<servMgr->IP_graylist->count; ++i)
2881                 {
2882                         addrCont addr = servMgr->IP_graylist->at(i);
2883                         LOG_NETWORK("######## %d.%d.%d.%d  # %d", (addr.addr >> 24), (addr.addr >> 16) & 0xFF, (addr.addr >> 8) & 0xFF, addr.addr & 0xFF, addr.count);
2884                         if (addr.count >= servMgr->dosThreashold)
2885                         {
2886                                 servMgr->IP_blacklist->push_back(addr);
2887                                 LOG_DEBUG("BANNED: %d.%d.%d.%d", (addr.addr >> 24), (addr.addr >> 16) & 0xFF, (addr.addr >> 8) & 0xFF, addr.addr & 0xFF);
2888                         }
2889                 }
2890
2891                 servMgr->IP_graylist->clear();
2892
2893
2894                 servMgr->IP_graylist->unlock();
2895                 servMgr->IP_blacklist->unlock();
2896
2897                 LOG_DEBUG("******************** check graylist: end");
2898
2899                 sys->sleep(servMgr->dosInterval*1000);
2900         }
2901
2902         t->finish = true;
2903         sys->endThread(t);
2904
2905         return 0;
2906 }