Example #1
0
ExternalEventSource*
LaunchDaemon::_FindEvent(const char* owner, const char* name) const
{
	if (name == NULL)
		return NULL;

	BString eventName = name;
	eventName.ToLower();

	EventMap::const_iterator found = fEvents.find(eventName);
	if (found != fEvents.end())
		return found->second;

	if (owner == NULL)
		return NULL;

	eventName.Prepend("/");
	eventName.Prepend(get_leaf(owner));

	found = fEvents.find(eventName);
	if (found != fEvents.end())
		return found->second;

	return NULL;
}
Example #2
0
void
LaunchDaemon::_AddJob(Target* target, bool service, BMessage& message)
{
	BString name = message.GetString("name");
	if (name.IsEmpty()) {
		// Invalid job description
		return;
	}
	name.ToLower();

	Job* job = FindJob(name);
	if (job == NULL) {
		job = new (std::nothrow) Job(name);
		if (job == NULL)
			return;

		job->SetService(service);
		job->SetCreateDefaultPort(service);
		job->SetTarget(target);
	}

	if (message.HasBool("disabled"))
		job->SetEnabled(!message.GetBool("disabled", !job->IsEnabled()));

	if (message.HasBool("legacy"))
		job->SetCreateDefaultPort(!message.GetBool("legacy", !service));

	_SetCondition(job, message);
	_SetEvent(job, message);
	_SetEnvironment(job, message);

	BMessage portMessage;
	for (int32 index = 0;
			message.FindMessage("port", index, &portMessage) == B_OK; index++) {
		job->AddPort(portMessage);
	}

	if (message.HasString("launch")) {
		job->Arguments().MakeEmpty();

		const char* argument;
		for (int32 index = 0; message.FindString("launch", index, &argument)
				== B_OK; index++) {
			job->AddArgument(argument);
		}
	}

	const char* requirement;
	for (int32 index = 0;
			message.FindString("requires", index, &requirement) == B_OK;
			index++) {
		job->AddRequirement(requirement);
	}
	if (fInitTarget != NULL)
		job->AddRequirement(fInitTarget->Name());

	fJobs.insert(std::make_pair(job->Title(), job));
}
Example #3
0
BString AIMProtocol::NormalizeNick(const char *nick) {
	BString normal = nick;
	
	normal.ReplaceAll(" ", "");
	normal.ToLower();
	
	map<string,BString>::iterator i = fNickMap.find(normal.String());
	
	if ( i == fNickMap.end() ) {
		// add 'real' nick if it's not already there
		LOG(fManager->Protocol(), liDebug, "Adding normal (%s) vs screen (%s)", normal.String(), nick );
		fNickMap[string(normal.String())] = BString(nick);
	}
	
	LOG(fManager->Protocol(), liDebug, "Screen (%s) to normal (%s)", nick, normal.String() );
	
	return normal;
};
Example #4
0
// ----------------------------------------------------------------------- RHTML_text_view - UpdateParamMenu -
void RHTMLtextview::UpdateParamMenu()
{
	BString tag = "";
	std::vector<Params> params;
	if (TextLength() > 0)
	{
		int32 c, d;
		GetSelection(&c, &d);
		int32 kezd, veg;

		BString text(Text());

		if ((kezd = text.FindLast("<",c)) > -1 || text[0] == '<')
		{
			if (kezd == -1)
				kezd = 0;
			if ((veg = text.FindFirst(">",c)) > -1)
				if ((veg < text.FindFirst("<",c)) || (text.FindFirst("<",c) == -1))
				{
					if ((veg > text.FindFirst(" ",kezd+1)) && (text.FindFirst(" ",kezd+1) > -1))
						veg = text.FindFirst(" ", kezd);
					text.CopyInto(tag, kezd + 1, veg - kezd - 1);
					veg = text.FindFirst(">",c);
					params.clear();

					while (text[kezd]!=' ' && kezd < veg )
						kezd++;
					kezd++;
					int32 i = kezd;
					while (i < veg)
					{
						if (text[i] == ' ')
						{
							struct Params tmp;
							text.CopyInto(tmp.name, kezd, i - kezd);
							tmp.name.ToLower();
							if (tmp.name != " " && tmp.name != "")
							{
								params.push_back(tmp);
							}
							kezd = i + 1;
						}

						if (text[i] == '=')
						{
							struct Params tmp;
							text.CopyInto(tmp.name, kezd, i - kezd);
							tmp.name.ToLower();
							if (text[i + 1] == '"')
							{
								if ((kezd = text.FindFirst('"', i + 2) + 1) > 0)
								{
									text.CopyInto(tmp.value, i + 2, kezd - i - 3);
									params.push_back(tmp);
									i = kezd - 1;
								} else
								{
									i++;
									break;
								}
							}
							else
							{
								if ((kezd = text.FindFirst(' ', i + 1 ) + 1) > 0)
								{
									text.CopyInto(tmp.value, i + 1, kezd - i - 2);
									i = text.FindFirst(' ', i + 1 );
									params.push_back(tmp);
								} else
								{
									i++;
									break;
								}
							}
						}
						i++;
					}
				}
		}
		tag.ToLower();
	}
	fTarget->fParamMenu->fParamList->SetTagParams(tag,params);
}
Example #5
0
// ------------------------------------------------------------------------------- RHTML_text_view - KeyDown -
void RHTMLtextview::KeyDown(const char *bytes, int32 numBytes)
{
	pushmenu = false;
	int32 c,d;
	GetSelection(&c, &d);
	BString *oldtext = new BString(Text());
	BString *newtext = 0;
	switch(bytes[0])
	{
		case B_ESCAPE:			// - ESC
		{
		}
		break;
		case B_ENTER:				// - ENTER
		{
			fTarget->SetModify(true);
			BString tmp = "";
			if (d - OffsetAt(CurrentLine()) > 0)
			{
				for (int i = OffsetAt(CurrentLine()); i < d; i++)
				{
					if (Text()[i] == B_SPACE || Text()[i] == B_TAB)
					{
						tmp << Text()[i];
					} else
						break;
				}
			}
			BTextView::KeyDown(bytes, numBytes);
			Insert(tmp.String());

			fFileTypes->SetFontAndColor(oldtext, newtext = new BString(Text()), 0, c);
   
			if (fUpdateTimer->IsActive())
				fUpdateTimer->ResetTimer();
			else
				fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
   
			if (PointAt(TextLength() - 1).y + 50 > fTarget->fNumView->Bounds().bottom) fTarget->fNumView->ResizeTo(fTarget->fNumView->Bounds().right, PointAt(TextLength() - 1).y + 50);
		}
		break;
		case '>':					// - >
		{
			fTagMenu->Stop();
   fTarget->SetModify(true);
   BTextView::KeyDown(bytes,numBytes);
   fFileTypes->SetFontAndColor(oldtext, newtext = new BString(Text()),0,c);

   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);

   if (PointAt(TextLength()-1).y+50>fTarget->fNumView->Bounds().bottom) fTarget->fNumView->ResizeTo(fTarget->fNumView->Bounds().right,PointAt(TextLength()-1).y+50);
  }
  break;
  case '<':					// - <
  {
   BTextView::KeyDown(bytes,numBytes);
   fTarget->SetModify(true);
   pushmenu=true;
   ScrollToSelection();
   fFileTypes->SetFontAndColor(oldtext, newtext = new BString(Text()),0,c);

   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);

   if (PointAt(TextLength()-1).y+50>fTarget->fNumView->Bounds().bottom) fTarget->fNumView->ResizeTo(fTarget->fNumView->Bounds().right,PointAt(TextLength()-1).y+50);
   mode=1;
   fTimer->StartTimer(fOptions->ReakcioIdoTM);
  }
  break;
  case B_SPACE:				// - SPACE
  {
   fTarget->SetModify(true);
   BTextView::KeyDown(bytes,numBytes);
   fFileTypes->SetFontAndColor(oldtext, newtext = new BString(Text()),0,c);

   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);

   if (PointAt(TextLength()-1).y+50>fTarget->fNumView->Bounds().bottom) fTarget->fNumView->ResizeTo(fTarget->fNumView->Bounds().right,PointAt(TextLength()-1).y+50);
   buf1 = "";
   int32 o;
   
   for (int i=c;i>=0;i--)
   {
    if (Text()[i]=='>') break;
    if (Text()[i]=='<')
    {
     for (o=i+1;o<=c+1;o++)
     {
      if (Text()[o]=='>') break;
      if (Text()[o]=='<') break;

      if (Text()[o]==' ')
      {
       pushmenu=true;
       mode=2;
       fTimer->StartTimer(fOptions->ReakcioIdoTM);
       break;
       i=-1;
      }
      buf1 << Text()[o];
     }
    }
   }
   
   BString str(Text());
   int32 a,b;
   tags.clear();

   a=str.FindLast('<',c);

   if (a>str.FindLast('>',c))
   {
    b=str.FindFirst('>',c);
    int32 e=str.FindFirst('<',c);
    if (b>=0 && ((b<e && e>=0) || (e<0)))
    {
     while (str[a]!=' ')
      a++;
     a++;
     int32 i=a;
     while (i<b)
     {
      if (str[i]==' ')
      {
       BString tmp;
       str.CopyInto(tmp,a,i-a);
       tmp.ToLower();
       if (tmp!=" " && tmp!="")
        tags.push_back(tmp);
       a=i+1;
      }

      if (str[i]=='=')
      {
       BString tmp;
       str.CopyInto(tmp,a,i-a);
       tmp.ToLower();
       tags.push_back(tmp);
       if (str[i+1]=='"')
       {
        a=str.FindFirst('"',i+2)+1;
        i=a-1;
       }
       else
        a=i=str.FindFirst(' ',i+1);
      }

      i++;
     }
    }   
   }
  }
  break;
  case B_UP_ARROW:			// - UP
  {
   BTextView::KeyDown(bytes,numBytes);
   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
  }
  break;
  case B_DOWN_ARROW:		// - DOWN
  {
   BTextView::KeyDown(bytes,numBytes);
   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
  }
  break;
  case B_LEFT_ARROW:		// - LEFT
  {
   BTextView::KeyDown(bytes,numBytes);
   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
  }
  break;
  case B_RIGHT_ARROW:		// - RIGHT
  {
   BTextView::KeyDown(bytes,numBytes);
   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
  }
  break;
  case B_PAGE_UP:			// - PUP
  {
   BTextView::KeyDown(bytes,numBytes);
   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
  }
  break;
  case B_PAGE_DOWN:			// - PDOWN
  {
   BTextView::KeyDown(bytes,numBytes);
   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
  }
  break;
  case B_HOME:				// - HOME
  {
   BTextView::KeyDown(bytes,numBytes);
   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
  }
  break;
  case B_END:				// - END
  {
   BTextView::KeyDown(bytes,numBytes);
   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);
  }
  break;
  case B_BACKSPACE:			// - BackSpace
  {
   fTarget->SetModify(true);
   BTextView::KeyDown(bytes,numBytes);
   fFileTypes->SetFontAndColor(oldtext, newtext = new BString(Text()),0,c-1);

   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);

   if (PointAt(TextLength()-1).y+50>fTarget->fNumView->Bounds().bottom) fTarget->fNumView->ResizeTo(fTarget->fNumView->Bounds().right,PointAt(TextLength()-1).y+50);
  }
  break;
  default:
  {
   fTarget->SetModify(true);
   BTextView::KeyDown(bytes,numBytes);
   fFileTypes->SetFontAndColor(oldtext, newtext = new BString(Text()),0,c);

   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);

   if (PointAt(TextLength()-1).y+50>fTarget->fNumView->Bounds().bottom) fTarget->fNumView->ResizeTo(fTarget->fNumView->Bounds().right,PointAt(TextLength()-1).y+50);

   if (fUpdateTimer->IsActive())
    fUpdateTimer->ResetTimer();
   else
    fUpdateTimer->StartTimer(fOptions->ReakcioIdo);

   if (PointAt(TextLength()-1).y+50>fTarget->fNumView->Bounds().bottom) fTarget->fNumView->ResizeTo(fTarget->fNumView->Bounds().right,PointAt(TextLength()-1).y+50);
  }
 }
	if (oldtext)
 		delete oldtext;
	if (newtext)
 		delete newtext;
