001 #ifndef IRCD_ACCOUNT_HH
002 #define IRCD_ACCOUNT_HH 'poop'
003 class CIrcAccount {
004   CDate last_login;
005   I64 password_hash;
006   U8 realname[STR_LEN];
007 };
008 #define IRC_ACNT_REGISTRY "Gihon/Accounts"
009 #define IRC_CHANNEL_REGISTRY "Gihon/Channels"
010 #define IRC_REGISTRY_FILE "T:/Gihon.DD"
011 #define IRC_MAIL_DIR "T:/GihonMail"
012 #define IRC_BACKLOG_DIR "T:/GihonLogs"
013 #define IRC_CHAN_REGISTRY "Gihon/Channels"
014 CDoc *registry_doc;
015 if(!FileFind(IRC_REGISTRY_FILE))
016   registry_doc=DocNew(IRC_REGISTRY_FILE);
017 else
018   registry_doc=DocRead(IRC_REGISTRY_FILE);
019 U0 IrcSetChannelUserMode(U8 *channel,U8 *user,U8 *mode_str) {
020   U8 *path=MStrPrint(IRC_CHANNEL_REGISTRY"/%s/%s",channel,user);
021   DocTreeWrite(registry_doc,path,TRUE,"StrNew(\"%Q\");",mode_str);
022   Free(path);
023 }
024 U8 *IrcGetChannelUserMode(U8 *channel,U8 *user) {
025   U8 *path=MStrPrint(IRC_CHANNEL_REGISTRY"/%s/%s",channel,user);
026   U8 *r=DocTreeExe(registry_doc,path);
027   Free(path);
028   return r;
029 }
030 CIrcAccount *_IrcAccountGet(U8 *realname,I64 password_hash,CDate last_login) {
031   CIrcAccount *acnt=CAlloc(sizeof(CIrcAccount),gihon_task);
032   acnt->password_hash=password_hash;
033   StrCpy(acnt->realname,realname);
034 //Dumb hack,if no assume assume throw-away account
035   if(HashStr("")==acnt->password_hash)
036     acnt->last_login=0;
037   else
038     acnt->last_login=last_login;
039   return acnt;
040 }
041 U0 IrcAccountChangePassword(IrcClient *client,U8 *password) {
042   CIrcAccount *account;
043   I64 hash=HashStr(password);
044   U8 *realname=client->nick;
045   U8 * path=MStrPrint("%s/%s",IRC_ACNT_REGISTRY,realname,password),*dft,*tmp;
046   dft=MStrPrint("_IrcAccountGet(\"%Q\",%d,%d);",realname,hash,0);
047   DocTreeWrite(registry_doc,path,TRUE,dft);
048   Free(path);
049   Free(dft);
050   StrCpy(client->password,password);
051 }
052 extern U0 IrcClientNotice(IrcClient *c,U8*);
053 CIrcAccount *IrcAccountLogin(IrcClient *client,U8 *realname,U8 *password="") {
054   CIrcAccount *account;
055   I64 hash=HashStr(password),ln;
056   U8 * path=MStrPrint("%s/%s",IRC_ACNT_REGISTRY,realname,password),*dft,*tmp;
057   dft=MStrPrint("_IrcAccountGet(\"%Q\",%d,%d);",realname,hash,0);
058   if(!DocTreeFind(registry_doc,path)) {
059     DocTreeWrite(registry_doc,path,TRUE,dft);    
060   }
061   account=DocTreeExe(registry_doc,path);
062   Free(path);
063   Free(dft);
064 //  client->last_connect=account->last_login;
065   if(hash!=account->password_hash) {
066     if(account->password_hash==HashStr("")) { //Server has Empty password,use new one
067       StrCpy(client->password,password);
068     } else {
069       GihonFifoIns(client->msgs,MStrPrint("%s 464 * %s:Password mismatch\r\n",ircd_hostname,client->username));
070     }
071     Free(account);
072     return NULL;
073   } else   if(HashStr("")==hash) {
074     GihonFifoIns(client->msgs,MStrPrint(":%s 372 %s : Please set a password(all trafic in here is logged so be careful)\r\n", ircd_hostname, client->username));
075   } else
076     GihonFifoIns(client->msgs,MStrPrint(":%s 372 %s : Password Accepted\r\n", ircd_hostname, client->username));
077 
078   if(account) {
079     if(!client->logged_in) {
080 //Read user mail
081       path=MStrPrint(IRC_MAIL_DIR"/%s",client->nick);
082       if(!FileFind(path))
083         goto skip_mail;
084       for(ln=1;dft=DocLineRead(path,ln);ln++) {
085         if(ln==1)
086           IrcClientNotice(client,"Here is your mail:");
087         tmp=MStrPrint("%s\r\n",dft);
088         GihonFifoIns(client->msgs,tmp);
089         Free(dft);
090       }
091 //      Del(path);
092 skip_mail:;
093       Free(path);
094     }
095     client->logged_in=TRUE;
096   }
097   client->account=account;
098   return account;
099 }
100 U0 IrcClientAccountLogout(IrcClient *c) {
101   CIrcAccount *acc=c->account;
102   if(!acc) return;
103   U8 *realname=acc->realname;
104   I64 password_hash=HashStr(c->password);
105   U8 *path=MStrPrint("%s/%s",IRC_ACNT_REGISTRY,c->nick);
106   U8 *new=MStrPrint("_IrcAccountGet(\"%Q\",%d,%d);",c->nick,password_hash,Now);
107   Free(path);Free(new);Free(acc);
108 }
109 U0 IrcSaveChannelTopic(IrcChannel *chan,U8 *msg) {
110   U8 *path=MStrPrint("%s/%s/Topic",IRC_ACNT_REGISTRY,chan->name);
111   DocTreeWrite(registry_doc,path,TRUE,"StrNew(\"%Q\");",msg);
112   Free(path);
113 }
114 U0 IrcLoadChannelTopic(IrcChannel *chan) {
115   U8 *path=MStrPrint("%s/%s/Topic",IRC_CHAN_REGISTRY,chan->name);
116   U8 *topic=DocTreeExe(registry_doc,path);
117   if(topic) StrCpy(chan->topic,topic);
118   Free(path),Free(topic);
119 }
120 U0 IrcAddToBacklog(IrcChannel *chan,U8 *nick,U8 *msg,Bool add_to_disk=TRUE) {
121   U8 *buf=MAlloc(4096),*tmp;
122   CDoc *disk_doc;
123   StrPrint(buf," %s:%s",nick,msg);
124   CFifoI64 *new_fifo;
125 
126   if(!FileFind(IRC_BACKLOG_DIR))
127     DirMk(IRC_BACKLOG_DIR);
128 
129   tmp=MStrPrint(IRC_BACKLOG_DIR"/%s",chan->name+1);
130   if(FileFind(tmp))
131     disk_doc=DocRead(tmp,DOCF_NO_CURSOR|DOCF_PLAIN_TEXT);
132   else
133     disk_doc=DocNew(tmp);
134   disk_doc->flags|=DOCF_NO_CURSOR|DOCF_PLAIN_TEXT;
135   Free(tmp);
136 
137   if(!GihonFifoIns(chan->backlog,tmp=StrNew(buf,gihon_task))) {
138     DocClear(disk_doc);
139 
140     new_fifo=FifoI64New(BACKLOG_FIFO_SZ,gihon_task);
141     GihonFifoIns(new_fifo,tmp);
142     while(FifoI64Rem(chan->backlog,&tmp)) {
143       DocPrint(disk_doc,"%s\n",tmp);
144       if(!GihonFifoIns(new_fifo,tmp))
145         Free(tmp);
146       }
147     GihonFifoIns(new_fifo,StrNew(buf));
148     FifoI64Del(chan->backlog);
149     chan->backlog=new_fifo;
150 
151     DocBottom(disk_doc);
152     DocPrint(disk_doc,"%s\n",buf);
153   } else {
154     DocBottom(disk_doc);
155     DocPrint(disk_doc,"%s\n",buf);
156   }
157 
158   if(add_to_disk) DocWrite(disk_doc);
159   DocDel(disk_doc);
160   Free(buf);
161 }
162 U0 IrcSetChannelPassword(IrcChannel *chan,U8 *pass) {
163   if(!pass)
164     chan->password_hash=0;
165   else
166     chan->password_hash=HashStr(pass);
167   U8 *path=MStrPrint("%s/%s/PasswordHash",IRC_CHAN_REGISTRY,chan->name);
168   DocTreeWrite(registry_doc,path,TRUE,"%d;\n",chan->password_hash);
169   Free(path);  
170 }
171 U0 IrcLoadChannelPassword(IrcChannel *chan) {
172   U8 *path=MStrPrint("%s/%s/PasswordHash",IRC_CHAN_REGISTRY,chan->name);
173   chan->password_hash=DocTreeExe(registry_doc,path);
174   Free(path);
175 }
176 
177 U0 IrcAddPrivMsgToUserMail(IrcClient *sender,U8 *to,U8 *msg) {
178   U8 *path=MStrPrint("%s/%s",IRC_ACNT_REGISTRY,to);
179   CDoc *doc;
180    //Check if user account exists
181   if(DocTreeFind(registry_doc,path)) {
182      Free(path);
183      if(!FileFind(IRC_MAIL_DIR)) DirMk(IRC_MAIL_DIR);
184      path=MStrPrint(IRC_MAIL_DIR"/%s",to);
185      if(!FileFind(path))
186        doc=DocNew(path);
187      else {
188        doc=DocRead(path,DOCF_NO_CURSOR);
189      }
190      doc->flags|=DOCF_NO_CURSOR;
191      DocBottom(doc);
192      DocPrint(doc,":%s!%s@%s %s %s :%s\n",sender->nick,sender->username,sender->host,"PRIVMSG",to,msg);
193      DocWrite(doc);
194      DocDel(doc);
195   }
196   Free(path);
197 }
198 #endif