// /adm/daemons/network/I3/news.c // Last edited Nov 10, 2003. // Tim // News server thing. // Started Nov 8, 2003. #include #include inherit SAVE_D; #define INFO_FIRST 0 #define INFO_LAST 1 #define INFO_PERM 2 #define INFO_DIR 3 #define PERM_READ_ONLY 0 // read-only #define PERM_AUTH_READ 1 // only auth'd can read and post #define PERM_AUTH_POST 2 // all can read, auth'd can post #define PERM_OPEN 3 // all can read or post mapping group_info; // first, last, permission, subdir void create(){ seteuid(getuid()); set_persistent(1); // Defaults, ::create() will load the data file and overwrite these if the data is there. group_info = ([ ]); ::create(); } void add_group(string str){ group_info[str] = ( ({ 1,0,PERM_OPEN,str }) ); } void rem_group(string str){ map_delete(group_info,str); write("Group "+str+" removed.\n"); } void oob_process_news_grplist_req(int fd, mixed info){ mixed output=({ }); string grp; object tim; tim=find_player("tim"); if(tim) message("news","Called oob_process_news (fd="+fd+"), data="+identify(info)+"\n",tim); foreach(grp in keys(group_info)){ output += ({ ({grp, group_info[grp][INFO_FIRST], group_info[grp][INFO_LAST]}) }); } I3_DAEMON->oob_write_data(fd, output); return; } void oob_process_news_read_req(int fd, mixed info){ // I am writing my own specs for news-read-req, leaving out useless // info and then also allowing them if they decide to act like the // specs anyway. // "news-read-req" // 5 // left out // originator_mudname // left out // originator_username // left out // 0 // left out // 0 // left out // newsgroup_name // id // // originator_mudname was left out because oob-req tells // what mud the client is // originator_username was left out because I can't think of // any case where the server would care as to which user // it is int id; string newsgroup_name; if(sizeof(info)==8){ if(!intp(info[1]) || !stringp(info[2])){ I3_DAEMON->oob_write_data(fd,({ "error", "invalid news-read-req" })); return; } id = info[1]; newsgroup_name = info[2]; } else{ if((sizeof(info)!=3) || !intp(info[6]) || !stringp(info[7]) ){ I3_DAEMON->oob_write_data(fd,({ "error", "invalid news-read-req" })); return; } id = info[1]; newsgroup_name = info[2]; } // At this point, valid request and newsgroup_name and id were set. if(member_array(keys(group_info),newsgroup_name)==-1){ // not a group I3_DAEMON->oob_write_data(fd,({ "error", newsgroup_name+ " is not a group" })); return; } if((group_info[newsgroup_name][INFO_PERM]==PERM_AUTH_READ) && !I3_DAEMON->get_auth(fd)){ I3_DAEMON->oob_write_data(fd,({ "error", "Only muds that use auth are allowed to read "+ newsgroup_name+"." })); return; } // Allowed to read at this point, valid group. if((id>group_info[newsgroup_name][INFO_LAST]) || (idoob_write_data(fd,({ "error","ID out of range." }) ); return; } // Valid request... I3_NEWS_OB->set_id(id); I3_NEWS_OB->set_dir(group_info[newsgroup_name][INFO_DIR]); if(!I3_NEWS_OB->load_msg()){ I3_DAEMON->oob_write_data(fd,({ "error", "Error loading message" })); return; } // Yay. I3_DAEMON->oob_write_data(fd,I3_NEWS_OB->get_info()); } void oob_process_news_post_req(int fd, mixed info){ // "news-post-req" // originator_mudname // ignored if using auth // mud_login_port // ignored if using auth // newsgroup // thread_id // subject // poster // contents string poster; if((sizeof(info)!=8) || !stringp(info[1]) || !intp(info[2]) || !stringp(info[3]) || !stringp(info[4]) || !stringp(info[5]) || !stringp(info[6]) || !stringp(info[7])){ I3_DAEMON->oob_write_data(fd,({ "error", "Invalid news-post-req." })); return; } if(member_array(info[3],keys(group_info))==-1){ // not a group I3_DAEMON->oob_write_data(fd,({ "error", info[3]+ " is not a group" })); return; } switch(group_info[info[3]][INFO_PERM]){ case PERM_READ_ONLY: I3_DAEMON->oob_write_data(fd,({ "error", info[3]+ " is read-only" })); return; case PERM_AUTH_READ: // same posting permission as PERM_AUTH_POST case PERM_AUTH_POST: if(!I3_DAEMON->get_auth(fd)){ I3_DAEMON->oob_write_data(fd,({ "error", info[3]+ " requires you to us auth" })); return; } break; case PERM_OPEN: // all can read or post break; } // Permission is okay at this point I think. if(!I3_DAEMON->get_auth(fd)){ poster = info[6]+"@"+I3_DAEMON->get_auth(fd); // just use the mudname they authed with } else{ sscanf(socket_address(fd),"%s %*s",poster); poster = "WITHOUT AUTH: ["+socket_address(fd)+":"+info[2]+ "]"+info[6]+"@"+info[2]; } group_info[info[3]][INFO_LAST] += 1; I3_NEWS_OB->set_dir(group_info[info[3]][INFO_DIR]); I3_NEWS_OB->set_id(group_info[info[3]][INFO_LAST]); I3_NEWS_OB->set_poster(poster); I3_NEWS_OB->set_posting_time(time()); I3_NEWS_OB->set_thread_id(info[4]); I3_NEWS_OB->set_subject(info[5]); I3_NEWS_OB->set_contents(info[7]); I3_NEWS_OB->save_message(); I3_DAEMON->oob_write_data(fd, ({ group_info[info[3]][INFO_LAST] })); }