OSDN Git Service

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