001 #exe {Cd(__DIR__);};;
002 #ifdef __AIWNIOS__
003 #include "CrossNetShims/Aiwnios2";
004 #else
005 #include "CrossNetShims/EXODUS";
006 #endif
007 #exe {Cd(__DIR__);};;
008 #define IRCD_LIMIT_MAX      20
009 #define IRCD_PING_INTERVAL  60000
010 #define IRCD_PORT           6667
011 #define IRCD_RXBUF_SIZE     4096
012 #define IRCD_TXBUF_SIZE     4096
013 #define IRCD_TXFIFO_SIZE    0x200
014 #define BACKLOG_FIFO_SZ (IRCD_TXFIFO_SIZE/2) //MUST REVERSE ROOM FOR JOIN MESSAGES(so use smaller size)
015 
016 U8 *ircd_hostname = "aiwnios.com";              
017 I64 ircd_chans_total = 0;
018 I64 ircd_clients_total = 0;
019 
020 CTask *gihon_task=Fs;
021 
022 //This accounts for Free-ing strings from the overflow of the fifo
023 U0 GihonFifoIns(CFifoI64 *fifo,U8 *s) {
024   U8 *new_s=StrNew(s,gihon_task),*tmp;
025   DbgPrint("%s\n",s);
026   if(FifoI64Cnt(fifo)==fifo->mask) {
027     FifoI64Rem(fifo,&tmp);
028     Free(tmp);
029   }
030   FifoI64Ins(fifo,new_s);
031   Free(s);
032 }
033 
034 
035 #include "BadWords";
036 #include "Motd";
037 #include "Service";
038 #include "Arg";
039 #include "Client";
040 #include "Channel";
041 #include "Command";
042 #include "DCC";
043 U0 LoadChannels() {
044   CDirEntry *root=FilesFind(IRC_BACKLOG_DIR,FUF_FLATTEN_TREE|FUF_JUST_FILES),*dd;
045   I64 ln;
046   U8 *tmp,nb[4096],mb[4096],*np=nb,*mp=mb;
047   IrcChannel *channel;
048   dd=root;
049   while(dd) {
050     tmp=MStrPrint("#%s",dd->name);
051     IrcChannelAdd(tmp);
052     channel=IrcGetChanByName(tmp);
053     IrcLoadChannelTopic(channel);
054     IrcLoadChannelPassword(channel);
055     Free(tmp);
056     for(ln=1;tmp=DocLineRead(dd->full_name,ln);ln++) {
057       StrScan(tmp," %s:%s",&np,&mp);
058       IrcAddToBacklog(channel,nb,mb,FALSE);
059       Free(tmp);
060     }
061     dd=dd->next;
062   }
063   DirEntryDel(root);
064 }
065 I64 Gihon()
066 {
067   I64 sock = socket(AF_INET,SOCK_STREAM);
068   IrcClient *iclient;
069   CTask *tx_task;
070   IrcChannel *ichannel;
071   if (sock < 0)
072     return -1;
073   sockaddr_in addr;
074   addr.sin_family = AF_INET;
075   addr.sin_port = htons(IRCD_PORT);
076   addr.sin_addr.s_addr = 0;
077   addrinfo* res, *curr;
078   getaddrinfo("0.0.0.0", NULL, NULL, &res);
079   for(curr=res;curr;curr=curr->ai_next) { 
080     if (curr->ai_family == AF_INET && (curr->ai_socktype == 0 || curr->ai_socktype == SOCK_STREAM)) {
081       MemCpy(&addr.sin_zero,&curr->ai_addr(sockaddr_in*)->sin_zero,8);
082       addr.sin_addr.s_addr = (curr->ai_addr(sockaddr_in*))->sin_addr.s_addr;
083       break;
084     }
085   }
086   freeaddrinfo(res);
087   bind(sock,&addr,sizeof (sockaddr_in));
088   listen(sock,100);
089   tx_task=Spawn(&IrcClientTxHandler,, "Gihon ClientTxHandler",,Fs);
090 //Flush previous keys
091   LoadChannels;
092   FlushMsgs; 
093   "Press a key to stop serving\n";
094   while (!ScanKey)
095     {
096     I64 client = accept(sock,NULL,0);
097     if(client!=-1)
098       Spawn(&IrcClientRxHandler, client, "Gihon ClientRxHandler",,Fs);
099     Sleep(10);
100   }
101   Kill(tx_task,FALSE);
102   while(iclient=client_head->next)
103     IrcClientDel(iclient);
104   while(ichannel=channel_head->next)
105     IrcChannelDel(ichannel);
106   Free(client_head);
107   Free(channel_head);
108   close(sock);
109 //  Exit;
110 }
111 Gihon;