static void readUnlock(skipList list, skipItem x, void **plock) { int startFlush = FALSE; if(list->threaded) mLock(&list->read); if(plock) { x->locks++; *plock = x; } if(! list->threaded) return; list->readers--; if((list->readers == 0) && list->block) startFlush = TRUE; mUnlock(&list->read); if(startFlush) cSignal(&list->flush); return; }
//************************************************************ //********功能:pop一个工作对象 //********参数:无 //********返回值:工作对象的shared_ptr指针 //************************************************************ shared_ptr<CJob> CJobQueue::popJop() { CLock mLock(m_mutex); if (m_JobQueue.empty())return NULL; shared_ptr<CJob> job = m_JobQueue.front(); m_JobQueue.pop(); return job; }
//************************************************************ //********功能:向工作队列中压入一个工作对象 //********参数:工作对象的shared_ptr指针 //********返回值: //************************************************************ void CJobQueue::pushJob(shared_ptr<CJob>& job) { if (job != NULL) { CLock mLock(m_mutex); m_JobQueue.push(job); } }
TA3DSock *SockList::getSock(const int id) { MutexLocker mLock(*this); SockType::iterator i = sockets.find(id); if (i == sockets.end()) return NULL; return (*i)->sock; }
SocketThread *SockList::getThread(const int id) { MutexLocker mLock(*this); SockType::iterator i = sockets.find(id); if (i == sockets.end()) return NULL; return &((*i)->thread); }
int SockList::Remove(const int id) { MutexLocker mLock(*this); if (!sockets.contains(id)) return -1; delete sockets[id]; sockets.remove(id); return 0; }
static void readBlock(skipList list) { mLock(&list->read); list->block = TRUE; if(list->readers) cWait(&list->flush, &list->read); /* wait until reader locks released */ return; }
NEOERR *nerr_init (void) { NEOERR *err; if (Inited == 0) { #ifdef HAVE_PTHREADS /* In threaded environments, we have to mutex lock to do this init, but * we don't want to use a mutex every time to check that it was Inited. * So, we only lock if our first test of Inited was false */ err = mLock(&InitLock); if (err != STATUS_OK) return nerr_pass(err); if (Inited == 0) { #endif err = uListInit (&Errors, 10, 0); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_PASS, "InternalPass"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_ASSERT, "AssertError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_NOT_FOUND, "NotFoundError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_DUPLICATE, "DuplicateError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_NOMEM, "MemoryError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_PARSE, "ParseError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_OUTOFRANGE, "RangeError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_SYSTEM, "SystemError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_IO, "IOError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_LOCK, "LockError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_DB, "DBError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_EXISTS, "ExistsError"); if (err != STATUS_OK) return nerr_pass(err); err = nerr_register (&NERR_MAX_RECURSION, "MaxRecursionError"); if (err != STATUS_OK) return nerr_pass(err); Inited = 1; #ifdef HAVE_PTHREADS } err = mUnlock(&InitLock); if (err != STATUS_OK) return nerr_pass(err); #endif } return STATUS_OK; }
int SockList::Add(TA3DSock* sock) { MutexLocker mLock(*this); if (maxid > 10000) //arbitrary limit return -1; SocketNode *node = new SocketNode; ++maxid; sockets[maxid] = node; node->sock = sock; return maxid; }
bool getOnFile(KeyType id, ValueType& value) { char* ptr = NULL; int sp; { boost::lock_guard<boost::mutex> mLock(readWriteMutex_); ptr = fileData_.get(id, sp); } if(ptr==NULL) return false; SerializeType::deserialize(ptr, (std::size_t)sp, value); free(ptr); return true; }
static void readLock(skipList list) { mLock(&list->read); if(list->block) cWait(&list->resume, &list->read); list->readers++; mUnlock(&list->read); return; }
void skipRelease(skipList list, void *lock) { skipItem x; mLock(&list->read); x = lock; x->locks--; mUnlock(&list->read); return; }
void update(KeyType id, const ValueType& value) { if( !isOpen() ) return; std::size_t vsize; char* data = SerializeType::serialize(value, vsize); if( vsize>0 ) { boost::lock_guard<boost::mutex> mLock(readWriteMutex_); fileData_.update(id, data, vsize); this->insertToCache(id, value); free(data); } }
static void writeLock(skipList list) { mLock(&list->write); return; }
bool ServerAgent::ParseENums (const char *data, const char *sWord) { int num (atoi (sWord)); switch (num) { case ZERO: // 0 { // wasn't a numeric, or the server is playing tricks on us } return false; case ERR_UNKNOWNCOMMAND: // 421 { BString tempString (RestOfString (data, 4)), badCmd (GetWord (data, 4)); if (badCmd == "VISION_LAG_CHECK") { int32 difference (system_time() - fLagCheck); if (difference > 0) { int32 secs (difference / 1000000); int32 milli (difference / 1000 - secs * 1000); char lag[15] = ""; sprintf (lag, "%0" B_PRId32 ".%03" B_PRId32, secs, milli); fMyLag = lag; fLagCount = 0; fCheckingLag = false; fMsgr.SendMessage (M_LAG_CHANGED); } } else { tempString.RemoveFirst (":"); tempString.Append ("\n"); Display (tempString.String()); } } return true; case RPL_WELCOME: // 001 case RPL_YOURHOST: // 002 case RPL_CREATED: // 003 case RPL_MYINFO: // 004 { fConnected = true; fIsConnecting = false; fInitialMotd = true; fRetry = 0; if (num == RPL_WELCOME) { BString message = B_TRANSLATE("Established"); message.Prepend("[@] ").Append("\n"); Display(message.String(), C_ERROR, C_BACKGROUND, F_SERVER); } if (fNetworkData.FindBool ("lagCheck")) { fMyLag = "0.000"; fMsgr.SendMessage (M_LAG_CHANGED); } BString theNick (GetWord (data, 3)); fMyNick = theNick; if (!IsHidden()) vision_app->pClientWin()->pStatusView()->SetItemValue (STATUS_NICK, theNick.String()); BString theMsg (RestOfString (data, 4)); theMsg.RemoveFirst (":"); theMsg.Prepend ("* "); theMsg.Append ("\n"); Display (theMsg.String()); if (num == RPL_MYINFO) { // set "real" hostname fServerHostName = (GetWord (data, 1)); fServerHostName.RemoveFirst (":"); BString hostName (fId.String()); hostName += " - ["; hostName += fServerHostName.String(); hostName += "]"; fAgentWinItem->SetName (hostName.String()); // detect IRCd fIrcdtype = IRCD_STANDARD; if (theMsg.FindFirst("hybrid") > 0) fIrcdtype = IRCD_HYBRID; // ultimate and unreal share the same numerics, so treat them with the same // identifier for now else if ((theMsg.FindFirst("UltimateIRCd") > 0) || (theMsg.FindFirst("Unreal") > 0)) fIrcdtype = IRCD_ULTIMATE; else if (theMsg.FindFirst("comstud") > 0) fIrcdtype = IRCD_COMSTUD; else if (theMsg.FindFirst("u2.") > 0) fIrcdtype = IRCD_UNDERNET; else if (theMsg.FindFirst("PTlink") > 0) fIrcdtype = IRCD_PTLINK; else if (theMsg.FindFirst ("CR") > 0) fIrcdtype = IRCD_CONFERENCEROOM; else if (theMsg.FindFirst ("nn-") > 0) fIrcdtype = IRCD_NEWNET; } } return true; case RPL_PROTOCTL: // 005 { // this numeric also serves as RPL_NNMAP on Newnet BString theMsg (RestOfString (data, 4)); theMsg.RemoveFirst (":"); theMsg.Append ("\n"); switch (fIrcdtype) { case IRCD_NEWNET: { // RPL_NNMAP Display (theMsg.String()); } break; default: { // RPL_PROTOCTL theMsg.Prepend ("* "); Display (theMsg.String()); } } } return true; case RPL_LUSERHIGHESTCONN: // 250 case RPL_LUSERCLIENT: // 251 case RPL_LUSEROP: // 252 case RPL_LUSERUNKNOWN: // 253 case RPL_LUSERCHANNELS: // 254 case RPL_LUSERME: // 255 case RPL_LUSERLOCAL: // 265 case RPL_LUSERGLOBAL: // 266 { BString theMsg (RestOfString (data, 4)); theMsg.RemoveFirst (":"); theMsg.Prepend ("* "); theMsg.Append ("\n"); Display (theMsg.String()); } return true; /// strip and send to server agent /// case RPL_ULMAP: // 006 case RPL_ULMAPEND: // 007 case RPL_U2MAP: // 015 case RPL_U2MAPEND: // 017 case RPL_TRACELINK: // 200 case RPL_TRACECONNECTING: // 201 case RPL_TRACEHANDSHAKE: // 202 case RPL_TRACEUNKNOWN: // 203 case RPL_TRACEOPERATOR: // 204 case RPL_TRACEUSER: // 205 case RPL_TRACESERVER: // 206 case RPL_TRACENEWTYPE: // 208 case RPL_TRACECLASS: // 209 case RPL_STATSLINKINFO: // 211 case RPL_STATSCOMMANDS: // 212 case RPL_STATSCLINE: // 213 case RPL_STATSNLINE: // 214 case RPL_STATSILINE: // 215 case RPL_STATSKLINE: // 216 case RPL_STATSQLINE: // 217 case RPL_STATSYLINE: // 218 case RPL_ENDOFSTATS: // 219 case RPL_STATSBLINE: // 220 case RPL_DALSTATSE: // 223 case RPL_DALSTATSF: // 224 case RPL_DALSTATSZ: // 225 case RPL_DALSTATSN: // 226 case RPL_DALSTATSG: // 227 case RPL_STATSLLINE: // 241 case RPL_STATSUPTIME: // 242 case RPL_STATSOLINE: // 243 case RPL_STATSHLINE: // 244 case RPL_STATSSLINE: // 245 case RPL_DALSTATSX: // 246 case RPL_STATSXLINE: // 247 case RPL_STATSPLINE: // 249 case RPL_ADMINME: // 256 case RPL_ADMINLOC1: // 257 case RPL_ADMINLOC2: // 258 case RPL_ADMINEMAIL: // 259 case RPL_TRACELOG: // 261 case RPL_ENDOFTRACE: // 262 case RPL_SILELIST: // 271 case RPL_ENDOFSILELIST: // 272 case RPL_ENDOFWHO: // 315 case RPL_CHANSERVURL: // 328 case RPL_COMMANDSYNTAX: // 334 case RPL_VERSION: // 351 case RPL_WHOREPLY: // 352 case RPL_BANLIST: // 367 case RPL_ENDOFBANLIST: // 368 case RPL_INFO: // 371 case RPL_ENDOFINFO: // 374 case RPL_YOUREOPER: // 381 case RPL_REHASHING: // 382 case RPL_TIME: // 391 case ERR_NOORIGIN: // 409 case ERR_NOTEXTTOSEND: // 412 case ERR_TOOMANYAWAY: // 429 case ERR_NICKCHANGETOOFAST: // 438 case ERR_TARGETCHANGETOOFAST: // 439 case ERR_SUMMONDISABLED: // 445 case ERR_USERSDISABLED: // 446 case ERR_NOTREGISTERED: // 451 case ERR_NEEDMOREPARMS: // 461 case ERR_PASSWDMISMATCH: // 464 case ERR_YOUREBANNEDCREEP: // 465 case ERR_NOPRIVILEGES: // 481 case ERR_NOOPERHOST: // 491 case ERR_USERSDONTMATCH: // 502 case ERR_SILELISTFULL: // 511 case ERR_TOOMANYWATCH: // 512 case ERR_TOOMANYDCC: // 514 case ERR_CANTINVITE: // 518 case ERR_LISTSYNTAX: // 521 case ERR_WHOSYNTAX: // 522 case ERR_WHOLIMEXCEED: // 523 case RPL_LOGON: // 600 case RPL_LOGOFF: // 601 case RPL_WATCHOFF: // 602 case RPL_WATCHSTAT: // 603 case RPL_NOWON: // 604 case RPL_NOWOFF: // 605 case RPL_WATCHLIST: // 606 case RPL_ENDOFWATCHLIST: // 607 case RPL_DCCALLOWLIST: // 618 case RPL_DCCALLOWEND: // 619 case RPL_DCCALLOW: // 620 { BString tempString (RestOfString (data, 4)); tempString.RemoveFirst (":"); tempString.Append ("\n"); Display (tempString.String()); } return true; case RPL_UMODEIS: // 221 { BString theMode (GetWord (data, 4)); BString tempString = B_TRANSLATE("Your current mode is %1"); tempString.ReplaceFirst("%1", theMode); tempString += '\n'; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_WHOIS); PostActive (&msg); } return true; /// strip and send to active agent /// case RPL_TRYAGAIN: // 263 case RPL_UNAWAY: // 305 case RPL_NOWAWAY: // 306 case ERR_NOSUCHNICK: // 401 case ERR_NOSUCHSERVER: // 402 case ERR_NOSUCHCHANNEL: // 403 case ERR_CANNOTSENDTOCHAN: // 404 case ERR_TOOMANYCHANNELS: // 405 case ERR_WASNOSUCHNICK: // 406 case ERR_TOOMANYTARGETS: // 407 case ERR_NOCOLORSONCHAN: // 408 case ERR_YOUCANTDOTHAT: // 460 case ERR_CHANOPRIVSNEEDED: // 482 { BString tempString ("[x] "); if (num == ERR_CHANOPRIVSNEEDED) tempString += RestOfString (data, 5); else tempString += RestOfString (data, 4); tempString.RemoveFirst (":"); tempString.Append ("\n"); BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&msg); } return true; case RPL_AWAY: // 301 { BString theNick (GetWord(data, 4)); BString tempString ("[x] "), theReason (RestOfString(data, 5)); theReason.RemoveFirst(":"); tempString += "Away: "; tempString += theReason; tempString += '\n'; if (fRemoteAwayMessages.find(theNick) != fRemoteAwayMessages.end()) { if (fRemoteAwayMessages[theNick] == theReason) { return true; } } fRemoteAwayMessages[theNick] = theReason; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&msg); } return true; case RPL_USERHOST: // 302 { BString theHost (GetWord (data, 4)), theHostname (GetAddress (theHost.String())); theHost.RemoveFirst (":"); BString tempString (RestOfString (data, 4)); tempString.RemoveFirst (":"); tempString.Append ("\n"); Display (tempString.String()); if (fGetLocalIP && (tempString.IFindFirst (fMyNick.String()) == 0)) { fGetLocalIP = false; struct addrinfo *info; struct addrinfo hints; memset(&hints, 0, sizeof(addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; int result = getaddrinfo(theHostname.String(), NULL, &hints, &info); if (result == 0) { char addr_buf[INET6_ADDRSTRLEN]; getnameinfo(info->ai_addr, info->ai_addrlen, addr_buf, sizeof(addr_buf), NULL, 0, NI_NUMERICHOST); fLocalip = addr_buf; printf("Got address: %s\n", fLocalip.String()); freeaddrinfo(info); return true; } } } return true; case RPL_ISON: // 303 { BString nicks (RestOfString (data, 4)); BString onlined, offlined; nicks.RemoveFirst (":"); int hasChanged (0); BMessage msg (M_NOTIFYLIST_UPDATE); for (int32 i = 0; i < fNotifyNicks.CountItems(); i++) { NotifyListItem *item (((NotifyListItem *)fNotifyNicks.ItemAt(i))); int32 nickidx (nicks.IFindFirst(item->Text())); // make sure that the nick isn't a partial match. if ((nickidx >= 0) && ((nicks[nickidx + strlen(item->Text())] == ' ') || (nicks[nickidx + strlen(item->Text())] == '\0'))) { if (item->GetState() != true) { item->SetState (true); hasChanged = 1; if (onlined.Length()) onlined << ", "; onlined << item->Text(); #ifdef USE_INFOPOPPER if (be_roster->IsRunning(InfoPopperAppSig) == true) { entry_ref ref = vision_app->AppRef(); BMessage infoMsg(InfoPopper::AddMessage); infoMsg.AddString("appTitle", S_INFOPOPPER_TITLE); infoMsg.AddString("title", fId.String()); infoMsg.AddInt8("type", (int8)InfoPopper::Information); infoMsg.AddInt32("iconType", InfoPopper::Attribute); infoMsg.AddRef("iconRef", &ref); BString content; content << item->Text() << " is online"; infoMsg.AddString("content", content); BMessenger(InfoPopperAppSig).SendMessage(&infoMsg); }; #endif } } else { if (item->GetState() == true) { item->SetState (false); hasChanged = 2; if (offlined.Length()) offlined << ", "; offlined << item->Text(); #ifdef USE_INFOPOPPER if (be_roster->IsRunning(InfoPopperAppSig) == true) { entry_ref ref = vision_app->AppRef(); BMessage infoMsg(InfoPopper::AddMessage); infoMsg.AddString("appTitle", S_INFOPOPPER_TITLE); infoMsg.AddString("title", fId.String()); infoMsg.AddInt8("type", (int8)InfoPopper::Information); infoMsg.AddInt32("iconType", InfoPopper::Attribute); infoMsg.AddRef("iconRef", &ref); BString content; content << item->Text() << " is offline"; infoMsg.AddString("content", content); BMessenger(InfoPopperAppSig).SendMessage(&infoMsg); }; #endif } } #ifdef __HAIKU__ if (offlined.Length()) { BNotification notification(B_INFORMATION_NOTIFICATION); notification.SetGroup(BString("Vision")); entry_ref ref = vision_app->AppRef(); notification.SetOnClickFile(&ref); notification.SetTitle(fServerName.String()); BString content; content << offlined; if (offlined.FindFirst(' ') > -1) content << " are offline"; else content << " is offline"; notification.SetContent(content); notification.Send(); } if (onlined.Length()) { BNotification notification(B_INFORMATION_NOTIFICATION); notification.SetGroup(BString("Vision")); entry_ref ref = vision_app->AppRef(); notification.SetOnClickFile(&ref); notification.SetTitle(fServerName.String()); BString content; content << onlined; if (onlined.FindFirst(' ') > -1) content << " are online"; else content << " is online"; notification.SetContent(content); notification.Send(); } #endif } fNotifyNicks.SortItems(SortNotifyItems); msg.AddPointer ("list", &fNotifyNicks); msg.AddPointer ("source", this); msg.AddInt32 ("change", hasChanged); Window()->PostMessage (&msg); } return true; case RPL_WHOISIDENTIFIED: // 307 { BString theInfo (RestOfString (data, 5)); theInfo.RemoveFirst (":"); if (theInfo == "-9z99") { // USERIP reply? (RPL_U2USERIP) BString tempString (RestOfString (data, 4)); tempString.RemoveFirst (":"); tempString.Append ("\n"); Display (tempString.String()); return true; } BMessage display (M_DISPLAY); BString buffer; buffer += "[x] "; buffer += theInfo; buffer += "\n"; PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&display); } return true; case RPL_WHOISADMIN: // 308 case RPL_WHOISSERVICESADMIN: // 309 case RPL_WHOISHELPOP: // 310 case RPL_WHOISOPERATOR: // 313 case RPL_WHOISREGNICK: // 320 case RPL_WHOISACTUALLY: // 338 case RPL_WHOISMASK: // 550 case RPL_WHOWASIP: // 612 case RPL_WHOISUSERMODESALT: // 614 case RPL_WHOISUSERMODES: // 615 case RPL_WHOISREALHOSTNAME: // 616 { BString theInfo (RestOfString (data, 5)); theInfo.RemoveFirst (":"); BMessage display (M_DISPLAY); BString buffer; buffer += "[x] "; buffer += theInfo; buffer += "\n"; PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&display); } return true; case RPL_WHOISUSER: // 311 { BString theNick (GetWord (data, 4)), theIdent (GetWord (data, 5)), theAddress (GetWord (data, 6)), theName (RestOfString (data, 8)); theName.RemoveFirst (":"); BMessage display (M_DISPLAY); BString buffer; buffer += "[x] "; buffer += theNick; buffer += " ("; buffer += theIdent; buffer += "@"; buffer += theAddress; buffer += ")\n"; buffer += "[x] "; buffer += theName; buffer += "\n"; PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&display); } return true; case RPL_WHOISSERVER: // 312 { BString theNick (GetWord (data, 4)), theServer (GetWord (data, 5)), theInfo (RestOfString (data, 6)); theInfo.RemoveFirst (":"); BMessage display (M_DISPLAY); BString buffer; buffer += "[x] Server: "; buffer += theServer; buffer += " ("; buffer += theInfo; buffer += ")\n"; PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&display); } return true; case RPL_WHOWASUSER: // 314 { BString theNick (GetWord (data, 4)), theIdent (GetWord (data, 5)), theAddress (GetWord (data, 6)), theName (RestOfString (data, 8)), tempString ("[x] "); theName.RemoveFirst (":"); tempString += B_TRANSLATE("%1 was (%2)"); tempString.ReplaceFirst("%1", theNick); BString nickString = theIdent << "@" << theAddress; tempString.ReplaceFirst("%2", nickString.String()); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&msg); } return true; case RPL_WHOISIDLE: // 317 { BString theNick (GetWord (data, 4)), tempString ("[x] "), tempString2 ("[x] "), theTime (GetWord (data, 5)), signOnTime (GetWord (data, 6)); int64 idleTime (strtoul(theTime.String(), NULL, 0)); tempString += B_TRANSLATE("Idle"); tempString += ": "; tempString += DurationString(idleTime * 1000 * 1000); tempString += "\n"; int32 serverTime = strtoul(signOnTime.String(), NULL, 0); struct tm ptr; time_t st; char str[80]; st = serverTime; localtime_r (&st, &ptr); strftime (str,80,"%A %b %d %Y %I:%M %p %Z", &ptr); BString signOnTimeParsed (str); signOnTimeParsed.RemoveAll ("\n"); tempString2 += B_TRANSLATE("Signon"); tempString2 += ": "; tempString2 += signOnTimeParsed; tempString2 += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&msg); PackDisplay (&msg, tempString2.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&msg); } return true; case RPL_ENDOFWHOIS: // 318 case RPL_ENDOFNAMES: // 366 case RPL_ENDOFWHOWAS: // 369 { // nothing } return true; case RPL_WHOISCHANNELS: // 319 { BString theChannels (RestOfString (data, 5)); theChannels.RemoveFirst(":"); BMessage display (M_DISPLAY); BString buffer = "[x] "; buffer += B_TRANSLATE("Channels"); buffer += ": "; buffer += theChannels; buffer += "\n"; PackDisplay (&display, buffer.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&display); } return true; case RPL_LISTSTART: // 321 { BMessage msg (M_LIST_BEGIN); if (fListAgent) vision_app->pClientWin()->DispatchMessage(&msg, (BView *)fListAgent); } return true; case RPL_LIST: // 322 { BMessage msg (M_LIST_EVENT); BString channel (GetWord (data, 4)), users (GetWord (data, 5)), topic (RestOfString (data, 6)); topic.RemoveFirst (":"); msg.AddString ("channel", channel.String()); msg.AddString ("users", users.String()); msg.AddString ("topic", topic.String()); if (fListAgent) vision_app->pClientWin()->DispatchMessage(&msg, (BView *)fListAgent); } return true; case RPL_LISTEND: // 323 { BMessage msg (M_LIST_DONE); if (fListAgent) vision_app->pClientWin()->DispatchMessage(&msg, (BView *)fListAgent); } return true; case RPL_CHANNELMODEIS: // 324 { BString theChan (GetWord (data, 4)), theMode (GetWord (data, 5)), tempStuff (RestOfString (data, 6)); if (tempStuff != "-9z99") { theMode.Append(" "); theMode.Append(tempStuff); // avoid extra space w/o params } ClientAgent *aClient (ActiveClient()), *theClient (Client (theChan.String())); BString tempString("*** "); tempString += B_TRANSLATE("Channel mode for %1: %2"); tempString.ReplaceFirst("%1", theChan.String()); tempString.ReplaceFirst("%2", theMode.String()); tempString += '\n'; BMessage msg (M_CHANNEL_MODES); msg.AddString ("msgz", tempString.String()); msg.AddString ("chan", theChan.String()); msg.AddString ("mode", theMode.String()); if (theClient) theClient->fMsgr.SendMessage (&msg); else if (aClient) aClient->fMsgr.SendMessage (&msg); else Display (tempString.String(), C_OP); } return true; case RPL_CHANNELMLOCK: // 325 { BString theChan (GetWord (data, 4)), mLock (GetWord (data, 8)), lockMessage ("*** "); lockMessage += B_TRANSLATE("Channel mode lock for %1: %2"); lockMessage.ReplaceFirst("%1", theChan); lockMessage.ReplaceFirst("%2", mLock); lockMessage += "\n"; BMessage display (M_DISPLAY); PackDisplay (&display, lockMessage.String(), C_OP, C_BACKGROUND, F_TEXT); ClientAgent *theClient (Client (theChan.String())); if (theClient) theClient->fMsgr.SendMessage (&display); else fMsgr.SendMessage (&display); } return true; case RPL_CHANNELCREATED: // 329 { BString theChan (GetWord (data, 4)), theTime (GetWord (data, 5)), tempString; int32 serverTime (strtoul(theTime.String(), NULL, 0)); struct tm ptr; time_t st; char str[80]; st = serverTime; localtime_r (&st, &ptr); strftime (str,80,"%a %b %d %Y %I:%M %p %Z",&ptr); BString theTimeParsed (str); theTimeParsed.RemoveAll ("\n"); tempString = B_TRANSLATE("Channel %1 was created at %2"); tempString.ReplaceFirst("%1", theChan); tempString.ReplaceFirst("%2", theTimeParsed); tempString += '\n'; Display (tempString.String()); } return true; case RPL_NOTOPIC: // 331 { BString theChan (GetWord (data, 4)), tempString ("[x] "); tempString += B_TRANSLATE("No topic set in %1"); tempString.ReplaceFirst("%1", theChan); tempString += '\n'; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_ERROR); PostActive (&msg); } return true; case RPL_TOPIC: // 332 { BString theChannel (GetWord (data, 4)), theTopic (RestOfString (data, 5)); ClientAgent *client (Client (theChannel.String())); theTopic.RemoveFirst (":"); if (client) { BMessage display (M_DISPLAY); BString buffer; buffer += "*** "; buffer += B_TRANSLATE("Topic: %1"); buffer.ReplaceFirst("%1", theTopic); buffer += '\n'; PackDisplay (&display, buffer.String(), C_WHOIS); BMessage msg (M_CHANNEL_TOPIC); msg.AddString ("topic", theTopic.String()); msg.AddMessage ("display", &display); if (client->fMsgr.IsValid()) client->fMsgr.SendMessage (&msg); } } return true; case RPL_TOPICSET: // 333 { BString channel (GetWord (data, 4)), user (GetWord (data, 5)), theTime (GetWord (data, 6)); int32 serverTime (strtoul(theTime.String(), NULL, 0)); struct tm ptr; time_t st; char str[80]; st = serverTime; localtime_r (&st, &ptr); strftime (str,80,"%A %b %d %Y %I:%M %p %Z",&ptr); BString theTimeParsed (str); theTimeParsed.RemoveAll ("\n"); ClientAgent *client (Client (channel.String())); if (client) { BMessage display (M_DISPLAY); BString buffer = "*** "; buffer += B_TRANSLATE("Topic set by %1 at %2"); buffer.ReplaceFirst("%1", user); buffer.ReplaceFirst("%2", theTimeParsed); buffer += '\n'; PackDisplay (&display, buffer.String(), C_WHOIS); if (client->fMsgr.IsValid()) client->fMsgr.SendMessage (&display); } } return true; case RPL_INVITING: // 341 { BString channel (GetWord (data, 5)), theNick (GetWord (data, 4)), tempString; tempString += "*** "; tempString += B_TRANSLATE("%1 has been invited to %2."); tempString.ReplaceFirst("%1", theNick); tempString.ReplaceFirst("%2", channel); tempString += "\n"; BMessage display (M_DISPLAY); PackDisplay (&display, tempString.String(), C_WHOIS); PostActive (&display); } return true; case RPL_NAMEREPLY: // 353 { BString channel (GetWord (data, 5)), names (RestOfString (data, 6)); ClientAgent *client (Client (channel.String())); names.RemoveFirst (":"); BString tempString ("*** "); tempString += B_TRANSLATE("Users in %1: %2"); tempString.ReplaceFirst("%1", channel); tempString.ReplaceFirst("%2", names); tempString += '\n'; Display (tempString.String(), C_TEXT); if (client) // in the channel { BMessage msg (M_CHANNEL_NAMES); BString nick; int32 place (1); while ((nick = GetWord (names.String(), place)) != "-9z99") { const char *sNick (nick.String()); bool founder (false), protect (false), op (false), voice (false), helper (false), ignored; if (nick[0] == '*') { ++sNick; founder = true; } else if (nick[0] == '!') { ++sNick; protect = true; } else if (nick[0] == '@') { ++sNick; op = true; } else if (nick[0] == '+') { ++sNick; voice = true; } else if (nick[0] == '%') { ++sNick; helper = true; } ignored = false; // BMessage aMsg (M_IS_IGNORED), reply; // aMsg.AddString ("server", fServerName.String()); // aMsg.AddString ("nick", sNick); // be_app_messenger.SendMessage (&aMsg, &reply); // reply.FindBool ("ignored", &ignored); msg.AddString ("nick", nick.String()); msg.AddBool ("founder", founder); msg.AddBool ("protect", protect); msg.AddBool ("op", op); msg.AddBool ("voice", voice); msg.AddBool ("helper", helper); msg.AddBool ("ignored", ignored); ++place; } if (client->fMsgr.IsValid()) client->fMsgr.SendMessage (&msg); } } return true; case RPL_MOTD: // 372 case RPL_MOTDALT: // 378 case RPL_OPERMOTDSTART: // 609 case RPL_OPERMOTD: // 610 case RPL_OPERENDOFMOTD: // 611 { BString tempString (RestOfString(data, 4)); tempString.RemoveFirst (":"); tempString.Append ("\n"); Display (tempString.String(), C_SERVER, C_BACKGROUND, F_SERVER); } return true; case RPL_MOTDSTART: // 375 { BString tempString ("- "); tempString += B_TRANSLATE("Server Message Of the Day"); tempString += ":\n"; Display (tempString.String(), C_SERVER, C_BACKGROUND, F_SERVER); } return true; case RPL_ENDOFMOTD: // 376 case ERR_NOMOTD: // 422 { BString tempString (RestOfString (data, 4)); tempString.RemoveFirst (":"); tempString.Append ("\n"); Display (tempString.String(), C_SERVER, C_BACKGROUND, F_SERVER); if (fInitialMotd && fCmds.Length()) { BMessage msg (M_SUBMIT_INPUT); const char *place (fCmds.String()), *eol; msg.AddInt32 ("which", PASTE_MULTI_NODELAY); while ((eol = strchr (place, '\n')) != 0) { BString line; line.Append (place, eol - place); msg.AddString ("data", line.String()); ParseAutoexecChans (line); place = eol + 1; } if (*place) { // check in case this was the only line ParseAutoexecChans (BString(place)); msg.AddString ("data", place); } msg.AddInt32 ("which", 3); msg.AddBool ("autoexec", true); fMsgr.SendMessage (&msg); } BString IPCommand ("/userhost "); IPCommand += fMyNick; ParseCmd (IPCommand.String()); if (fReconnecting) { BString reString = "[@] "; reString += B_TRANSLATE("Successful reconnect"); reString += "\n"; Display (reString.String(), C_ERROR); DisplayAll (reString.String(), C_ERROR, C_BACKGROUND, F_SERVER); fMsgr.SendMessage (M_REJOIN_ALL); fReconnecting = false; } fInitialMotd = false; } return true; case RPL_USERSSTART: // 392 { // empty for now } return true; case RPL_USERS: // 393 { // empty for now } return true; case ERR_ERRONEOUSNICKNAME: // 432 case ERR_NICKNAMEINUSE: // 433 case ERR_RESOURCEUNAVAILABLE: // 437 { BString theNick (GetWord (data, 4)); if (fIsConnecting) { BString nextNick (GetNextNick()); if (nextNick != "") { BString tempString = "* "; tempString += B_TRANSLATE("Nickname \"%1\" in use or unavailable, trying \"%2\""); tempString.ReplaceFirst("%1", theNick.String()); tempString.ReplaceFirst("%2", nextNick.String()); tempString += "\n"; Display (tempString.String()); tempString = "NICK "; tempString += nextNick; SendData (tempString.String()); return true; } else { BString tempString = "* "; tempString += B_TRANSLATE("All your pre-selected nicknames are in use."); tempString += "\n"; Display (tempString.String()); tempString = "* "; tempString += B_TRANSLATE("Please type /NICK <NEWNICK> to try another."); tempString += "\n"; Display (tempString.String()); return true; } } BString tempString = "[x] "; tempString += B_TRANSLATE("Nickname/Channel \"%1\" is already in use or unavailable."); tempString.ReplaceFirst("%1", theNick); tempString += "\n"; BMessage display (M_DISPLAY); PackDisplay (&display, tempString.String(), C_NICK); PostActive (&display); } return true; case ERR_USERNOTINCHANNEL: // 441 { BString theChannel (GetWord (data, 5)), theNick (GetWord (data, 4)), tempString ("[x] "); tempString += B_TRANSLATE("%1 not in %2."); tempString.ReplaceFirst("%1", theNick); tempString.ReplaceFirst("%2", theChannel); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_ERROR); PostActive (&msg); } return true; case ERR_NOTONCHANNEL: // 442 { BString theChannel (GetWord (data, 4)), tempString ("[x] "); tempString += B_TRANSLATE("You're not in %1."); tempString.ReplaceFirst("%1", theChannel); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_ERROR); PostActive (&msg); } return true; case ERR_USERONCHANNEL: // 443 { BString theChannel (GetWord (data, 5)), theNick (GetWord (data, 4)), tempString ("[x] "); tempString += B_TRANSLATE("%1 is already in %2."); tempString.ReplaceFirst("%1", theNick); tempString.ReplaceFirst("%2", theChannel); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_ERROR); PostActive (&msg); } return true; case ERR_KEYSET: // 467 { BString theChannel (GetWord (data, 4)), tempString ("[x] "); tempString += B_TRANSLATE("Channel key already set in %1."); tempString.ReplaceFirst("%1", theChannel); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_ERROR); PostActive (&msg); } return true; case ERR_UNKNOWNMODE: // 472 { BString theMode (GetWord (data, 4)), tempString ("[x] "); tempString += B_TRANSLATE("Unknown channel mode: '%1'."); tempString.ReplaceFirst("%1", theMode); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_QUIT); PostActive (&msg); } return true; case ERR_INVITEONLYCHAN: // 473 { BString theChan (GetWord (data, 4)), tempString ("[x] "), theReason (RestOfString (data, 5)); theReason.RemoveFirst(":"); theReason.ReplaceLast("channel", theChan.String()); tempString << theReason < " "; tempString += B_TRANSLATE("(invite only)"); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_QUIT, C_BACKGROUND, F_SERVER); PostActive (&msg); RemoveAutoexecChan (theChan); } return true; case ERR_BANNEDFROMCHAN: // 474 { BString theChan (GetWord (data, 4)), tempString ("[x] "), theReason (RestOfString (data, 5)); theReason.RemoveFirst(":"); theReason.ReplaceLast("channel", theChan.String()); tempString << theReason < " "; tempString += B_TRANSLATE("(you're banned)"); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_QUIT, C_BACKGROUND, F_SERVER); PostActive (&msg); RemoveAutoexecChan (theChan); } return true; case ERR_BADCHANNELKEY: // 475 { BString theChan (GetWord(data, 4)), theReason (RestOfString(data, 5)), tempString("[x] "); theReason.RemoveFirst(":"); theReason.ReplaceLast("channel", theChan.String()); tempString << theReason << " "; tempString += B_TRANSLATE("(bad channel key)"); tempString += "\n"; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_QUIT, C_BACKGROUND, F_SERVER); PostActive (&msg); RemoveAutoexecChan (theChan); } return true; case ERR_UMODEUNKNOWNFLAG: // 501 { BMessage msg (M_DISPLAY); BString buffer = "[x] "; buffer += B_TRANSLATE("Unknown mode flag."); buffer += "\n"; PackDisplay (&msg, buffer.String(), C_QUIT); PostActive (&msg); } return true; // not sure what these numerics are, // but they are usually on-connect messages case RPL_290: // 290 case RPL_291: // 291 case RPL_292: // 292 { BString tempString (RestOfString(data, 4)); tempString.RemoveFirst (":"); tempString.Append ("\n"); tempString.Prepend ("- "); Display (tempString.String()); } return true; case RPL_WHOISREGISTEREDBOT: // 617 { // conflicts with RPL_DCCALLOWCHANGE BString theNick (GetWord (data, 4)), theMessage (RestOfString (data, 5)), tempString; theNick.RemoveFirst (":"); theMessage.RemoveFirst (":"); theMessage.Append ("\n"); switch (fIrcdtype) { case IRCD_ULTIMATE: { tempString += "[@] "; tempString += theMessage; BMessage msg (M_DISPLAY); PackDisplay (&msg, tempString.String(), C_WHOIS, C_BACKGROUND, F_SERVER); PostActive (&msg); } break; default: { tempString += theNick; tempString += " "; tempString += theMessage; Display (tempString.String()); } } } return true; default: break; } return false; }
static NEOERR *split_and_convert (const char *src, int slen, STRING *out, HTML_CONVERT_OPTS *opts) { NEOERR *err = STATUS_OK; regmatch_t email_match, url_match; int errcode; char *ptr, *esc; char errbuf[256]; struct _parts *parts; int part_count; int part; int x, i; int spaces = 0; if (!CompiledRe) { #ifdef HAVE_PTHREADS /* In threaded environments, we have to mutex lock to do this regcomp, but * we don't want to use a mutex every time to check that it was regcomp. * So, we only lock if our first test of compiled was false */ err = mLock(&InitLock); if (err != STATUS_OK) return nerr_pass(err); if (CompiledRe == 0) { #endif if ((errcode = regcomp (&EmailRegex, EmailRe, REG_ICASE | REG_EXTENDED))) { regerror (errcode, &EmailRegex, errbuf, sizeof(errbuf)); err = nerr_raise (NERR_PARSE, "Unable to compile EmailRE: %s", errbuf); } if ((errcode = regcomp (&UrlRegex, URLRe, REG_ICASE | REG_EXTENDED))) { regerror (errcode, &UrlRegex, errbuf, sizeof(errbuf)); err = nerr_raise (NERR_PARSE, "Unable to compile URLRe: %s", errbuf); } CompiledRe = 1; #ifdef HAVE_PTHREADS } if (err) { mUnlock(&InitLock); return err; } err = mUnlock(&InitLock); if (err != STATUS_OK) return nerr_pass(err); #else if (err) { return err; } #endif } part_count = 20; parts = (struct _parts *) malloc (sizeof(struct _parts) * part_count); part = 0; x = 0; if (regexec (&EmailRegex, src+x, 1, &email_match, 0) != 0) { email_match.rm_so = -1; email_match.rm_eo = -1; } else { email_match.rm_so += x; email_match.rm_eo += x; } if (regexec (&UrlRegex, src+x, 1, &url_match, 0) != 0) { url_match.rm_so = -1; url_match.rm_eo = -1; } else { url_match.rm_so += x; url_match.rm_eo += x; } while ((x < slen) && !((email_match.rm_so == -1) && (url_match.rm_so == -1))) { if (part >= part_count) { void *new_ptr; part_count *= 2; new_ptr = realloc (parts, sizeof(struct _parts) * part_count); if (new_ptr == NULL) { free(parts); return nerr_raise (NERR_NOMEM, "Unable to increase url matcher to %d urls", part_count); } parts = (struct _parts *) new_ptr; } if ((url_match.rm_so != -1) && ((email_match.rm_so == -1) || (url_match.rm_so <= email_match.rm_so))) { parts[part].begin = url_match.rm_so; parts[part].end = url_match.rm_eo; parts[part].type = SC_TYPE_URL; x = parts[part].end + 1; part++; if (x < slen) { if (regexec (&UrlRegex, src+x, 1, &url_match, 0) != 0) { url_match.rm_so = -1; url_match.rm_eo = -1; } else { url_match.rm_so += x; url_match.rm_eo += x; } if ((email_match.rm_so != -1) && (x > email_match.rm_so)) { if (regexec (&EmailRegex, src+x, 1, &email_match, 0) != 0) { email_match.rm_so = -1; email_match.rm_eo = -1; } else { email_match.rm_so += x; email_match.rm_eo += x; } } } } else { parts[part].begin = email_match.rm_so; parts[part].end = email_match.rm_eo; parts[part].type = SC_TYPE_EMAIL; x = parts[part].end + 1; part++; if (x < slen) { if (regexec (&EmailRegex, src+x, 1, &email_match, 0) != 0) { email_match.rm_so = -1; email_match.rm_eo = -1; } else { email_match.rm_so += x; email_match.rm_eo += x; } if ((url_match.rm_so != -1) && (x > url_match.rm_so)) { if (regexec (&UrlRegex, src+x, 1, &url_match, 0) != 0) { url_match.rm_so = -1; url_match.rm_eo = -1; } else { url_match.rm_so += x; url_match.rm_eo += x; } } } } } i = 0; x = 0; while (x < slen) { if ((i >= part) || (x < parts[i].begin)) { ptr = strpbrk(src + x, "&<>\r\n "); if (ptr == NULL) { if (spaces) { int sp; for (sp = 0; sp < spaces - 1; sp++) { err = string_append (out, " "); if (err != STATUS_OK) break; } if (err != STATUS_OK) break; err = string_append_char (out, ' '); } spaces = 0; if (i < part) { err = string_appendn (out, src + x, parts[i].begin - x); x = parts[i].begin; } else { err = string_append (out, src + x); x = slen; } } else { if ((i >= part) || ((ptr - src) < parts[i].begin)) { if (spaces) { int sp; for (sp = 0; sp < spaces - 1; sp++) { err = string_append (out, " "); if (err != STATUS_OK) break; } if (err != STATUS_OK) break; err = string_append_char (out, ' '); } spaces = 0; err = string_appendn (out, src + x, (ptr - src) - x); if (err != STATUS_OK) break; x = ptr - src; if (src[x] == ' ') { if (opts->space_convert) { spaces++; } else err = string_append_char (out, ' '); } else { if (src[x] != '\n' && spaces) { int sp; for (sp = 0; sp < spaces - 1; sp++) { err = string_append (out, " "); if (err != STATUS_OK) break; } if (err != STATUS_OK) break; err = string_append_char (out, ' '); } spaces = 0; if (src[x] == '&') err = string_append (out, "&"); else if (src[x] == '<') err = string_append (out, "<"); else if (src[x] == '>') err = string_append (out, ">"); else if (src[x] == '\n') if (opts->newlines_convert) err = string_append (out, "<br/>\n"); else if (x && src[x-1] == '\n') err = string_append (out, "<p/>\n"); else err = string_append_char (out, '\n'); else if (src[x] != '\r') err = nerr_raise (NERR_ASSERT, "src[x] == '%c'", src[x]); } x++; } else { if (spaces) { int sp; for (sp = 0; sp < spaces - 1; sp++) { err = string_append (out, " "); if (err != STATUS_OK) break; } if (err != STATUS_OK) break; err = string_append_char (out, ' '); } spaces = 0; err = string_appendn (out, src + x, parts[i].begin - x); x = parts[i].begin; } } } else { if (spaces) { int sp; for (sp = 0; sp < spaces - 1; sp++) { err = string_append (out, " "); if (err != STATUS_OK) break; } if (err != STATUS_OK) break; err = string_append_char (out, ' '); } spaces = 0; if (parts[i].type == SC_TYPE_URL) { char last_char = src[parts[i].end-1]; int suffix=0; if (last_char == '.' || last_char == ',') { suffix=1; } err = string_append (out, " <a "); if (err != STATUS_OK) break; if (opts->url_class) { err = string_appendf (out, "class=%s ", opts->url_class); if (err) break; } if (opts->url_target) { err = string_appendf (out, "target=\"%s\" ", opts->url_target); if (err) break; } err = string_append(out, "href=\""); if (err) break; if (opts->bounce_url) { char *url, *esc_url, *new_url; int url_len; if (!strncasecmp(src + x, "www.", 4)) { url_len = 7 + parts[i].end - x - suffix; url = (char *) malloc(url_len+1); if (url == NULL) { err = nerr_raise(NERR_NOMEM, "Unable to allocate memory to convert url"); break; } strcpy(url, "http://"); strncat(url, src + x, parts[i].end - x - suffix); } else { url_len = parts[i].end - x - suffix; url = (char *) malloc(url_len+1); if (url == NULL) { err = nerr_raise(NERR_NOMEM, "Unable to allocate memory to convert url"); break; } strncpy(url, src + x, parts[i].end - x - suffix); url[url_len] = '\0'; } err = cgi_url_escape(url, &esc_url); free(url); if (err) { free(esc_url); break; } new_url = sprintf_alloc(opts->bounce_url, esc_url); free(esc_url); if (new_url == NULL) { err = nerr_raise(NERR_NOMEM, "Unable to allocate memory to convert url"); break; } err = string_append (out, new_url); free(new_url); if (err) break; } else { if (!strncasecmp(src + x, "www.", 4)) { err = string_append (out, "http://"); if (err != STATUS_OK) break; } err = string_appendn (out, src + x, parts[i].end - x - suffix); if (err != STATUS_OK) break; } err = string_append (out, "\">"); if (err != STATUS_OK) break; if (opts->link_name) { err = html_escape_alloc((opts->link_name), strlen(opts->link_name), &esc); } else { err = html_escape_alloc((src + x), parts[i].end - x - suffix, &esc); } if (err != STATUS_OK) break; err = string_append (out, esc); free(esc); if (err != STATUS_OK) break; err = string_append (out, "</a>"); if (suffix) { err = string_appendn(out,src + parts[i].end - 1,1); if (err != STATUS_OK) break; } } else /* type == SC_TYPE_EMAIL */ { err = string_append (out, "<a "); if (err != STATUS_OK) break; if (opts->mailto_class) { err = string_appendf (out, "class=%s ", opts->mailto_class); if (err) break; } err = string_append(out, "href=\"mailto:"); if (err) break; err = string_appendn (out, src + x, parts[i].end - x); if (err != STATUS_OK) break; err = string_append (out, "\">"); if (err != STATUS_OK) break; err = html_escape_alloc(src + x, parts[i].end - x, &esc); if (err != STATUS_OK) break; err = string_append (out, esc); free(esc); if (err != STATUS_OK) break; err = string_append (out, "</a>"); } x = parts[i].end; i++; } if (err != STATUS_OK) break; } free (parts); return err; }
af::Msg* threadProcessMsgCase( ThreadArgs * i_args, af::Msg * i_msg) { //i_msg->stdOut(); //printf("IM=%d LM=%d MM=%d\n", i_msg->getMagicNumber(), af::Msg::Magic, af::Environment::getMagicMode()); af::Msg * o_msg_response = NULL; switch( i_msg->type()) { case af::Msg::TVersionMismatch: { AFCommon::QueueLogError( i_msg->v_generateInfoString( false)); o_msg_response = new af::Msg( af::Msg::TVersionMismatch, 1); break; } case af::Msg::TMagicMismatch: { std::string err = "Magick number mismatch: recieved "; err += af::itos( i_msg->getMagicNumber()) + " != " + af::itos( af::Msg::Magic) += " local."; AFCommon::QueueLogError( err); o_msg_response = new af::Msg( af::Msg::TMagicMismatch, 1); break; } case af::Msg::TMagicNumber: { std::string msg = "Magick Number " + af::itos( af::Msg::Magic) + " changed to " + af::itos( i_msg->int32()); AFCommon::QueueLog( msg); o_msg_response = new af::Msg(); o_msg_response->setString( msg); af::Msg::Magic = i_msg->int32(); break; } case af::Msg::TInvalid: { AFCommon::QueueLogError( std::string("Invalid message recieved: ") + i_msg->v_generateInfoString( false)); break; } case af::Msg::TNULL: case af::Msg::TDATA: case af::Msg::TTESTDATA: case af::Msg::TStringList: { i_msg->stdOutData(); break; } case af::Msg::THTTP: case af::Msg::TJSON: { return threadProcessJSON( i_args, i_msg); } case af::Msg::TString: { std::string str = i_msg->getString(); if( str.empty()) break; AFCommon::QueueLog( str); AfContainerLock mLock( i_args->monitors, AfContainerLock::WRITELOCK); i_args->monitors->sendMessage( str); break; } case af::Msg::TStatRequest: { o_msg_response = new af::Msg; af::statwrite( o_msg_response); break; } case af::Msg::TConfirm: { printf("Thread process message: Msg::TConfirm: %d\n", i_msg->int32()); i_args->msgQueue->pushMsg( new af::Msg( af::Msg::TConfirm, 1)); o_msg_response = new af::Msg( af::Msg::TConfirm, 1 - i_msg->int32()); break; } case af::Msg::TConfigLoad: { AfContainerLock jlock( i_args->jobs, AfContainerLock::WRITELOCK); AfContainerLock rlock( i_args->renders, AfContainerLock::WRITELOCK); AfContainerLock tlock( i_args->talks, AfContainerLock::WRITELOCK); AfContainerLock ulock( i_args->users, AfContainerLock::WRITELOCK); printf("\n ========= RELOADING CONFIG =========\n\n"); std::string message; if( af::Environment::reload()) { message = "Reloaded successfully."; printf("\n ========= CONFIG RELOADED SUCCESSFULLY =========\n\n"); } else { message = "Failed, see server logs fo details."; printf("\n ========= CONFIG RELOADING FAILED =========\n\n"); } o_msg_response = new af::Msg(); o_msg_response->setString( message); break; } case af::Msg::TFarmLoad: { AfContainerLock mLock( i_args->monitors, AfContainerLock::WRITELOCK); AfContainerLock rlock( i_args->renders, AfContainerLock::WRITELOCK); printf("\n ========= RELOADING FARM =========\n\n"); std::string message; if( af::loadFarm( true)) { RenderContainerIt rendersIt( i_args->renders); for( RenderAf *render = rendersIt.render(); render != NULL; rendersIt.next(), render = rendersIt.render()) { render->getFarmHost(); i_args->monitors->addEvent( af::Msg::TMonitorRendersChanged, render->getId()); } message = "Reloaded successfully."; printf("\n ========= FARM RELOADED SUCCESSFULLY =========\n\n"); } else { message = "Failed, see server logs fo details. Check farm with \"afcmd fcheck\" at first."; printf("\n ========= FARM RELOADING FAILED =========\n\n"); } o_msg_response = new af::Msg(); o_msg_response->setString( message); break; } // ---------------------------------- Monitor ---------------------------------// case af::Msg::TMonitorRegister: { AfContainerLock lock( i_args->monitors, AfContainerLock::WRITELOCK); MonitorAf * newMonitor = new MonitorAf( i_msg); newMonitor->setAddressIP( i_msg->getAddress()); o_msg_response = i_args->monitors->addMonitor( newMonitor); break; } case af::Msg::TMonitorUpdateId: { AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK); if( i_args->monitors->updateId( i_msg->int32())) { o_msg_response = new af::Msg( af::Msg::TMonitorId, i_msg->int32()); } else { o_msg_response = new af::Msg( af::Msg::TMonitorId, 0); } break; } case af::Msg::TMonitorsListRequest: { AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK); o_msg_response = i_args->monitors->generateList( af::Msg::TMonitorsList); break; } case af::Msg::TMonitorsListRequestIds: { AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK); af::MCGeneral ids( i_msg); o_msg_response = i_args->monitors->generateList( af::Msg::TMonitorsList, ids); break; } case af::Msg::TMonitorLogRequestId: { AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK); MonitorContainerIt it( i_args->monitors); MonitorAf* node = it.getMonitor( i_msg->int32()); if( node == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = new af::Msg(); o_msg_response->setStringList( node->getLog()); break; } // ---------------------------------- Talk ---------------------------------// case af::Msg::TTalkRegister: { AfContainerLock mlock( i_args->monitors, AfContainerLock::WRITELOCK); AfContainerLock tlock( i_args->talks, AfContainerLock::WRITELOCK); TalkAf * newTalk = new TalkAf( i_msg); newTalk->setAddressIP( i_msg->getAddress()); o_msg_response = i_args->talks->addTalk( newTalk, i_args->monitors); break; } case af::Msg::TTalksListRequest: { AfContainerLock lock( i_args->talks, AfContainerLock::READLOCK); o_msg_response = i_args->talks->generateList( af::Msg::TTalksList); break; } case af::Msg::TTalksListRequestIds: { AfContainerLock lock( i_args->talks, AfContainerLock::READLOCK); af::MCGeneral ids( i_msg); o_msg_response = i_args->talks->generateList( af::Msg::TTalksList, ids); break; } case af::Msg::TTalkUpdateId: { AfContainerLock lock( i_args->talks, AfContainerLock::READLOCK); if( i_args->talks->updateId( i_msg->int32())) { o_msg_response = i_args->talks->generateList( af::Msg::TTalksList); } else { o_msg_response = new af::Msg( af::Msg::TTalkId, 0); } break; } case af::Msg::TTalkDistributeData: { AfContainerLock lock( i_args->talks, AfContainerLock::READLOCK); i_args->talks->distributeData( i_msg); break; } // ---------------------------------- Render -------------------------------// case af::Msg::TRenderRegister: { //printf("case af::Msg::TRenderRegister:\n"); AfContainerLock mLock( i_args->monitors, AfContainerLock::WRITELOCK); AfContainerLock rLock( i_args->renders, AfContainerLock::WRITELOCK); RenderAf * newRender = new RenderAf( i_msg); newRender->setAddressIP( i_msg->getAddress()); o_msg_response = i_args->renders->addRender( newRender, i_args->monitors); break; } case af::Msg::TRenderUpdate: { //printf("case af::Msg::TRenderUpdate:\n"); AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK); af::Render render_up( i_msg); //printf("Msg::TRenderUpdate: %s - %s\n", render_up.getName().toUtf8().data(), time2Qstr( time(NULL)).toUtf8().data()); RenderContainerIt rendersIt( i_args->renders); RenderAf* render = rendersIt.getRender( render_up.getId()); int id = 0; // If there is not such render, a zero id will be send. // It is a signal for client to register again (may be server was restarted). if((render != NULL) && ( render->update( &render_up))) { id = render->getId(); } o_msg_response = new af::Msg( af::Msg::TRenderId, id); break; } case af::Msg::TRendersListRequest: { AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK); o_msg_response = i_args->renders->generateList( af::Msg::TRendersList); break; } case af::Msg::TRendersListRequestIds: { AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK); af::MCGeneral ids( i_msg); o_msg_response = i_args->renders->generateList( af::Msg::TRendersList, ids); break; } case af::Msg::TRendersResourcesRequestIds: { AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK); af::MCGeneral ids( i_msg); o_msg_response = i_args->renders->generateList( af::Msg::TRendersResources, ids); break; } case af::Msg::TRenderLogRequestId: { AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK); RenderContainerIt rendersIt( i_args->renders); RenderAf* render = rendersIt.getRender( i_msg->int32()); if( render == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = new af::Msg; o_msg_response->setStringList( render->getLog()); break; } case af::Msg::TRenderTasksLogRequestId: { AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK); RenderContainerIt rendersIt( i_args->renders); RenderAf* render = rendersIt.getRender( i_msg->int32()); if( render == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = new af::Msg; if( render->getTasksLog().empty()) { o_msg_response->setString("No tasks execution log."); } else { o_msg_response->setStringList( render->getTasksLog()); } break; } case af::Msg::TRenderInfoRequestId: { AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK); RenderContainerIt rendersIt( i_args->renders); RenderAf* render = rendersIt.getRender( i_msg->int32()); if( render == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = render->writeFullInfo(); break; } // ---------------------------------- Users -------------------------------// case af::Msg::TUserIdRequest: { AfContainerLock lock( i_args->users, AfContainerLock::READLOCK); af::MsgClassUserHost usr( i_msg); std::string name = usr.getUserName(); int id = 0; UserContainerIt usersIt( i_args->users); for( af::User *user = usersIt.user(); user != NULL; usersIt.next(), user = usersIt.user()) { if( user->getName() == name) { id = user->getId(); } } o_msg_response = new af::Msg( af::Msg::TUserId, id); break; } case af::Msg::TUsersListRequest: { AfContainerLock lock( i_args->users, AfContainerLock::READLOCK); o_msg_response = i_args->users->generateList( af::Msg::TUsersList); break; } case af::Msg::TUsersListRequestIds: { AfContainerLock lock( i_args->users, AfContainerLock::READLOCK); af::MCGeneral ids( i_msg); o_msg_response = i_args->users->generateList( af::Msg::TUsersList, ids); break; } case af::Msg::TUserLogRequestId: { AfContainerLock lock( i_args->users, AfContainerLock::READLOCK); UserContainerIt usersIt( i_args->users); UserAf* user = usersIt.getUser( i_msg->int32()); if( user == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = new af::Msg(); o_msg_response->setStringList( user->getLog()); break; } case af::Msg::TUserJobsOrderRequestId: { AfContainerLock lock( i_args->users, AfContainerLock::READLOCK); UserContainerIt usersIt( i_args->users); UserAf* user = usersIt.getUser( i_msg->int32()); if( user == NULL ) { // FIXME: Better to return some message in any case. break; } af::MCGeneral ids; ids.setId( user->getId()); ids.setList( user->generateJobsIds()); o_msg_response = new af::Msg( af::Msg::TUserJobsOrder, &ids); break; } // ------------------------------------- Job -------------------------------// case af::Msg::TJobRequestId: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); JobContainerIt jobsIt( i_args->jobs); JobAf* job = jobsIt.getJob( i_msg->int32()); if( job == NULL ) { o_msg_response = new af::Msg( af::Msg::TJobRequestId, 0); break; } o_msg_response = new af::Msg( af::Msg::TJob, job); break; } case af::Msg::TJobLogRequestId: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); JobContainerIt jobsIt( i_args->jobs); JobAf* job = jobsIt.getJob( i_msg->int32()); if( job == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = new af::Msg(); o_msg_response->setStringList( job->getLog()); break; } case af::Msg::TJobErrorHostsRequestId: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); JobContainerIt jobsIt( i_args->jobs); JobAf* job = jobsIt.getJob( i_msg->int32()); if( job == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = new af::Msg(); o_msg_response->setString( job->v_getErrorHostsListString()); break; } case af::Msg::TJobProgressRequestId: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); JobContainerIt jobsIt( i_args->jobs); JobAf* job = jobsIt.getJob( i_msg->int32()); if( job == NULL ) { // FIXME: Send back the same message on error - is it good? o_msg_response = new af::Msg( af::Msg::TJobProgressRequestId, 0); break; } o_msg_response = new af::Msg; job->writeProgress( *o_msg_response); break; } case af::Msg::TJobsListRequest: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); o_msg_response = i_args->jobs->generateList( af::Msg::TJobsList); break; } case af::Msg::TJobsListRequestIds: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); af::MCGeneral ids( i_msg); o_msg_response = i_args->jobs->generateList( af::Msg::TJobsList, ids); break; } case af::Msg::TJobsListRequestUserId: { AfContainerLock jLock( i_args->jobs, AfContainerLock::READLOCK); AfContainerLock uLock( i_args->users, AfContainerLock::READLOCK); o_msg_response = i_args->users->generateJobsList( i_msg->int32()); if( o_msg_response == NULL ) { o_msg_response = new af::Msg( af::Msg::TUserId, 0); } break; } case af::Msg::TJobsListRequestUsersIds: { AfContainerLock jLock( i_args->jobs, AfContainerLock::READLOCK); AfContainerLock uLock( i_args->users, AfContainerLock::READLOCK); af::MCGeneral mcids( i_msg); std::string type_name; o_msg_response = i_args->users->generateJobsList( mcids.getList(), type_name); break; } case af::Msg::TTaskRequest: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); af::MCTaskPos mctaskpos( i_msg); JobContainerIt jobsIt( i_args->jobs); JobAf* job = jobsIt.getJob( mctaskpos.getJobId()); if( job == NULL ) { o_msg_response = new af::Msg(); std::ostringstream stream; stream << "Msg::TTaskRequest: No job with id=" << mctaskpos.getJobId(); o_msg_response->setString( stream.str()); break; } af::TaskExec * task = job->generateTask( mctaskpos.getNumBlock(), mctaskpos.getNumTask()); if( task ) { o_msg_response = new af::Msg( af::Msg::TTask, task); delete task; } else { o_msg_response = new af::Msg(); std::ostringstream stream; stream << "Msg::TTaskRequest: No such task[" << mctaskpos.getJobId() << "][" << mctaskpos.getNumBlock() << "][" << mctaskpos.getNumTask() << "]"; o_msg_response->setString( stream.str()); } break; } case af::Msg::TTaskLogRequest: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); af::MCTaskPos mctaskpos( i_msg); JobContainerIt jobsIt( i_args->jobs); JobAf* job = jobsIt.getJob( mctaskpos.getJobId()); if( job == NULL ) { o_msg_response = new af::Msg(); std::ostringstream stream; stream << "Msg::TTaskLogRequest: No job with id=" << mctaskpos.getJobId(); o_msg_response->setString( stream.str()); break; } const std::list<std::string> * list = &(job->getTaskLog( mctaskpos.getNumBlock(), mctaskpos.getNumTask())); if( list == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = new af::Msg(); if( list->size() == 0) { std::list<std::string> list; list.push_back("Task log is empty."); o_msg_response->setStringList( list); } else { o_msg_response->setStringList( *list); } break; } case af::Msg::TTaskErrorHostsRequest: { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); af::MCTaskPos mctaskpos( i_msg); JobContainerIt jobsIt( i_args->jobs); JobAf* job = jobsIt.getJob( mctaskpos.getJobId()); if( job == NULL ) { // FIXME: Better to return some message in any case. break; } o_msg_response = new af::Msg(); o_msg_response->setString( job->v_getErrorHostsListString( mctaskpos.getNumBlock(), mctaskpos.getNumTask())); break; } case af::Msg::TTaskOutputRequest: { af::Msg * msg_request_render = NULL; std::string filename, error; af::MCTaskPos tp( i_msg); //printf("ThreadReadMsg::msgCase: case af::Msg::TJobTaskOutputRequest: job=%d, block=%d, task=%d, number=%d\n", tp.getJobId(), tp.getNumBlock(), tp.getNumTask(), tp.getNumber()); { AfContainerLock jLock( i_args->jobs, AfContainerLock::READLOCK); AfContainerLock rLock( i_args->renders, AfContainerLock::READLOCK); JobContainerIt jobsIt( i_args->jobs); JobAf* job = jobsIt.getJob( tp.getJobId()); if( job == NULL ) { o_msg_response = af::msgString("Error: Job is NULL."); AFCommon::QueueLogError("Jobs is NULL"); break; } // Trying to set message to request output from running remote host. msg_request_render = job->v_getTaskStdOut( tp.getNumBlock(), tp.getNumTask(), tp.getNumber(), i_args->renders, filename, error); if( error.size()) { if( msg_request_render ) delete msg_request_render; o_msg_response = af::msgString( error); AFCommon::QueueLogError( error); break; } } if( filename.size()) { // // Retrieving output from file // int readsize = -1; char * data = af::fileRead( filename, readsize, af::Msg::SizeDataMax, &error); if( data ) { o_msg_response = new af::Msg(); o_msg_response->setData( readsize, data); delete [] data; } else if( error.size()) { error = std::string("Getting task output: ") + error; AFCommon::QueueLogError( error); o_msg_response = af::msgString( error); } } else if( msg_request_render) { // // Retrieving output from render // msg_request_render->setReceiving(); bool ok; o_msg_response = af::msgsend( msg_request_render, ok, af::VerboseOn); if( o_msg_response == NULL ) { error = "Retrieving output from render failed. See server logs for details."; o_msg_response = af::msgString( error); AFCommon::QueueLogError( error); } delete msg_request_render; } else { if( error.size()) { o_msg_response = af::msgString( error); AFCommon::QueueLogError("TTaskOutputRequest: Neiter message nor filename\n" + error); } else AFCommon::QueueLogError("TTaskOutputRequest: Neiter message nor filename."); } break; } case af::Msg::TJobsWeightRequest: { AfContainerLock jLock( i_args->jobs, AfContainerLock::READLOCK); af::MCJobsWeight jobsWeight; i_args->jobs->getWeight( jobsWeight); o_msg_response = new af::Msg( af::Msg::TJobsWeight, &jobsWeight); break; } // Cases for run cycle thread: case af::Msg::TTaskUpdateState: { af::MCTaskUp taskup( i_msg); af::MCTaskPos taskpos( taskup.getNumJob(), taskup.getNumBlock(), taskup.getNumTask(), taskup.getNumber()); o_msg_response = new af::Msg( af::Msg::TRenderCloseTask, &taskpos); } case af::Msg::TTaskUpdatePercent: case af::Msg::TTaskListenOutput: case af::Msg::TRenderDeregister: case af::Msg::TTalkDeregister: /* { // Check magic number mismatch mode: // All message types above are not allowed in "GetOnly" mode. if( i_msg->isMagicInvalid() && ( af::Environment::getMagicMode() <= af::MMM_GetOnly )) { std::string err = "Magic Mismatch Mode: \""; err += af::Environment::getMagicModeName(); err += "\""; err += "\nMessage type not allowed: \""; err += af::Msg::TNAMES[i_msg->type()]; err += "\""; AFCommon::QueueLogError( err); delete i_msg; return o_msg_response; } // Only Monitor message types are allowed in "GetOnly" mode. }*/ case af::Msg::TMonitorSubscribe: case af::Msg::TMonitorUnsubscribe: case af::Msg::TMonitorDeregister: case af::Msg::TMonitorUsersJobs: case af::Msg::TMonitorJobsIdsAdd: case af::Msg::TMonitorJobsIdsSet: case af::Msg::TMonitorJobsIdsDel: case af::Msg::TMonitorMessage: { // Push message for run cycle thread. i_args->msgQueue->pushMsg( i_msg); // Need to return here to not to delete input message (i_msg) later. return o_msg_response; // ( o_msg_response is NULL in all cases except Msg::TTaskUpdateState, // in that case render should recieve an answer to close task // and finish sending any updates for the task ) } // -------------------------------------------------------------------------// default: { AFCommon::QueueLogError( std::string("Unknown message recieved: ") + i_msg->v_generateInfoString( false)); break; } } // Deleting input message as it not needed any more. delete i_msg; // Returning an answer return o_msg_response; }
bool JobContainer::registerJob( JobAf *job, std::string & o_err, UserContainer *users, MonitorContainer * monitoring) { if( job == NULL ) { AF_ERR << "JobContainer::registerJob: Can't allocate memory for a new job."; return false; } if( users == NULL ) { AF_ERR << "JobContainer::registerJob: Users container is not set."; delete job; return false; } // Job from store is already checked for validness if(( job->isFromStore() == false ) && (job->isValidConstructed() == false )) { o_err = "Invalid job."; delete job; return false; } UserAf *user; { // Register new user if job has a new user name. AfContainerLock jLock( this, AfContainerLock::WRITELOCK); AfContainerLock uLock( users, AfContainerLock::WRITELOCK ); if( monitoring) AfContainerLock mLock( monitoring, AfContainerLock::WRITELOCK ); AF_DEBUG << "JobContainer::registerJob: Checking job user: "******"JobContainer::registerJob: Can't register new user."; return false; } // Add job node to container. if( add( job) == false ) { delete job; o_err = "JobContainer::registerJob: Can't add job to container."; return false; } AF_DEBUG << "JobContainer::registerJob: locking job."; job->lock(); AF_DEBUG << "JobContainer::registerJob: locking user."; user->lock(); user->addJob( job); if( monitoring ) { AF_DEBUG << "JobContainer::registerJob: monitor new job events."; monitoring->addJobEvent( af::Monitor::EVT_jobs_add, job->getId(), user->getId()); monitoring->addEvent( af::Monitor::EVT_users_change, user->getId()); } } // initialize job ( create tasks output root_dir, execute "pre"commands if any) AF_DEBUG << "JobContainer::registerJob: initiaizing new job with user."; if( job->initialize() == false) { AF_DEBUG << "JobContainer::registerJob: Job initialization failed."; if( monitoring ) { AfContainerLock mLock( monitoring, AfContainerLock::WRITELOCK ); monitoring->addJobEvent( af::Monitor::EVT_jobs_del, job->getId(), user->getId()); monitoring->addEvent( af::Monitor::EVT_users_change, user->getId()); } { // Set job to zombie: AfContainerLock jLock( this, AfContainerLock::WRITELOCK); AfContainerLock uLock( users, AfContainerLock::WRITELOCK); user->unLock(); job->deleteNode( NULL, NULL); } return false; } if( monitoring ) { AfContainerLock mLock( monitoring, AfContainerLock::WRITELOCK ); AF_DEBUG << "JobContainer::registerJob: monitor unlock job and user events."; monitoring->addJobEvent( af::Monitor::EVT_jobs_change, job->getId(), user->getId()); monitoring->addEvent( af::Monitor::EVT_users_change, user->getId()); } AF_DEBUG << "JobContainer::registerJob: unlocking user and job."; { AfContainerLock jLock( this, AfContainerLock::WRITELOCK); AfContainerLock uLock( users, AfContainerLock::WRITELOCK); user->unLock(); job->unLock(); } AFCommon::QueueLog("Job registered: " + job->v_generateInfoString()); return true; }
//************************************************************ //********功能:清空一个工作队列 //********参数:无 //********返回值: //************************************************************ void CJobQueue::clear() { CLock mLock(m_mutex); while (!m_JobQueue.empty()) m_JobQueue.pop(); }
af::Msg * threadProcessJSON( ThreadArgs * i_args, af::Msg * i_msg) { rapidjson::Document document; std::string error; char * data = af::jsonParseMsg( document, i_msg, &error); if( data == NULL ) { AFCommon::QueueLogError( error); delete i_msg; return NULL; } af::Msg * o_msg_response = NULL; JSON & getObj = document["get"]; if( getObj.IsObject()) { std::string type, mode; bool binary = false; af::jr_string("type", type, getObj); af::jr_string("mode", mode, getObj); af::jr_bool("binary", binary, getObj); bool json = true; if( binary ) json = false; bool full = false; if( mode == "full") full = true; std::vector<int32_t> ids; af::jr_int32vec("ids", ids, getObj); std::string mask; af::jr_string("mask", mask, getObj); if( type == "jobs" ) { if( getObj.HasMember("uids")) { std::vector<int32_t> uids; af::jr_int32vec("uids", uids, getObj); if( uids.size()) { AfContainerLock jLock( i_args->jobs, AfContainerLock::READLOCK); AfContainerLock uLock( i_args->users, AfContainerLock::READLOCK); o_msg_response = i_args->users->generateJobsList( uids, type, json); } } if( getObj.HasMember("users")) { std::vector<std::string> users; af::jr_stringvec("users", users, getObj); if( users.size()) { AfContainerLock jLock( i_args->jobs, AfContainerLock::READLOCK); AfContainerLock uLock( i_args->users, AfContainerLock::READLOCK); o_msg_response = i_args->users->generateJobsList( users, type, json); } } else if( mode == "output") { std::vector<int32_t> block_ids; std::vector<int32_t> task_ids; int number = 0; af::jr_int32vec("block_ids", block_ids, getObj); af::jr_int32vec("task_ids", task_ids, getObj); af::jr_int("number", number, getObj); if(( ids.size() == 1 ) && ( block_ids.size() == 1 ) && ( task_ids.size() == 1 )) { af::Msg * msg_request_render = NULL; std::string filename, error, name; // Get output from job, it can return a request message for render or a filename { AfContainerLock jlock( i_args->jobs, AfContainerLock::READLOCK); AfContainerLock rLock( i_args->renders, AfContainerLock::READLOCK); JobContainerIt it( i_args->jobs); JobAf * job = it.getJob( ids[0]); if( job == NULL ) o_msg_response = af::jsonMsgError("Invalid ID"); else { msg_request_render = job->v_getTaskStdOut( block_ids[0], task_ids[0], number, i_args->renders, filename, error); name = job->generateTaskName( block_ids[0], task_ids[0]); if( number > 0 ) name += "["+af::itos(number)+"]"; } } if( filename.size()) // Reading output from file { int readsize = -1; char * data = af::fileRead( filename, &readsize, af::Msg::SizeDataMax, &error); if( data ) { o_msg_response = af::jsonMsg( mode, name, data, readsize); delete [] data; } } else if( msg_request_render) // Retrieving output from render { msg_request_render->setReceiving(); bool ok; af::Msg * response = af::msgsend( msg_request_render, ok, af::VerboseOn); if( response ) { o_msg_response = af::jsonMsg( mode, name, response->data(), response->dataLen()); delete response; } else error = "Retrieving output from render failed. See server logs for details."; delete msg_request_render; } if( error.size()) { if( o_msg_response == NULL ) o_msg_response = af::jsonMsgError( error); AFCommon::QueueLogError("TTaskOutputRequest: " + error); } } } else { AfContainerLock lock( i_args->jobs, AfContainerLock::READLOCK); JobAf * job = NULL; bool was_error = false; if( ids.size() == 1 ) { JobContainerIt it( i_args->jobs); job = it.getJob( ids[0]); if( job == NULL ) o_msg_response = af::jsonMsgError( "Invalid ID"); } if( job ) { std::vector<int32_t> block_ids; af::jr_int32vec("block_ids", block_ids, getObj); if( block_ids.size() && ( block_ids[0] != -1 )) { std::vector<int32_t> task_ids; af::jr_int32vec("task_ids", task_ids, getObj); if( task_ids.size() && ( task_ids[0] != -1)) o_msg_response = job->writeTask( block_ids[0], task_ids[0], mode, binary); else { std::vector<std::string> modes; af::jr_stringvec("mode", modes, getObj); o_msg_response = job->writeBlocks( block_ids, modes); } } else if( mode.size()) { if( mode == "thumbnail" ) o_msg_response = job->writeThumbnail( binary); else if( mode == "progress" ) o_msg_response = job->writeProgress( json); else if( mode == "error_hosts" ) o_msg_response = job->writeErrorHosts(); else if( mode == "log" ) o_msg_response = job->writeLog(); } } if( o_msg_response == NULL ) o_msg_response = i_args->jobs->generateList( full ? af::Msg::TJob : af::Msg::TJobsList, type, ids, mask, json); } } else if( type == "renders") { AfContainerLock lock( i_args->renders, AfContainerLock::READLOCK); if( mode.size()) { RenderAf * render = NULL; if( ids.size() == 1 ) { RenderContainerIt it( i_args->renders); render = it.getRender( ids[0]); if( render == NULL ) o_msg_response = af::jsonMsgError( "Invalid ID"); } if( render ) { if( full ) o_msg_response = render->jsonWriteSrvFarm(); else if( mode == "log" ) o_msg_response = render->writeLog(); else if( mode == "tasks_log" ) o_msg_response = af::jsonMsg("tasks_log", render->getName(), render->getTasksLog()); } } if( o_msg_response == NULL ) { if( mode == "resources" ) o_msg_response = i_args->renders->generateList( af::Msg::TRendersResources, type, ids, mask, json); else o_msg_response = i_args->renders->generateList( af::Msg::TRendersList, type, ids, mask, json); } } else if( type == "users") { AfContainerLock lock( i_args->users, AfContainerLock::READLOCK); if( mode.size()) { UserAf * user = NULL; if( ids.size() == 1 ) { UserContainerIt it( i_args->users); user = it.getUser( ids[0]); if( user == NULL ) o_msg_response = af::jsonMsgError( "Invalid ID"); } if( user ) { if( mode == "jobs_order" ) o_msg_response = user->writeJobdsOrder(); else if( mode == "log" ) o_msg_response = user->writeLog(); } } if( o_msg_response == NULL ) o_msg_response = i_args->users->generateList( af::Msg::TUsersList, type, ids, mask, json); } else if( type == "monitors") { AfContainerLock lock( i_args->monitors, AfContainerLock::READLOCK); if( mode == "events") { MonitorContainerIt it( i_args->monitors); if( ids.size() ) { MonitorAf* node = it.getMonitor( ids[0]); if( node != NULL ) { o_msg_response = node->getEvents(); } else { o_msg_response = af::jsonMsg("{\"monitor\":{\"id\":0}}"); } } else { o_msg_response = af::jsonMsgError("id is not specified"); } } else o_msg_response = i_args->monitors->generateList( af::Msg::TMonitorsList, type, ids, mask, json); } else if( type == "files") { std::string path; std::ostringstream files; af::jr_string("path", path, getObj); std::vector<std::string> list = af::getFilesListSafe( path); files << "{\"path\":\"" << path << "\",\n"; files << "\"files\":["; for( int i = 0; i < list.size(); i++) { if( i ) files << ','; files << '"' << list[i] << '"'; } files << "]}"; o_msg_response = af::jsonMsg( files); } else if( type == "config" ) { o_msg_response = af::jsonMsg( af::Environment::getConfigData()); } } else if( document.HasMember("action")) { i_args->msgQueue->pushMsg( i_msg); // To not to detele it, set to NULL, as it pushed to another queue i_msg = NULL; } else if( document.HasMember("job")) { if( af::Environment::isDemoMode() ) { AFCommon::QueueLogError("Job registration is not allowed: Server demo mode."); } else { // No containers locks needed here. // Job registration is a complex procedure. // It locks and unlocks needed containers itself. i_args->jobs->job_register( new JobAf( document["job"]), i_args->users, i_args->monitors); } } else if( document.HasMember("monitor")) { AfContainerLock mlock( i_args->monitors, AfContainerLock::WRITELOCK); AfContainerLock ulock( i_args->users, AfContainerLock::READLOCK); MonitorAf * newMonitor = new MonitorAf( document["monitor"], i_args->users); newMonitor->setAddressIP( i_msg->getAddress()); o_msg_response = i_args->monitors->addMonitor( newMonitor, /*JSON = */ true); } else if( document.HasMember("user")) { AfContainerLock ulock( i_args->users, AfContainerLock::WRITELOCK); o_msg_response = i_args->users->addUser( new UserAf( document["user"]), i_args->monitors); } else if( document.HasMember("reload_farm")) { AfContainerLock mLock( i_args->monitors, AfContainerLock::WRITELOCK); AfContainerLock rlock( i_args->renders, AfContainerLock::WRITELOCK); printf("\n ========= RELOADING FARM =========\n\n"); if( af::loadFarm( true)) { RenderContainerIt rendersIt( i_args->renders); for( RenderAf *render = rendersIt.render(); render != NULL; rendersIt.next(), render = rendersIt.render()) { render->getFarmHost(); i_args->monitors->addEvent( af::Msg::TMonitorRendersChanged, render->getId()); } printf("\n ========= FARM RELOADED SUCCESSFULLY =========\n\n"); o_msg_response = af::jsonMsgStatus( true, "reload_farm", "Reloaded successfully."); } else { printf("\n ========= FARM RELOADING FAILED =========\n\n"); o_msg_response = af::jsonMsgStatus( false, "reload_farm", "Failed, see server logs fo details. Check farm with \"afcmd fcheck\" at first."); } } else if( document.HasMember("reload_config")) { AfContainerLock jlock( i_args->jobs, AfContainerLock::WRITELOCK); AfContainerLock rlock( i_args->renders, AfContainerLock::WRITELOCK); AfContainerLock ulock( i_args->users, AfContainerLock::WRITELOCK); printf("\n ========= RELOADING CONFIG =========\n\n"); std::string message; if( af::Environment::reload()) { printf("\n ========= CONFIG RELOADED SUCCESSFULLY =========\n\n"); o_msg_response = af::jsonMsgStatus( true, "reload_config", "Reloaded successfully."); } else { printf("\n ========= CONFIG RELOADING FAILED =========\n\n"); o_msg_response = af::jsonMsgStatus( false, "reload_config", "Failed, see server logs fo details."); } } delete [] data; if( i_msg ) delete i_msg; return o_msg_response; }