OSDN Git Service

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