OSDN Git Service

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