// ScrollToSelection();
}
status_t
CreateAppMetaMimeThread::DoMimeUpdate(const entry_ref* ref, bool* _entryIsDir)
{
    if (ref == NULL)
        return B_BAD_VALUE;

    BNode typeNode;

    BFile file;
    status_t status = file.SetTo(ref, B_READ_ONLY);
    if (status < B_OK)
        return status;

    bool isDir = file.IsDirectory();
    if (_entryIsDir != NULL)
        *_entryIsDir = isDir;

    if (isDir)
        return B_OK;

    BAppFileInfo appInfo(&file);
    status = appInfo.InitCheck();
    if (status < B_OK)
        return status;

    // Read the app sig (which consequently keeps us from updating
    // non-applications, since we get an error if the file has no
    // app sig)
    BString signature;
    status = file.ReadAttrString("BEOS:APP_SIG", &signature);
    if (status < B_OK)
        return B_BAD_TYPE;

    // Init our various objects

    BMimeType mime;
    status = mime.SetTo(signature.String());
    if (status < B_OK)
        return status;

    InstallNotificationDeferrer _(fDatabase, signature.String());

    if (!mime.IsInstalled())
        mime.Install();

    BString path = "/";
    path.Append(signature);
    path.ToLower();
    // Signatures and MIME types are case insensitive, but we want to
    // preserve the case wherever possible
    path.Prepend(get_database_directory().c_str());

    status = typeNode.SetTo(path.String());
    if (status < B_OK)
        return status;

    // Preferred App
    attr_info info;
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kPreferredAppAttr, &info) != B_OK))
        status = mime.SetPreferredApp(signature.String());

    // Short Description (name of the application)
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kShortDescriptionAttr, &info) != B_OK))
        status = mime.SetShortDescription(ref->name);

    // App Hint
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kAppHintAttr, &info) != B_OK))
        status = mime.SetAppHint(ref);

    // Vector Icon
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kIconAttr, &info) != B_OK)) {
        uint8* data = NULL;
        size_t size = 0;
        if (appInfo.GetIcon(&data, &size) == B_OK) {
            status = mime.SetIcon(data, size);
            free(data);
        }
    }
    // Mini Icon
    BBitmap miniIcon(BRect(0, 0, 15, 15), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kMiniIconAttr, &info) != B_OK)) {
        if (appInfo.GetIcon(&miniIcon, B_MINI_ICON) == B_OK)
            status = mime.SetIcon(&miniIcon, B_MINI_ICON);
    }
    // Large Icon
    BBitmap largeIcon(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_CMAP8);
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kLargeIconAttr, &info) != B_OK)) {
        if (appInfo.GetIcon(&largeIcon, B_LARGE_ICON) == B_OK)
            status = mime.SetIcon(&largeIcon, B_LARGE_ICON);
    }

    // Supported Types
    bool setSupportedTypes = false;
    BMessage supportedTypes;
    if (status == B_OK && (fForce || typeNode.GetAttrInfo(kSupportedTypesAttr, &info) != B_OK)) {
        if (appInfo.GetSupportedTypes(&supportedTypes) == B_OK)
            setSupportedTypes = true;
    }

    // defer notifications for supported types
    const char* type;
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
        fDatabase->DeferInstallNotification(type);

    // set supported types
    if (setSupportedTypes)
        status = mime.SetSupportedTypes(&supportedTypes);

    // Icons for supported types
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++) {
        // vector icon
        uint8* data = NULL;
        size_t size = 0;
        if (status == B_OK && appInfo.GetIconForType(type, &data, &size) == B_OK) {
            status = mime.SetIconForType(type, data, size);
            free(data);
        }
        // mini icon
        if (status == B_OK && appInfo.GetIconForType(type, &miniIcon, B_MINI_ICON) == B_OK)
            status = mime.SetIconForType(type, &miniIcon, B_MINI_ICON);
        // large icon
        if (status == B_OK && appInfo.GetIconForType(type, &largeIcon, B_LARGE_ICON) == B_OK)
            status = mime.SetIconForType(type, &largeIcon, B_LARGE_ICON);
    }

    // undefer notifications for supported types
    for (int32 i = 0; supportedTypes.FindString("types", i, &type) == B_OK; i++)
        fDatabase->UndeferInstallNotification(type);

    return status;
}
Example #7
0
KeyStrokeSequenceCommandActuator::KeyStrokeSequenceCommandActuator(int32 argc,
	char** argv)
	:
	CommandActuator(argc, argv)
{
	for (int s = 1; s < argc; s++) {
		fSequence.Append(argv[s]);
		if (s < argc - 1)
			fSequence.Append(" ");
	}

	// Find any insert-unicode-here sequences and replace them with spaces...
	int32 nextStart;
	while ((nextStart = fSequence.FindFirst("$$")) >= 0) {
		int32 nextEnd = fSequence.FindFirst("$$", nextStart + 2);
		if (nextEnd >= 0) {
			uint32 customKey= 0;
			int32 unicodeVal= 0;
			uint32 customMods = 0;
			BString sub;
			fSequence.CopyInto(sub, nextStart + 2, nextEnd-(nextStart + 2));
			sub.ToLower();

			if ((sub.FindFirst('-') >= 0) || ((sub.Length() > 0)
				&& ((sub.String()[0] < '0') || (sub.String()[0] > '9')))) {

				const char* s = sub.String();
				while (*s == '-') s++;// go past any initial dashes

				bool lastWasDash = true;
				while (*s) {
					if (lastWasDash) {
						if (strncmp(s, "shift",5) == 0)
							customMods |=B_LEFT_SHIFT_KEY| B_SHIFT_KEY;
						else if (strncmp(s, "leftsh", 6) == 0)
							customMods |=B_LEFT_SHIFT_KEY| B_SHIFT_KEY;
						else if (strncmp(s, "rightsh",7) == 0)
							customMods |=B_RIGHT_SHIFT_KEY | B_SHIFT_KEY;
						else if (strncmp(s, "alt",3) == 0)
							customMods |=B_LEFT_COMMAND_KEY| B_COMMAND_KEY;
						else if (strncmp(s, "leftalt",7) == 0)
							customMods |=B_LEFT_COMMAND_KEY| B_COMMAND_KEY;
						else if (strncmp(s, "rightalt", 8) == 0)
							customMods |=B_RIGHT_COMMAND_KEY | B_COMMAND_KEY;
						else if (strncmp(s, "com",3) == 0)
							customMods |=B_LEFT_COMMAND_KEY| B_COMMAND_KEY;
						else if (strncmp(s, "leftcom",7) == 0)
							customMods |=B_LEFT_COMMAND_KEY| B_COMMAND_KEY;
						else if (strncmp(s, "rightcom", 8) == 0)
							customMods |=B_RIGHT_COMMAND_KEY | B_COMMAND_KEY;
						else if (strncmp(s, "con",3) == 0)
							customMods |=B_LEFT_CONTROL_KEY| B_CONTROL_KEY;
						else if (strncmp(s, "leftcon",7) == 0)
							customMods |=B_LEFT_CONTROL_KEY| B_CONTROL_KEY;
						else if (strncmp(s, "rightcon", 8) == 0)
							customMods |=B_RIGHT_CONTROL_KEY | B_CONTROL_KEY;
						else if (strncmp(s, "win",3) == 0)
							customMods |=B_LEFT_OPTION_KEY | B_OPTION_KEY;
						else if (strncmp(s, "leftwin",7) == 0)
							customMods |=B_LEFT_OPTION_KEY | B_OPTION_KEY;
						else if (strncmp(s, "rightwin", 8) == 0)
							customMods |=B_RIGHT_OPTION_KEY| B_OPTION_KEY;
						else if (strncmp(s, "opt",3) == 0)
							customMods |=B_LEFT_OPTION_KEY | B_OPTION_KEY;
						else if (strncmp(s, "leftopt",7) == 0)
							customMods |=B_LEFT_OPTION_KEY | B_OPTION_KEY;
						else if (strncmp(s, "rightopt", 8) == 0)
							customMods |=B_RIGHT_OPTION_KEY| B_OPTION_KEY;
						else if (strncmp(s, "menu", 4) == 0)
							customMods |=B_MENU_KEY;
						else if (strncmp(s, "caps", 4) == 0)
							customMods |=B_CAPS_LOCK;
						else if (strncmp(s, "scroll", 6) == 0)
							customMods |=B_SCROLL_LOCK;
						else if (strncmp(s, "num",3) == 0)
							customMods |=B_NUM_LOCK;
						else if (customKey == 0) {
							BString arg = s;
							int32 dashIdx = arg.FindFirst('-');

							if (dashIdx >= 0)
								arg.Truncate(dashIdx);

							uint32 key = (uint32)FindKeyCode(arg.String());

							if (key > 0) {
								customKey = key;
								const char* u = GetKeyUTF8(key);

								//Parse the UTF8 back into an int32
								switch(strlen(u)) {
									case 1:
										unicodeVal = ((uint32)(u[0]&0x7F));
										break;
									case 2:
										unicodeVal = ((uint32)(u[1]&0x3F)) |
											(((uint32)(u[0]&0x1F)) << 6);
										break;
									case 3:
										unicodeVal = ((uint32)(u[2]&0x3F)) |
											(((uint32)(u[1]&0x3F)) << 6) |
											(((uint32)(u[0]&0x0F)) << 12);
										break;
									default: unicodeVal = 0;
										break;
								}
							}
						}
						lastWasDash = false;
					} else
						lastWasDash = (*s == '-');

					s++;
				}

				// If we have a letter, try to make it the correct case
				if ((unicodeVal >= 'A') && (unicodeVal <= 'Z')) {
					if ((customMods & B_SHIFT_KEY) == 0)
						unicodeVal += 'a'-'A';
				} else if ((unicodeVal >= 'a') && (unicodeVal <= 'z')) {
					if ((customMods & B_SHIFT_KEY) != 0)
						unicodeVal -= 'a'-'A';
				}
			} else {
				unicodeVal = strtol(&(fSequence.String())[nextStart + 2],
					NULL, 0);
				customMods = (uint32) -1;
			}

			if (unicodeVal == 0)
				unicodeVal = ' ';

			BString newString = fSequence;
			newString.Truncate(nextStart);
			fOverrides.AddItem((void*)(addr_t)unicodeVal);
			fOverrideOffsets.AddItem((void*)(addr_t)newString.Length());
			fOverrideModifiers.AddItem((void*)(addr_t)customMods);
			fOverrideKeyCodes.AddItem((void*)(addr_t)customKey);
			newString.Append((unicodeVal > 0
				&& unicodeVal < 127) ? (char)unicodeVal : ' ', 1);
			newString.Append(&fSequence.String()[nextEnd + 2]);
			fSequence = newString;
		} else
			break;
	}

	_GenerateKeyCodes();
}
Example #8
0
bool
ClientWindow::ParseCmd (const char *data)
{
	BString firstWord (GetWord(data, 1).ToUpper());
		


	if (firstWord == "/WALLOPS"	// we need to insert a ':' before parm2
	||  firstWord == "/SQUIT"   // for the user
	||  firstWord == "/PRIVMSG")
	{
		BString theCmd (firstWord.RemoveAll ("/")),
	            theRest (RestOfString (data, 2));
		
		BMessage send (M_SERVER_SEND);
		AddSend (&send, theCmd);
		if (theRest != "-9z99")
		{
			AddSend (&send, " :");
			AddSend (&send, theRest);
		}
		AddSend (&send, endl);	

		return true;
	}

	if (firstWord == "/KILL")	// we need to insert a ':' before parm3
	{                           // for the user
		BString theCmd (firstWord.RemoveAll ("/")),
				theTarget (GetWord (data, 2)),
	            theRest (RestOfString (data, 3));
		
		BMessage send (M_SERVER_SEND);		
		AddSend (&send, theCmd);
		AddSend (&send, " ");
		AddSend (&send, theTarget);
		if (theRest != "-9z99")
		{
			AddSend (&send, " :");
			AddSend (&send, theRest);
		}
		AddSend (&send, endl);	

		return true;
	}


	// some quick aliases for scripts, these will of course be
	// moved to an aliases section eventually
	
	if (firstWord == "/SOUNDPLAY"
	||  firstWord == "/CL-AMP")
	{
		app_info ai;
		be_app->GetAppInfo (&ai);
		
		BEntry entry (&ai.ref);
		BPath path;
		entry.GetPath (&path);
		path.GetParent (&path);
		//path.Append ("data");
		path.Append ("scripts");
		
		if (firstWord == "/SOUNDPLAY")
			path.Append ("soundplay-hey");
		else
			path.Append ("cl-amp-clr");
		
		BMessage *msg (new BMessage);
		msg->AddString ("exec", path.Path());
		msg->AddPointer ("client", this);
		
		thread_id execThread = spawn_thread (
			ExecPipe,
			"exec_thread",
			B_LOW_PRIORITY,
			msg);

		resume_thread (execThread);
	
		return true;
	}
		


	if (firstWord == "/ABOUT")
	{
		be_app_messenger.SendMessage (B_ABOUT_REQUESTED);
		
		return true;
	}
	
	
	if (firstWord == "/AWAY")
	{
		BString theReason (RestOfString (data, 2));
		BString tempString;
	
	
		if (theReason != "-9z99")
		{
			//nothing to do
		}
		else
		{
			theReason = "BRB"; // Todo: make a default away msg option
		}
	
		const char *expansions[1];
		expansions[0] = theReason.String();
		
		tempString = ExpandKeyed (bowser_app->GetCommand (CMD_AWAY).String(), "R",
			expansions);
		tempString.RemoveFirst("\n");
	
		BMessage send (M_SERVER_SEND);
		AddSend (&send, "AWAY");
		AddSend (&send, " :");
		AddSend (&send, theReason.String());
		AddSend (&send, endl);
		
		if (id != serverName)
		{
			ActionMessage (tempString.String(), myNick.String());
		}
		
		return true;	
	}
	
	
	if (firstWord == "/BACK")
	{
		BMessage send (M_SERVER_SEND);
	
		AddSend (&send, "AWAY");
		AddSend (&send, endl);
	
		if (id != serverName)
		{
			ActionMessage (
				bowser_app->GetCommand (CMD_BACK).String(),
				myNick.String());
		}
		
		return true;
	}
	
	
	if (firstWord == "/CHANSERV"
	||  firstWord == "/NICKSERV"
	||  firstWord == "/MEMOSERV")
	{
		BString theCmd (firstWord.RemoveFirst ("/")),
				theRest (RestOfString (data, 2));
		theCmd.ToLower();
	
		if (theRest != "-9z99")
		{
			if (bowser_app->GetMessageOpenState())
			{
				BMessage msg (OPEN_MWINDOW);
				BMessage buffer (M_SUBMIT);
	
				buffer.AddString ("input", theRest.String());
				msg.AddMessage ("msg", &buffer);
				msg.AddString ("nick", theCmd.String());
				sMsgr.SendMessage (&msg);
			}
			else
			{
				BString tempString;
				
				tempString << "[M]-> " << theCmd << " > " << theRest << "\n";
				Display (tempString.String(), 0);
	
				BMessage send (M_SERVER_SEND);
				AddSend (&send, "PRIVMSG ");
				AddSend (&send, theCmd);
				AddSend (&send, " :");
				AddSend (&send, theRest);
				AddSend (&send, endl);
			}
		}
		
		return true;
	}
	
	
	if (firstWord == "/CLEAR")
	{
		text->ClearView (false);
		return true;
	}

	if (firstWord == "/FCLEAR")
	{
		text->ClearView (true);
		return true;
	}
	
	
	if (firstWord == "/CTCP")
	{
		BString theTarget (GetWord (data, 2));
		BString theAction (RestOfString (data, 3));
	
		if (theAction != "-9z99")
		{
			theAction.ToUpper();
	
			if (theAction.ICompare ("PING") == 0)
			{
				time_t now (time (0));
	
				theAction << " " << now;
			}
	
			CTCPAction (theTarget, theAction);
	
			BMessage send (M_SERVER_SEND);
			AddSend (&send, "PRIVMSG ");
			AddSend (&send, theTarget << " :\1" << theAction << "\1");
			AddSend (&send, endl);
		}
		
		return true;
	}
	
	
	if (firstWord == "/DCC")
	{
		BString secondWord (GetWord (data, 2));
		BString theNick (GetWord (data, 3));
		BString theFile (RestOfString(data, 4));
		
		if (secondWord.ICompare ("SEND") == 0
		&&  theNick != "-9z99")
		{
			BMessage *msg (new BMessage (CHOSE_FILE));
			msg->AddString ("nick", theNick.String());
			if (theFile != "-9z99")
			{	
				char filePath[B_PATH_NAME_LENGTH] = "\0";
				if (theFile.ByteAt(0) != '/')
				{
					find_directory(B_USER_DIRECTORY, 0, false, filePath, B_PATH_NAME_LENGTH);
					filePath[strlen(filePath)] = '/';
				}
				strcat(filePath, theFile.LockBuffer(0));
				theFile.UnlockBuffer();
	
				// use BPath to resolve relative pathnames, above code forces it
				// to use /boot/home as a working dir as opposed to the app path
	
				BPath sendPath(filePath, NULL, true);
				
				// the BFile is used to verify if the file exists
				// based off the documentation get_ref_for_path *should*
				// return something other than B_OK if the file doesn't exist
				// but that doesn't seem to be working correctly
				
				BFile sendFile(sendPath.Path(), B_READ_ONLY);
				
				// if the file exists, send, otherwise drop to the file panel
				
				if (sendFile.InitCheck() == B_OK)
				{
					sendFile.Unset();
					entry_ref ref;
					get_ref_for_path(sendPath.Path(), &ref);
					msg->AddRef("refs", &ref);
					sMsgr.SendMessage(msg);	
					return true;	
				}
			}
			BFilePanel *myPanel (new BFilePanel);
			BString myTitle ("Sending a file to ");
	
			myTitle.Append (theNick);
			myPanel->Window()->SetTitle (myTitle.String());
	
			myPanel->SetMessage (msg);
	
			myPanel->SetButtonLabel (B_DEFAULT_BUTTON, "Send");
			myPanel->SetTarget (sMsgr);
			myPanel->Show();
		}
		else if (secondWord.ICompare ("CHAT") == 0
		&&       theNick != "-9z99")
		{
			BMessage msg (CHAT_ACTION);
	
			msg.AddString ("nick", theNick.String());
	
			sMsgr.SendMessage (&msg);
		}
		
		return true;
	}
	
	
	if (firstWord == "/DOP" || firstWord == "/DEOP")
	{
		BString theNick (RestOfString (data, 2));

		if (theNick != "-9z99")
		{
			BMessage send (M_SERVER_SEND);
	
			AddSend (&send, "MODE ");
			AddSend (&send, id);
			AddSend (&send, " -oooo ");
			AddSend (&send, theNick);
			AddSend (&send, endl);
		}
		
		return true;
	}
	
	
	if (firstWord == "/DESCRIBE")
	{
    	BString theTarget (GetWord (data, 2));
		BString theAction (RestOfString (data, 3));
		
		if (theAction != "-9z99") {
		
			BMessage send (M_SERVER_SEND);
	
			AddSend (&send, "PRIVMSG ");
			AddSend (&send, theTarget);
			AddSend (&send, " :\1ACTION ");
			AddSend (&send, theAction);
			AddSend (&send, "\1");
			AddSend (&send, endl);
		
			BString theActionMessage ("[ACTION]-> ");
			theActionMessage << theTarget << " -> " << theAction << "\n";
	
			Display (theActionMessage.String(), 0);
		}
		
		return true;
	}
		
	
	if (firstWord == "/DNS")
	{
		BString parms (GetWord(data, 2));
	
		ChannelWindow *window;
		MessageWindow *message;
		
		if ((window = dynamic_cast<ChannelWindow *>(this)))
		{
				int32 count (window->namesList->CountItems());
				
				for (int32 i = 0; i < count; ++i)
				{
					NameItem *item ((NameItem *)(window->namesList->ItemAt (i)));
					
					if (!item->Name().ICompare (parms.String(), strlen (parms.String()))) //nick
					{
						BMessage send (M_SERVER_SEND);
						AddSend (&send, "USERHOST ");
						AddSend (&send, item->Name().String());
						AddSend (&send, endl);
						PostMessage(&send);	
						return true;				
					}
				}
		}
	
		else if ((message = dynamic_cast<MessageWindow *>(this)))
		{
			BString eid (id);
			eid.RemoveLast (" [DCC]");
			if (!ICompare(eid, parms) || !ICompare(myNick, parms))
			{
				BMessage send (M_SERVER_SEND);
				AddSend (&send, "USERHOST ");
				AddSend (&send, parms.String());
				AddSend (&send, endl);
				PostMessage(&send);
				return true;
			}
		}
			
		if (parms != "-9z99")
		{
			BMessage *msg (new BMessage);
			msg->AddString ("lookup", parms.String());
			msg->AddPointer ("client", this);
			
			thread_id lookupThread = spawn_thread (
				DNSLookup,
				"dns_lookup",
				B_LOW_PRIORITY,
				msg);
	
			resume_thread (lookupThread);
		}
		
		return true;
	}
	
	
	if (firstWord == "/PEXEC") // piped exec
	{
		
		BString theCmd (RestOfString (data, 2));
		
		if (theCmd != "-9z99")
		{
			BMessage *msg (new BMessage);
			msg->AddString ("exec", theCmd.String());
			msg->AddPointer ("client", this);
			
			thread_id execThread = spawn_thread (
				ExecPipe,
				"exec_thread",
				B_LOW_PRIORITY,
				msg);
	
			resume_thread (execThread);
		
		}
		
		return true;
	
	}
	
	
	if (firstWord == "/EXCLUDE")
	{
		BString second (GetWord (data, 2)),
			rest (RestOfString (data, 3));
	
		if (rest != "-9z99" && rest != "-9z99")
		{
			BMessage msg (M_EXCLUDE_COMMAND);
	
			msg.AddString ("second", second.String());
			msg.AddString ("cmd", rest.String());
			msg.AddString ("server", serverName.String());
			msg.AddRect ("frame", Frame());
			bowser_app->PostMessage (&msg);	
		}
		
		return true;
	}
	
	
	if (firstWord == "/IGNORE")
	{
		BString rest (RestOfString (data, 2));
	
		if (rest != "-9z99")
		{
			BMessage msg (M_IGNORE_COMMAND);
	
			msg.AddString ("cmd", rest.String());
			msg.AddString ("server", serverName.String());
			msg.AddRect ("frame", Frame());
			bowser_app->PostMessage (&msg);
		}
		
		return true;
	}	
	
	if (firstWord == "/INVITE" || firstWord == "/I")
	{

		BString theUser (GetWord (data, 2));

		if (theUser != "-9z99")
		{
			BString theChan (GetWord (data, 3));
	
			if (theChan == "-9z99")
				theChan = id;
	
			BMessage send (M_SERVER_SEND);
	
			AddSend (&send, "INVITE ");
			AddSend (&send, theUser << " " << theChan);
			AddSend (&send, endl);
		}
		
		return true;	
	}
	
	
	if (firstWord == "/JOIN" || firstWord == "/J")
	{
		BString channel (GetWord (data, 2));

		if (channel != "-9z99")
		{
			if (channel[0] != '#' && channel[0] != '&')
				channel.Prepend("#");

			BMessage send (M_SERVER_SEND);

			AddSend (&send, "JOIN ");
			AddSend (&send, channel);

			BString key (GetWord (data, 3));
			if (key != "-9z99")
			{
				AddSend (&send, " ");
				AddSend (&send, key);
			}
	
			AddSend (&send, endl);
		}
		
		return true;
	}
	
	if (firstWord == "/KICK" || firstWord == "/K")
	{
		BString theNick (GetWord (data, 2));
	
		if (theNick != "-9z99")
		{
			BString theReason (RestOfString (data, 3));
	
			if (theReason == "-9z99")
			{
				// No expansions
				theReason = bowser_app
					->GetCommand (CMD_KICK);
			}
	
			BMessage send (M_SERVER_SEND);
	
			AddSend (&send, "KICK ");
			AddSend (&send, id);
			AddSend (&send, " ");
			AddSend (&send, theNick);
			AddSend (&send, " :");
			AddSend (&send, theReason);
			AddSend (&send, endl);
		}
		
		return true;
	}
	
	
	if (firstWord == "/LIST")
	{
		BMessage msg (M_LIST_COMMAND);

		msg.AddString ("cmd", data);
		msg.AddString ("server", serverName.String());
		msg.AddRect ("frame", Frame());
		bowser_app->PostMessage (&msg);
	
		return true;
	}
	
	
	if (firstWord == "/M")
	{
		BString theMode (RestOfString (data, 2));
		
		BMessage send (M_SERVER_SEND);
		AddSend (&send, "MODE ");
	
		if (id == serverName)
			AddSend (&send, myNick);
		else if (id[0] == '#' || id[0] == '&')
			AddSend (&send, id);
		else
			AddSend (&send, myNick);
		 
		if (theMode != "-9z99")
		{
				AddSend (&send, " ");
				AddSend (&send, theMode);
		}

		AddSend (&send, endl);
	
		return true;
	}
	
	
	if (firstWord == "/ME")
	{
		BString theAction (RestOfString (data, 2));

		if (theAction != "-9z99")
		{
			ActionMessage (theAction.String(), myNick.String());
		}
		
		return true;
	}

		
	if (firstWord == "/MODE")
	{
		BString theMode (RestOfString (data, 3));
		BString theTarget (GetWord (data, 2));

		if (theTarget != "-9z99")
		{
			BMessage send (M_SERVER_SEND);
	
			AddSend (&send, "MODE ");
	
			if (theMode == "-9z99")
				AddSend (&send, theTarget);
			else
				AddSend (&send, theTarget << " " << theMode);
	
			AddSend (&send, endl);
		}
		
		return true;
	}
	
	
	if (firstWord == "/MSG")
	{
		BString theRest (RestOfString (data, 3));
		BString theNick (GetWord (data, 2));
	
		if (theRest != "-9z99"
		&&  myNick.ICompare (theNick))
		{
			if (bowser_app->GetMessageOpenState())
			{
				BMessage msg (OPEN_MWINDOW);
				BMessage buffer (M_SUBMIT);
	
				buffer.AddString ("input", theRest.String());
				msg.AddMessage ("msg", &buffer);
				msg.AddString ("nick", theNick.String());
				sMsgr.SendMessage (&msg);
			}
			else
			{
				BString tempString;
				
				tempString << "[M]-> " << theNick << " > " << theRest << "\n";
				Display (tempString.String(), 0);
	
				BMessage send (M_SERVER_SEND);
				AddSend (&send, "PRIVMSG ");
				AddSend (&send, theNick);
				AddSend (&send, " :");
				AddSend (&send, theRest);
				AddSend (&send, endl);
			}

		}
		return true;
	}	
		
	if (firstWord == "/NICK")
	{
		BString newNick (GetWord (data, 2));

		if (newNick != "-9z99")
		{
			BString tempString ("*** Trying new nick ");
	
			tempString << newNick << ".\n";
			Display (tempString.String(), 0);
	
			BMessage send (M_SERVER_SEND);
			AddSend (&send, "NICK ");
			AddSend (&send, newNick);
			AddSend (&send, endl);
		}
		
		return true;
	}
	
	
	if (firstWord == "/NOTICE")
	{
		BString theTarget (GetWord (data, 2));
		BString theMsg (RestOfString (data, 3));
	
		if (theMsg != "-9z99")
		{
			BMessage send (M_SERVER_SEND);
	
			AddSend (&send, "NOTICE ");
			AddSend (&send, theTarget);
			AddSend (&send, " :");
			AddSend (&send, theMsg);
			AddSend (&send, endl);
	
			BString tempString ("[N]-> ");
			tempString << theTarget << " -> " << theMsg << '\n';
	
			Display (tempString.String(), 0);
		}
		
		return true;
	}
	
	
	if (firstWord == "/NOTIFY")
	{
		BString rest (RestOfString (data, 2));
	
		if (rest != "-9z99")
		{
			BMessage msg (M_NOTIFY_COMMAND);
	
			msg.AddString ("cmd", rest.String());
			msg.AddBool ("add", true);
			msg.AddString ("server", serverName.String());
			msg.AddRect ("frame", Frame());
			bowser_app->PostMessage (&msg);
		}
		
		return true;
	}

	if (firstWord == "/OP")
	{
		BString theNick (RestOfString (data, 2));
	
		if (theNick != "-9z99")
		{
			// TODO only applies to a channel
	
			BMessage send (M_SERVER_SEND);
	
			AddSend (&send, "MODE ");
			AddSend (&send, id);
			AddSend (&send, " +oooo ");
			AddSend (&send, theNick);
			AddSend (&send, endl);
		}
		
		return true;
	}
	

	if (firstWord == "/PART")
	{
		BMessage msg (B_QUIT_REQUESTED);

		msg.AddBool ("bowser:part", true);
		PostMessage (&msg);

		return true;
	}	
	
	
	if (firstWord == "/PING")
	{
		BString theNick (GetWord (data, 2));
	
		if (theNick != "-9z99")
		{
			long theTime (time (0));
			BString tempString ("/CTCP ");
	
			tempString << theNick << " PING " << theTime;
			SlashParser (tempString.String());
		}
	
		return true;
	}
	
	
	if (firstWord == "/PREFERENCES")
	{
		be_app_messenger.SendMessage (M_PREFS_BUTTON);
		
		return true;
	}
	
	
	if (firstWord == "/QUERY" || firstWord == "/Q")
	{
		BString theNick (GetWord (data, 2));

		if (theNick != "-9z99")
		{
			BMessage msg (OPEN_MWINDOW);
	
			msg.AddString ("nick", theNick.String());
			sMsgr.SendMessage (&msg);
		}
	
		return true;	
	}

	
	if (firstWord == "/QUIT")
	{
		BString theRest (RestOfString (data, 2));
		BString buffer;
	
		if (theRest == "-9z99")
		{
			const char *expansions[1];
			BString version (bowser_app->BowserVersion());
	
			expansions[0] = version.String();
			theRest = ExpandKeyed (bowser_app
				->GetCommand (CMD_QUIT).String(), "V", expansions);
		}
	
		buffer << "QUIT :" << theRest;
	
		BMessage msg (B_QUIT_REQUESTED);
		msg.AddString ("bowser:quit", buffer.String());
		sMsgr.SendMessage (&msg);
	
		return true;
	}
	
	
	if (firstWord == "/RAW" || firstWord == "/QUOTE")
	{

		BString theRaw (RestOfString (data, 2));
	
		if (theRaw != "-9z99")
		{
			BMessage send (M_SERVER_SEND);
	
			AddSend (&send, theRaw);
			AddSend (&send, endl);
	
			BString tempString ("[R]-> ");
			tempString << theRaw << '\n';
	
			Display (tempString.String(), 0);
	
		}
		
		return true;
	}
	
	
	if (firstWord == "/RECONNECT")
	{
		BMessage msg (M_SLASH_RECONNECT);
		msg.AddString ("server", serverName.String());
		bowser_app->PostMessage (&msg);
		return true;
	}
	
	
	if (firstWord == "/SLEEP")
	{
		BString rest (RestOfString (data, 2));
	
		if (rest != "-9z99")
		{
			// this basically locks up the window its run from,
			// but I can't think of a better way with our current
			// commands implementation
			int32 time = atoi(rest.String());
			snooze(time * 1000 * 100); // deciseconds? 10 = one second
		}
		
		return true;
	
	}
	
		
	if (firstWord == "/TOPIC" || firstWord == "/T")
	{
		BString theChan (id);
		BString theTopic (RestOfString (data, 2));
		BMessage send (M_SERVER_SEND);
	
		AddSend (&send, "TOPIC ");
	
		if (theTopic == "-9z99")
			AddSend (&send, theChan);
		else
			AddSend (&send, theChan << " :" << theTopic);
		AddSend (&send, endl);
		
		return true;
	}
	
	
	if (firstWord == "/UNIGNORE")
	{
		BString rest (RestOfString (data, 2));
	
		if (rest != "-9z99")
		{
			BMessage msg (M_UNIGNORE_COMMAND);
	
			msg.AddString ("cmd", rest.String());
			msg.AddString ("server", serverName.String());
			msg.AddRect ("frame", Frame());
			bowser_app->PostMessage (&msg);
		}
	
		return true;
	}
	
	
	if (firstWord == "/UNNOTIFY")
	{
		BString rest (RestOfString (data, 2));
	
		if (rest != "-9z99")
		{
			BMessage msg (M_NOTIFY_COMMAND);
	
			msg.AddString ("cmd", rest.String());
			msg.AddBool ("add", false);
			msg.AddRect ("frame", Frame());
			msg.AddString ("server", serverName.String());
			bowser_app->PostMessage (&msg);
		}
	
		return true;
	}
	
	
	if (firstWord == "/UPTIME")
	{
		BString parms (GetWord(data, 2));
		
		BString uptime (DurationString(system_time()));
		BString expandedString;
		const char *expansions[1];
		expansions[0] = uptime.String();
		expandedString = ExpandKeyed (bowser_app->GetCommand (CMD_UPTIME).String(), "U",
			expansions);
		expandedString.RemoveFirst("\n");
	
		if ((id != serverName) && (parms == "-9z99"))
		{
			BMessage send (M_SERVER_SEND);
			
			AddSend (&send, "PRIVMSG ");
			AddSend (&send, id);
			AddSend (&send, " :");
			AddSend (&send, expandedString.String());
			AddSend (&send, endl);
			
			ChannelMessage (expandedString.String(), myNick.String());
		}
		else if ((parms == "-l") || (id == serverName)) // echo locally
		{
			BString tempString;
				
			tempString << "Uptime: " << expandedString << "\n";
			Display (tempString.String(), &whoisColor);
			
		}
		
		return true;
	}
	
	
	if (firstWord == "/VERSION"
	||  firstWord == "/TIME")
	{
		BString theCmd (firstWord.RemoveFirst ("/")),
				theNick (GetWord (data, 2));
		theCmd.ToUpper();
	
		// the "." check is because the user might specify a server name
		
		if (theNick != "-9z99" && theNick.FindFirst(".") < 0)
		{
			BString tempString ("/CTCP ");
	
			tempString << theNick << " " << theCmd;
			SlashParser (tempString.String());
		}
		else
		{
		  	BMessage send (M_SERVER_SEND);
	
			AddSend (&send, theCmd);
			
			if (theNick != "-9z99")
			{
				AddSend (&send, " ");
				AddSend (&send, theNick);
			}
						
			AddSend (&send, endl);
		}
		
		return true;
	}
	
	
	if (firstWord == "/VISIT")
	{
		BString buffer (data);
		int32 place;
	
		if ((place = buffer.FindFirst (" ")) >= 0)
		{
			buffer.Remove (0, place + 1);
	
			const char *arguments[] = {buffer.String(), 0};
			
			
	
			be_roster->Launch (
				"text/html",
				1,
				const_cast<char **>(arguments));
		}
		
		return true;
	}



	if (firstWord != "" && firstWord[0] == '/')
	// != "" is required to prevent a nasty crash with string[0]
	{
		BString theCmd (firstWord.RemoveAll ("/")),
	            theRest (RestOfString (data, 2));
		
		BMessage send (M_SERVER_SEND);
		
		if (theCmd == "W")
			theCmd = "WHOIS";

		AddSend (&send, theCmd);
	
		if (theRest != "-9z99")
		{
			AddSend (&send, " ");
			AddSend (&send, theRest);
		}
		AddSend (&send, endl);	

		return true;
	}
	
	return false;  // we couldn't handle this message

}