This file is indexed.

/usr/lib/Wt/examples/simplechat/SimpleChatServer.C is in witty-examples 3.1.10-1ubuntu2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 * Copyright (C) 2008 Emweb bvba, Heverlee, Belgium.
 *
 * See the LICENSE file for terms of use.
 */

#include "SimpleChatServer.h"
#include <Wt/WServer>

#include <iostream>
#include <boost/lexical_cast.hpp>

using namespace Wt;

const WString ChatEvent::formattedHTML(const WString& user) const
{
  switch (type_) {
  case Login:
    return "<span class='chat-info'>" + user_ + " joined.</span>";
  case Logout:
    return "<span class='chat-info'>"
      + ((user == user_) ? "You" : user_)
      + " logged out.</span>";
  case Rename:
    return "<span class='chat-info'>"
      + ((user == data_ || user == user_) ?
	 "You are" : (user_ + " is")) + " now known as "
      + data_ + ".</span>";
  case Message:{
    WString result;

    result = WString("<span class='")
      + ((user == user_) ? "chat-self" : "chat-user")
      + "'>" + user_ + ":</span>";

    if (message_.toUTF8().find(user.toUTF8()) != std::string::npos)
      return result + "<span class='chat-highlight'>" + message_ + "</span>";
    else
      return result + message_;
  }
  default:
    return "";
  }
}


SimpleChatServer::SimpleChatServer(WServer& server)
  : server_(server)
{ }

bool SimpleChatServer::login(const WString& user,
			     const ChatEventCallback& handleEvent)
{
  boost::recursive_mutex::scoped_lock lock(mutex_);
  
  if (users_.find(user) == users_.end()) {
    UserInfo userInfo;
    userInfo.sessionId = WApplication::instance()->sessionId();
    userInfo.eventCallback = handleEvent;

    users_[user] = userInfo;

    postChatEvent(ChatEvent(ChatEvent::Login, user));

    return true;
  } else
    return false;
}

void SimpleChatServer::logout(const WString& user)
{
  boost::recursive_mutex::scoped_lock lock(mutex_);

  UserMap::iterator i = users_.find(user);

  if (i != users_.end()) {
    users_.erase(i);

    postChatEvent(ChatEvent(ChatEvent::Logout, user));
  }
}

bool SimpleChatServer::changeName(const WString& user, const WString& newUser)
{
  if (user == newUser)
    return true;

  boost::recursive_mutex::scoped_lock lock(mutex_);
  
  UserMap::iterator i = users_.find(user);

  if (i != users_.end()) {
    if (users_.find(newUser) == users_.end()) {
      UserInfo info = i->second;
      users_.erase(i);
      users_[newUser] = info;

      postChatEvent(ChatEvent(ChatEvent::Rename, user, newUser));

      return true;
    } else
      return false;
  } else
    return false;
}

WString SimpleChatServer::suggestGuest()
{
  boost::recursive_mutex::scoped_lock lock(mutex_);

  for (int i = 1;; ++i) {
    std::string s = "guest " + boost::lexical_cast<std::string>(i);
    WString ss = s;

    if (users_.find(ss) == users_.end())
      return ss;
  }
}

void SimpleChatServer::sendMessage(const WString& user, const WString& message)
{
  postChatEvent(ChatEvent(user, message));
}

void SimpleChatServer::postChatEvent(const ChatEvent& event)
{
  boost::recursive_mutex::scoped_lock lock(mutex_);

  WApplication *app = WApplication::instance();

  for (UserMap::const_iterator i = users_.begin(); i != users_.end(); ++i) {
    /*
     * If the user corresponds to the current application, we directly
     * call the call back method. This avoids an unnecessary delay for
     * the update to the user causing the event.
     *
     * For other uses, we post it to their session. By posting the
     * event, we avoid dead-lock scenarios, race conditions, and
     * delivering the event to a session that is just about to be
     * terminated.
     */
    if (app && app->sessionId() == i->second.sessionId)
      i->second.eventCallback(event);
    else
      server_.post(i->second.sessionId,
		   boost::bind(i->second.eventCallback, event));
  }
}

SimpleChatServer::UserSet SimpleChatServer::users()
{
  boost::recursive_mutex::scoped_lock lock(mutex_);

  UserSet result;
  for (UserMap::const_iterator i = users_.begin(); i != users_.end(); ++i)
    result.insert(i->first);

  return result;
}