Example #1
0
bool psEntity::CanPlay(int time, float range) const
{
    EntityState* entityState;

    // checking if it is in the undefined state
    entityState = states.Get(state, 0);
    if(entityState == 0)
    {
        Debug3(LOG_SOUND, 0, "psEntity::CanPlay %s meshid: %u undefined state.", entityName.GetData(), GetMeshID());
        return false;
    }

    // checking time, range and delay
    if(range < minRange || range > maxRange)
    {
        Debug6(LOG_SOUND, 0, "psEntity::CanPlay %s meshid: %u range %f %f %f", entityName.GetData(),GetMeshID(), minRange, range, maxRange);
        return false;
    }
    else if(time < entityState->timeOfDayStart || entityState->timeOfDayEnd < time)
    {
        Debug6(LOG_SOUND, 0, "psEntity::CanPlay %s meshid: %u time of day %d %d %d", entityName.GetData(),GetMeshID(), entityState->timeOfDayStart,time,entityState->timeOfDayEnd);
        return false;
    }
    else if(when <= 0)
    {
        Debug4(LOG_SOUND, 0, "psEntity::CanPlay TRUE %s meshid: %u when <0 : %d", entityName.GetData(),GetMeshID(), when);
        return true;
    }
    Debug4(LOG_SOUND, 0, "psEntity::CanPlay %s meshid: %u when : %d", entityName.GetData(),GetMeshID(), when);

    return false;
}
Example #2
0
File: sycls.c Project: erluko/socat
struct hostent *Getipnodebyname(const char *name, int af, int flags,
                                int *error_num) {
   struct hostent *result;
   Debug4("getipnodebyname(\"%s\", %d, %d, %p)", name, af, flags, error_num);
   result = getipnodebyname(name, af, flags, error_num);
   if (result == NULL) {
      Debug1("getipnodebyname(,,, {%d}) -> NULL", *error_num);
   } else {
      Debug4("getipnodebyname() -> {\"%s\", %p, %d, %d, ???}",
	     result->h_name, result->h_aliases, result->h_addrtype,
	     result->h_length);
   }
   return result;
}
Example #3
0
File: sycls.c Project: erluko/socat
int Recvmsg(int s, struct msghdr *msgh, int flags) {
   int retval, _errno;
   char infobuff[256];
#if defined(HAVE_STRUCT_MSGHDR_MSGCONTROL) && defined(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN) && defined(HAVE_STRUCT_MSGHDR_MSGFLAGS)
   Debug10("recvmsg(%d, %p{%p,%u,%p,%u,%p,%u,%d}, %d)", s, msgh,
	  msgh->msg_name, msgh->msg_namelen,  msgh->msg_iov,  msgh->msg_iovlen,
	  msgh->msg_control,  msgh->msg_controllen,  msgh->msg_flags, flags);
#else
   Debug7("recvmsg(%d, %p{%p,%u,%p,%u}, %d)", s, msgh,
	  msgh->msg_name, msgh->msg_namelen,  msgh->msg_iov,  msgh->msg_iovlen,
	  flags);
#endif
   retval = recvmsg(s, msgh, flags);
   _errno = errno;
#if defined(HAVE_STRUCT_MSGHDR_MSGCONTROLLEN)
   Debug5("recvmsg(, {%s,%u,,%u,,%u,}, ) -> %d",
	  msgh->msg_name?sockaddr_info(msgh->msg_name, msgh->msg_namelen, infobuff, sizeof(infobuff)):"NULL",
	  msgh->msg_namelen, msgh->msg_iovlen, msgh->msg_controllen,
	  retval);
#else
   Debug4("recvmsg(, {%s,%u,,%u,,}, ) -> %d",
	  msgh->msg_name?sockaddr_info(msgh->msg_name, msgh->msg_namelen, infobuff, sizeof(infobuff)):"NULL",
	  msgh->msg_namelen, msgh->msg_iovlen,
	  retval);
#endif
   errno = _errno;
   return retval;
}
Example #4
0
File: sycls.c Project: erluko/socat
int Connect(int sockfd, const struct sockaddr *serv_addr, int addrlen) {
   int result, _errno;
   char infobuff[256];

   /*sockaddr_info(serv_addr, infobuff, sizeof(infobuff));
   Debug3("connect(%d, %s, "F_Zd")", sockfd, infobuff, addrlen);*/
#if 0
   Debug18("connect(%d,{0x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x}, "F_Zd")",
	   sockfd,
	   ((unsigned char *)serv_addr)[0],  ((unsigned char *)serv_addr)[1],
	   ((unsigned char *)serv_addr)[2],  ((unsigned char *)serv_addr)[3], 
	   ((unsigned char *)serv_addr)[4],  ((unsigned char *)serv_addr)[5], 
	   ((unsigned char *)serv_addr)[6],  ((unsigned char *)serv_addr)[7], 
	   ((unsigned char *)serv_addr)[8],  ((unsigned char *)serv_addr)[9], 
	   ((unsigned char *)serv_addr)[10], ((unsigned char *)serv_addr)[11], 
	   ((unsigned char *)serv_addr)[12], ((unsigned char *)serv_addr)[13], 
	   ((unsigned char *)serv_addr)[14], ((unsigned char *)serv_addr)[15], 
	   addrlen);
#else
   Debug4("connect(%d, {%d,%s}, "F_Zd")",
	  sockfd, serv_addr->sa_family,
	  sockaddr_info(serv_addr, addrlen, infobuff, sizeof(infobuff)),
	  addrlen);
#endif
   result = connect(sockfd, serv_addr, addrlen);
   _errno = errno;
   Debug1("connect() -> %d", result);
   errno = _errno;
   return result;
}
Example #5
0
File: sycls.c Project: erluko/socat
int Recv(int s, void *buf, size_t len, int flags) {
   int retval, _errno;
   Debug4("recv(%d, %p, "F_Zu", %d)", s, buf, len, flags);
   retval = recv(s, buf, len, flags);
   _errno = errno;
   Debug1("recv() -> %d", retval);
   errno = _errno;
   return retval;
}
Example #6
0
File: sycls.c Project: erluko/socat
int Socketpair(int d, int type, int protocol, int sv[2]) {
   int result, _errno;
   Debug4("socketpair(%d, %d, %d, %p)", d, type, protocol, sv);
   result = socketpair(d, type, protocol, sv);
   _errno = errno;
   Info6("socketpair(%d, %d, %d, {%d,%d}) -> %d", d, type, protocol, sv[0], sv[1], result);
   errno = _errno;
   return result;
}
Example #7
0
/* move the filedescriptors from the old handles to the new handles.
   old -1 handles are ignored, new -1 handles are not closed.
   returns 0 on success, -1 if a dup error occurred, or 1 on a close error
*/
static int reassignfds(int oldfd1, int oldfd2, int newfd1, int newfd2) {
   int tmpfd;
   int result;

   Debug4("reassignfds(%d, %d, %d, %d)", oldfd1, oldfd2, newfd1, newfd2);
   if (oldfd1 == newfd1) {
      Fcntl_l(newfd1, F_SETFD, 0);
      oldfd1 = -1;
   }
   if (oldfd2 == newfd2) {
      Fcntl_l(newfd2, F_SETFD, 0);
      oldfd2 = -1;
   }

   if (oldfd1 < 0 && oldfd2 < 0)  return 0;

   if (oldfd2 < 0) {
      if ((result = xiodup2(oldfd1, newfd1)) < 0)  return result;
      if (newfd2 != oldfd1)  if (Close(oldfd1) < 0)  return 1;
      return 0;
   }

   if (oldfd1 < 0) {
      if ((result = xiodup2(oldfd2, newfd2)) < 0)  return result;
      if (oldfd2 >= 0)  if (Close(oldfd2) < 0)  return 1;
      return 0;
   }

   if (oldfd2 == newfd1) {
      if (oldfd1 == newfd2) {
	 /* exchange them */
	 if ((tmpfd  = xiodup(oldfd2)) < 0)  return tmpfd;
	 if ((result = xiodup2(oldfd1, newfd1)) < 0)  return result;
	 if ((result = xiodup2(tmpfd,  newfd2)) < 0)  return result;
	 if (Close(tmpfd) < 0)  return 1;
      } else {
	 if ((result = xiodup2(oldfd2, newfd2)) < 0)  return result;
	 if ((result = xiodup2(oldfd1, newfd1)) < 0)  return result;
	 if (Close(oldfd1) < 0)  return 1;
      }
   } else {
      if (oldfd1 == newfd2) {
	 if ((result = xiodup2(oldfd1, newfd1)) < 0)  return result;
	 if ((result = xiodup2(oldfd2, newfd2)) < 0)  return result;
	 if (Close(oldfd2) < 0)  return 1;
      } else {
	 if ((result = xiodup2(oldfd1, newfd1)) < 0)  return result;
	 if ((result = xiodup2(oldfd2, newfd2)) < 0)  return result;
	 if (Close(oldfd1) < 0 || Close(oldfd2) < 0)  return 1;
      }
   }
   return 0;
}
Example #8
0
DH *sycPEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) {
   DH *result;
   Debug4("PEM_read_bio_DHparams(%p, %p, %p, %p)",
	  bp, x, cb, u);
   result = PEM_read_bio_DHparams(bp, x, cb, u);
   if (result) {
      /*Debug2("PEM_read_bio_DHparams(, {%p},,) -> %p", *x, result);*/
      Debug1("PEM_read_bio_DHparams() -> %p", result);
   } else {
      Debug("PEM_read_bio_DHparams() -> NULL");
   }
   return result;
}
Example #9
0
File: sycls.c Project: erluko/socat
int Getpeername(int s, struct sockaddr *name, socklen_t *namelen) {
   int result, _errno;
   char infobuff[256];

   Debug4("getpeername(%d, %p, %p{"F_socklen"})", s, name, namelen, *namelen);
   result = getpeername(s, name, namelen);
   _errno = errno;
   sockaddr_info(name, *namelen, infobuff, sizeof(infobuff));
   Debug3("getpeername(, {%s}, {"F_socklen"}) -> %d",
	  infobuff, *namelen, result);
   errno = _errno;
   return result;
}
Example #10
0
File: sycls.c Project: erluko/socat
int Ioctl(int d, int request, void *argp) {
   int retval, _errno;
   if (argp > (void *)0x10000) {	/* fuzzy...*/
      Debug4("ioctl(%d, 0x%x, %p{%lu})", d, request, argp, *(unsigned long *)argp);
   } else {
      Debug3("ioctl(%d, 0x%x, 0x%p)", d, request, argp);
   }
   retval = ioctl(d, request, argp);
   _errno = errno;
   Debug1("ioctl() -> %d", retval);
   errno = _errno;
   return retval;
}
Example #11
0
void EntityManager::HandleUserAction(MsgEntry* me, Client *client)
{
    psUserActionMessage actionMsg(me);
    csString action;

    if (!actionMsg.valid)
    {
        Debug2(LOG_NET,me->clientnum,"Received unparsable psUserActionMessage from client id %u.",me->clientnum);
        return;
    }

    gemObject *object = gem->FindObject(actionMsg.target);

    if (actionMsg.target.IsValid() && !object)
    {
        Debug2(LOG_ANY, me->clientnum, "User action on unknown entity (%s)!", ShowID(actionMsg.target));
        return;
    }

    client->SetTargetObject(object);  // have special tracking for this for fast processing of other messages

    if (!object)
    {
        // TODO: Evaluate if this output is needed. 
        Debug2(LOG_ANY, me->clientnum, "User action on none or unknown object (%s)!", ShowID(actionMsg.target));
        return;
    }

    // Resolve default behaviour
    action = actionMsg.action;
    if (action == "dfltBehavior")
    {
        action = object->GetDefaultBehavior(actionMsg.dfltBehaviors);
        if (action.IsEmpty())
        {
            return;
        }
    }

    if (action == "select" || action == "context")
    {
        if (object != NULL)
            object->SendTargetStatDR(client);
    }

    Debug4(LOG_USER,client->GetClientNum(), "User Action: %s %s %s",client->GetName(),
        (const char *)action,
        (object)?object->GetName():"None")

    object->SendBehaviorMessage(action, client->GetActor() );
}
Example #12
0
File: sycls.c Project: erluko/socat
struct hostent *Gethostbyname(const char *name) {
   struct hostent *hent;
   Debug1("gethostbyname(\"%s\")", name);
   hent = gethostbyname(name);
   if (hent == NULL) {
      Debug("gethostbyname() -> NULL");
   } else {
      Debug4("gethostbyname() -> %d.%d.%d.%d",
	     ((unsigned char *)hent->h_addr_list[0])[0],
	     ((unsigned char *)hent->h_addr_list[0])[1],
	     ((unsigned char *)hent->h_addr_list[0])[2],
	     ((unsigned char *)hent->h_addr_list[0])[3]);
   }
   return hent;
}
Example #13
0
File: sycls.c Project: erluko/socat
int Recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from,
	     socklen_t *fromlen) {
   int retval, _errno;
   char infobuff[256];
   Debug6("recvfrom(%d, %p, "F_Zu", %d, %p, "F_Zu")",
	  s, buf, len, flags, from, *fromlen);
   retval = recvfrom(s, buf, len, flags, from, fromlen);
   _errno = errno;
   if (from) {
      Debug4("recvfrom(,,,, {%d,%s}, "F_Zd") -> %d",
	     from->sa_family,
	     sockaddr_info(from, *fromlen, infobuff, sizeof(infobuff)),
	     *fromlen, retval);
   } else {
      Debug1("recvfrom(,,,, NULL, NULL) -> %d", retval);
   }
   errno = _errno;
   return retval;
}
Example #14
0
File: sycls.c Project: erluko/socat
/* we only show the first struct pollfd; hope this is enough for most cases. */
int Poll(struct pollfd *ufds, unsigned int nfds, int timeout) {
   int result;
   if (nfds == 4) {
      Debug10("poll({%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}{%d,0x%02hx,}, %u, %d)",
	      ufds[0].fd, ufds[0].events, ufds[1].fd, ufds[1].events,
	      ufds[2].fd, ufds[2].events, ufds[3].fd, ufds[3].events,
	      nfds, timeout);
   } else {
      Debug4("poll({%d,0x%02hx,}, , %u, %d)", ufds[0].fd, ufds[0].events, nfds, timeout);
   }
   result = poll(ufds, nfds, timeout);
   if (nfds == 4) {
      Debug5("poll(, {,,0x%02hx}{,,0x%02hx}{,,0x%02hx}{,,0x%02hx}) -> %d",
	     ufds[0].revents, ufds[1].revents, ufds[2].revents, ufds[3].revents, result);
   } else {
      Debug2("poll(, {,,0x%02hx}) -> %d", ufds[0].revents, result);
   }
   return result;
}
Example #15
0
File: sycls.c Project: erluko/socat
int Execvp(const char *file, char *const argv[]) {
   int result, _errno;
   if (argv[1] == NULL)
      Debug2("execvp(\"%s\", \"%s\")", file, argv[0]);
   else if (argv[2] == NULL)
      Debug3("execvp(\"%s\", \"%s\" \"%s\")", file, argv[0], argv[1]);
   else if (argv[3] == NULL)
      Debug4("execvp(\"%s\", \"%s\" \"%s\" \"%s\")", file, argv[0], argv[1], argv[2]);
   else if (argv[4] == NULL)
      Debug5("execvp(\"%s\", \"%s\" \"%s\" \"%s\" \"%s\")", file, argv[0], argv[1], argv[2], argv[3]);
   else if (argv[5] == NULL)
      Debug6("execvp(\"%s\", \"%s\" \"%s\" \"%s\" \"%s\" \"%s\")", file, argv[0], argv[1], argv[2], argv[3], argv[4]);
   else
      Debug6("execvp(\"%s\", \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" ...)", file, argv[0], argv[1], argv[2], argv[3], argv[4]);

   result = execvp(file, argv);
   _errno = errno;
   Debug1("execvp() -> %d", result);
   errno = _errno;
   return result;
}
void SpawnManager::Respawn(PID playerID, SpawnRule* spawnRule)
{
    psCharacter *chardata=psServer::CharacterLoader.LoadCharacterData(playerID,false);
    if (chardata==NULL)
    {
        Error2("Character %s to be respawned does not have character data to be loaded!\n", ShowID(playerID));
        return;
    }

    csVector3 pos;
    float angle;
    csString sectorName;
    iSector* sector = NULL;
    InstanceID instance;

    int count = 4; // For random positions we try 4 times before going with the result.

    // DetermineSpawnLoc will return true if it is a random picked position so for fixed we will fall true
    // on the first try.
    while (spawnRule->DetermineSpawnLoc(chardata, pos, angle, sectorName, instance) && spawnRule->GetMinSpawnSpacingDistance() > 0.0 && count-- > 0)
    {
        sector = psserver->entitymanager->GetEngine()->GetSectors()->FindByName(sectorName);

        csArray<gemObject*> nearlist = psserver->entitymanager->GetGEM()->FindNearbyEntities(sector, pos, spawnRule->GetMinSpawnSpacingDistance(), false);
        if (nearlist.IsEmpty())
        {
            break; // Nothing in the neare list so spawn position is ok.
        }
        Debug4(LOG_SPAWN,0,"Spawn position %s is occuplied by %zu entities. %s",
               toString(pos,sector).GetDataSafe(),
               nearlist.GetSize(),count>0?" Will Retry":"Last try");

    }

    CS_ASSERT(sector);

    Debug1(LOG_SPAWN,0,"Position accepted");
    Respawn(chardata, instance, pos, angle, sectorName);
}
Example #17
0
bool psEntity::Play(SoundControl* &ctrl, csVector3 entityPosition)
{
    EntityState* entityState;

    // checking if a sound is still playing
    if(IsPlaying())
    {
        return false;
    }

    // checking if the state is defined
    entityState = states.Get(state, 0);
    if(entityState == 0)
    {
        return false;
    }

    // picking up randomly among resources
    if(!entityState->resources.IsEmpty())
    {
        int resourceNumber = SoundManager::randomGen.Get() * entityState->resources.GetSize();

        Debug4(LOG_SOUND, 0, "psEntity::Play() %s PLAYS %s meshid: %u",entityName.GetData(),entityState->resources[resourceNumber],GetMeshID());

        if(SoundSystemManager::GetSingleton().Play3DSound(entityState->resources[resourceNumber], DONT_LOOP, 0, 0,
                entityState->volume, ctrl, entityPosition, 0, minRange, maxRange,
                VOLUME_ZERO, CS_SND3D_ABSOLUTE, handle))
        {
            when = entityState->delay;
            handle->SetCallback(this, &StopCallback);
            return true;
        }
    }

    return false;
}
void ChatManager::HandleChatMessage(MsgEntry *me, Client *client)
{
    psChatMessage msg(me);

    // Dont
    if (!msg.valid)
    {
        Debug2(LOG_NET,me->clientnum,"Received unparsable psChatMessage from client %u.\n",me->clientnum);
        return;
    }

    const char *pType = msg.GetTypeText();

    if (msg.iChatType != CHAT_TELL && msg.iChatType != CHAT_AWAY)
    {
        Debug4(LOG_CHAT, client->GetClientNum(),
                "%s %s: %s\n", client->GetName(),
                pType, msg.sText.GetData());
    }
    else
    {
        Debug5(LOG_CHAT,client->GetClientNum(), "%s %s %s: %s\n", client->GetName(),
               pType, msg.sPerson.GetData(),msg.sText.GetData());
    }

    bool saveFlood = true;

    if (!client->IsMute())
    {
      // Send Chat to other players
      switch (msg.iChatType)
      {
          case CHAT_GUILD:
          {
              SendGuild(client, msg);
              break;
          }
          case CHAT_ALLIANCE:
          {
              SendAlliance(client, msg);
              break;
          }
          case CHAT_GROUP:
          {
              SendGroup(client, msg);
              break;
           }
          case CHAT_AUCTION:
          case CHAT_SHOUT:
          {
              SendShout(client, msg);
              break;
          }
          case CHAT_CHANNEL:
          {
              csArray<uint32_t> subscribed = channelSubscriptions.GetAll(client->GetClientNum());
              bool found = false;
              for(size_t i = 0; i < subscribed.GetSize(); i++)
              {
                  if(subscribed[i] == msg.channelID)
                      found = true;
              }
              if(!found)
              {
                  psserver->SendSystemError(client->GetClientNum(), "You have not yet joined this channel.");
                  break;
              }

              // channel 1 is public
              if(msg.channelID == 1)
                  CPrintf (CON_WARNING, "Gossip %s: %s\n", client->GetName(), msg.sText.GetData());

              psChatMessage newMsg(client->GetClientNum(), client->GetActor()->GetEID(), client->GetName(), 0, msg.sText, msg.iChatType, msg.translate, msg.channelID);

              csArray<uint32_t> subscribers = channelSubscribers.GetAll(msg.channelID);
              csArray<PublishDestination> destArray;
              for (size_t i = 0; i < subscribers.GetSize(); i++)
              {
                  destArray.Push(PublishDestination(subscribers[i], NULL, 0, 0));
                  Client *target = psserver->GetConnections()->Find(subscribers[i]);
                  if (target && target->IsReady())
                      target->GetActor()->LogChatMessage(client->GetActor()->GetFirstName(), newMsg);
              }

              newMsg.Multicast(destArray, 0, PROX_LIST_ANY_RANGE );
              break;
          }
          case CHAT_PET_ACTION:
          {
              gemNPC *pet = NULL;

              // Check if a specific pet's name was specified, in one of these forms:
              // - /mypet Petname ...
              // - /mypet Petname's ...
              size_t numPets = client->GetNumPets();
              for (size_t i = 0; i < numPets; i++)
              {
                  if ((pet = dynamic_cast <gemNPC*>(client->GetPet(i)))
                      && msg.sText.StartsWith(pet->GetCharacterData()->GetCharName(), true))
                  {
                      size_t n = strlen(pet->GetCharacterData()->GetCharName());
                      if (msg.sText.Length() >= n + 1 && msg.sText.GetAt(n) == ' ')
                      {
                          msg.sText.DeleteAt(0, n);
                          msg.sText.LTrim();
                          break;
                      }
                      else if (msg.sText.Length() >= n + 3 && msg.sText.GetAt(n) == '\''
                               && msg.sText.GetAt(n + 1) == 's' && msg.sText.GetAt(n + 2) == ' ')
                      {
                          msg.sText.DeleteAt(0, n);
                          break;
                      }
                  }
                  else pet = NULL;
              }
              // If no particular pet was specified, assume the default familiar...
              if (!pet)
                  pet = dynamic_cast <gemNPC*>(client->GetFamiliar());

              // Send the message or an appropriate error...
              if (!pet)
                  psserver->SendSystemInfo(me->clientnum, "You have no familiar to command.");
              else
                  SendSay(client->GetClientNum(), pet, msg, pet->GetCharacterData()->GetCharFullName());

              break;
          }
          case CHAT_SAY:
          {
              // Send to all if there's no NPC response or the response is public
              SendSay(client->GetClientNum(), client->GetActor(), msg, client->GetName());
              break;
          }
          case CHAT_NPC:
          {
              // Only the speaker sees his successful chatting with an npc.
              // This helps quests stay secret.
              //psChatMessage newMsg(client->GetClientNum(), client->GetName(), 0,
            //    msg.sText, msg.iChatType, msg.translate);
              //newMsg.SendMessage();
              saveFlood = false;

              gemObject *target = client->GetTargetObject();
              gemNPC *targetnpc = dynamic_cast<gemNPC*>(target);
              NpcResponse *resp = CheckNPCResponse(msg,client,targetnpc);
              if (resp)
              {
                  csTicks delay = resp->ExecuteScript(client->GetActor(), targetnpc);
                  if (delay != (csTicks)-1 && resp->menu )
                      resp->menu->ShowMenu(client, delay, targetnpc);
              }
              break;
          }
          case CHAT_AWAY:
          {
              saveFlood = false; //do not check Away messages for flooding
              msg.iChatType = CHAT_TELL; //do regard it as tell message from now on
              //intentionally no break, so it falls through to CHAT_TELL
          }
          case CHAT_TELL:
          {
              if ( msg.sPerson.Length() == 0 )
              {
                  psserver->SendSystemError(client->GetClientNum(), "You must specify name of player.");
                  break;
              }

              Client *target = FindPlayerClient(msg.sPerson);
              if (target && !target->IsSuperClient())
              {
                  if (!target->IsReady())
                      psserver->SendSystemError(client->GetClientNum(), "%s is not ready yet.", msg.sPerson.GetDataSafe());
                  else
                      SendTell(msg, client->GetName(), client, target);
              }
              else
                  psserver->SendSystemError(client->GetClientNum(), "%s is not found online.", msg.sPerson.GetDataSafe());

              break;
          }
          case CHAT_REPORT:
          {
              // First thing to extract the name of the player to log
              csString targetName;
              int index = (int)msg.sText.FindFirst(' ', 0);
              targetName = (index == -1) ? msg.sText : msg.sText.Slice(0, index);
              targetName = NormalizeCharacterName(targetName);

              if ( targetName.Length() == 0 )
              {
                  psserver->SendSystemError(client->GetClientNum(), "You must specify name of player.");
                  break;
              }

              Client * target = psserver->GetConnections()->Find(targetName);
              if ( !target )
              {
                  psserver->SendSystemError(client->GetClientNum(), "%s is not found online.", targetName.GetData());
                  break;
              }
              if (target->IsSuperClient())
              {
                  psserver->SendSystemError(client->GetClientNum(), "Can't report NPCs.");
                  break;
              }

              // Add an active report to the target.
              if (target->GetActor()->AddChatReport(client->GetActor()))
              {
                  // Add report removal event.
                  psserver->GetEventManager()->Push(new psEndChatLoggingEvent(target->GetClientNum(), 300000));
                  psserver->SendSystemInfo(client->GetClientNum(), "Last 5 minutes of %s's chat were logged. Logging will continue for another 5 minutes.", targetName.GetData());
              }
              else
                  psserver->SendSystemError(client->GetClientNum(), "Could not start logging %s, due to a server error.", targetName.GetData());
              break;
         }
         case CHAT_ADVISOR:
         case CHAT_ADVICE:
             break;

         default:
         {
              Error2("Unknown Chat Type: %d\n",msg.iChatType);
              break;
         }
       }
    }
    else
    {
        //User is muted but tries to chat anyway. Remind the user that he/she/it is muted
        psserver->SendSystemInfo(client->GetClientNum(),"You can't send messages because you are muted.");
    }

    if (saveFlood)
        client->FloodControl(msg.iChatType, msg.sText, msg.sPerson);
}
Example #19
0
bool psEntity::DefineState(csRef<iDocumentNode> stateNode)
{

    int stateID;

    EntityState* entityState;
    csRef<iDocumentNodeIterator> resourceItr;

    // checking if the state ID is legal
    stateID = stateNode->GetAttributeValueAsInt("ID", -1);
    Debug4(LOG_SOUND, 0, "psEntity::DefineState %s state %d meshid %u",entityName.GetData(),stateID,id);
    if(stateID < 0)
    {
        return false;
    }

    // initializing the EntityState
    entityState = states.Get(stateID, 0);

    if(entityState != 0) // already defined
    {
        return false;
    }

    entityState = new EntityState();

    // initializing resources
    resourceItr = stateNode->GetNodes("RESOURCE");
    while(resourceItr->HasNext())
    {
        const char* resourceName = resourceItr->Next()->GetAttributeValue("NAME", 0);
        if(resourceName == 0)
        {
            continue;
        }
        entityState->resources.PushSmart(resourceName);
    }

    // checking if there is at least one resource
    if(entityState->resources.IsEmpty())
    {
        delete entityState;
        return false;
    }

    // setting all the other parameters
    entityState->probability = stateNode->GetAttributeValueAsFloat("PROBABILITY", 1.0);
    entityState->volume = stateNode->GetAttributeValueAsFloat("VOLUME", VOLUME_NORM);
    entityState->delay = stateNode->GetAttributeValueAsInt("DELAY", 0);
    entityState->timeOfDayStart = stateNode->GetAttributeValueAsInt("TIME_START", 0);
    entityState->timeOfDayEnd = stateNode->GetAttributeValueAsInt("TIME_END", 24);
    entityState->fallbackState = stateNode->GetAttributeValueAsInt("FALLBACK_STATE", UNDEFINED_ENTITY_STATE);
    entityState->fallbackProbability = stateNode->GetAttributeValueAsFloat("FALLBACK_PROBABILITY", 0.0);
    entityState->references = 1;

    // adjusting the probabilities on the update time
    if(entityState->probability < 1.0)
    {
        entityState->probability *= SoundManager::updateTime / 1000.0;
    }
    if(entityState->fallbackProbability < 1.0)
    {
        entityState->fallbackProbability *= SoundManager::updateTime / 1000.0;
    }

    // in XML delay is given in seconds, converting delay into milliseconds
    entityState->delay = entityState->delay * 1000;

    states.Put(stateID, entityState);

    return true;
}
Example #20
0
bool NetBase::CheckIn()
{    
    // check for incoming packets
    SOCKADDR_IN addr;
    memset (&addr, 0, sizeof(SOCKADDR_IN));
    socklen_t len = sizeof(SOCKADDR_IN);

    if (!input_buffer)
    {
        input_buffer = (char*) cs_malloc(MAXPACKETSIZE);

        if (!input_buffer)
        {
            Error2("Failed to cs_malloc %d bytes for packet buffer!\n",MAXPACKETSIZE);
            return false;
        }
    }

    // Connection must be initialized!
    CS_ASSERT(ready);
    
    int packetlen = RecvFrom (&addr, &len, (void*) input_buffer, MAXPACKETSIZE);

    if (packetlen <= 0)
    {
        return false;
    }
    // Identify the connection
    Connection* connection = GetConnByIP(&addr);

    // Extract the netpacket from the buffer and prep for use locally.
    psNetPacket *bufpacket = psNetPacket::NetPacketFromBuffer(input_buffer,packetlen);
    if (bufpacket==NULL)
    {
        char addrText[INET_ADDRSTRLEN];

        //for win32 for now only inet_ntoa as inet_ntop wasn't supported till vista.
        //it has the same degree of compatibility of the previous code and it's supported till win2000
        #ifdef WIN32
        strncpy(addrText, inet_ntoa(addr.sin_addr), INET_ADDRSTRLEN);
        #else
        //there was a failure in conversion if null
        if(!inet_ntop(addr.sin_family,&addr.sin_addr, addrText, sizeof(addrText)))
        {
            strncpy(addrText, "UNKNOWN", INET_ADDRSTRLEN);
        }
        #endif

        // The data received was too small to make a full packet.
        if (connection)
        {
            Debug4(LOG_NET, connection->clientnum, "Too short packet received from client %d (IP: %s) (%d bytes)", connection->clientnum, addrText, packetlen);
        }
        else
        {
            Debug3(LOG_NET, 0, "Too short packet received from IP address %s. (%d bytes) No existing connection from this IP.",
                addrText, packetlen);
        }
        return true; // Continue processing more packets if available
    }
    input_buffer = NULL; //input_buffer now hold by the bufpacket pointer.

    // Endian correction
    bufpacket->UnmarshallEndian();

    // Check for too-big packets - no harm in processing them, but probably a bug somewhere
    if (bufpacket->GetPacketSize() < static_cast<unsigned int>(packetlen))
    {
        char addrText[INET_ADDRSTRLEN];

        //for win32 for now only inet_ntoa as inet_ntop wasn't supported till vista.
        //it has the same degree of compatibility of the previous code and it's supported till win2000
        #ifdef WIN32
        strncpy(addrText, inet_ntoa(addr.sin_addr), INET_ADDRSTRLEN);
        #else
        //there was a failure in conversion if null
        if(!inet_ntop(addr.sin_family,&addr.sin_addr, addrText, sizeof(addrText)))
        {
            strncpy(addrText, "UNKNOWN", INET_ADDRSTRLEN);
        }
        #endif
        
        if (connection)
        {
            Debug5(LOG_NET, connection->clientnum, "Too long packet received from client %d (IP: %s) (%d bytes received, header reports %zu bytes)",
                connection->clientnum, addrText, packetlen, bufpacket->GetPacketSize());
        }
        else
        {
            
            Debug4(LOG_NET, 0,"Too long packet received from IP address %s. (%d bytes received, header reports %zu bytes) No existing connection from this IP.",
                   addrText, packetlen, bufpacket->GetPacketSize());
        }
    }

    //Create new net packet entry and transfer ownership of bufpacket to pkt.
    csRef<psNetPacketEntry> pkt;
    pkt.AttachNew(new psNetPacketEntry( bufpacket, 
            connection ? connection->clientnum : 0, packetlen));
    
    if(TEST_PACKETLOSS > 0.0 && randomgen->Get() < TEST_PACKETLOSS)
    {
        psNetPacket* packet = pkt->packet;
        int type = 0;

        if (packet->offset == 0) 
        {
            psMessageBytes* msg = (psMessageBytes*) packet->data;
            type = msg->type;
        }

        Error3("Packet simulated lost. Type %s ID %d.\n", type == 0 ? "Fragment" : (const char *)  GetMsgTypeName(type), pkt->packet->pktid);
        return true;
    }

    // ACK packets can get eaten by HandleAck
    if (HandleAck(pkt, connection, &addr))
    {
        return true;
    }

    // printf("Got packet with sequence %d.\n", pkt->packet->GetSequence());
    //
    // Check for doubled packets and drop them
    if (pkt->packet->pktid != 0)
    {
        if (connection && CheckDoublePackets (connection, pkt))
        {
#ifdef PACKETDEBUG
            Debug2(LOG_NET,0,"Dropping doubled packet (ID %d)\n", pkt->packet->pktid);
#endif
            return true;
        }
    }
    
#ifdef PACKETDEBUG
    Debug7(LOG_NET,0,"Received Pkt, ID: %d, offset %d, from %d size %d (actual %d) flags %d\n", 
        pkt->packet->pktid, pkt->packet->offset, pkt->clientnum, pkt->packet->pktsize,packetlen, pkt->packet->flags);
#endif

    /**
    * Now either send this packet to BuildMessage, or loop through
    * subpackets if they are merged.
    */
    csRef<psNetPacketEntry> splitpacket = pkt;
    psNetPacket      *packetdata = NULL;

    do
    {
        splitpacket = pkt->GetNextPacket(packetdata);
        if (splitpacket)
            BuildMessage(splitpacket, connection, &addr);
    } while (packetdata);
    return true;
}
bool PaladinJr::SpeedCheck(Client* client, gemActor* actor, psDRMessage& currUpdate)
{
    csVector3 oldpos;
    // Dummy variables
    float yrot;
    iSector* sector;
    psWorld * world = entitymanager->GetWorld();
    int violation = NOVIOLATION;

    actor->pcmove->GetLastClientPosition (oldpos, yrot, sector);
    
    // If no previous observations then we have nothing to check against.
    if (!sector)
        return true;

    // define cheating variables
    float dist;
    float reported_distance;
    float max_noncheat_distance;
    float lag_distance;
    csTicks timedelta;
    csVector3 vel;

    // check for warpviolation
    if (sector != currUpdate.sector && !world->WarpSpace(sector, currUpdate.sector, oldpos))
    {
        if (checks & WARPVIOLATION)
        {
            violation = WARPVIOLATION;
        }
        else
        {
            // we don't do warp checking and crossed a sector
            // skip this round
            return true;
        }
    }

    if (checks & SPEEDVIOLATION)
    {
        // we don't use the absolute value of the vertical
        // speed in order to let falls go through
        if (fabs(currUpdate.vel.x) <= maxVelocity.x &&
                 currUpdate.vel.y  <= maxVelocity.y &&
            fabs(currUpdate.vel.z) <= maxVelocity.z)
        {
            violation |= SPEEDVIOLATION;
        }
    }

    // distance check is skipped on warp violation as it would be wrong
    if (checks & DISTVIOLATION && !(violation & WARPVIOLATION))
    {
        dist = (currUpdate.pos-oldpos).Norm();
        timedelta = actor->pcmove->ClientTimeDiff();

        // We use the last reported vel, not the new vel, to calculate how far he should have gone since the last DR update
        vel = actor->pcmove->GetVelocity();
        vel.y = 0; // ignore vertical velocity
        reported_distance = vel.Norm()*timedelta/1000;

        Debug4(LOG_CHEAT, client->GetClientNum(),"Player went %1.3fm in %u ticks when %1.3fm was allowed.\n",dist, timedelta, reported_distance);

        max_noncheat_distance = maxSpeed*timedelta/1000;
        lag_distance          = maxSpeed*client->accumulatedLag/1000;

        if (dist < max_noncheat_distance + lag_distance)
        {
            if(dist == 0)
            {
                // player is stationary - reset accumulated lag
                NetBase::Connection * connection = client->GetConnection();
                client->accumulatedLag = connection->estRTT + connection->devRTT;
            }
            else if(fabs(dist-reported_distance) < dist/20)
            {
                // ignore jitter caused differences
                Debug1(LOG_CHEAT, client->GetClientNum(),"Ignoring lag jitter.");
            }
            else
            {
                // adjust accumulated lag
                float lag = (reported_distance - dist) * 1000.f/maxSpeed + client->accumulatedLag;

                // cap to meaningful values
                lag = lag < 0 ? 0 : lag > MAX_ACCUMULATED_LAG ? MAX_ACCUMULATED_LAG : lag;

                client->accumulatedLag = (csTicks)lag;

                Debug2(LOG_CHEAT, client->GetClientNum(),"Accumulated lag: %u\n",client->accumulatedLag);
            }
        }
        else
        {
            violation |= DISTVIOLATION;
        }
    }

    if (violation != NOVIOLATION)
    {
        if (client->GetCheatMask(MOVE_CHEAT))
        {
            //printf("Server has pre-authorized this apparent speed violation.\n");
            client->SetCheatMask(MOVE_CHEAT, false);  // now clear the Get Out of Jail Free card
            return true;  // not cheating
        }

        Debug6(LOG_CHEAT, client->GetClientNum(),"Went %1.2f in %u ticks when %1.2f was expected plus %1.2f allowed lag distance (%1.2f)\n", dist, timedelta, max_noncheat_distance, lag_distance, max_noncheat_distance+lag_distance);
        //printf("Z Vel is %1.2f\n", currUpdate.vel.z);
        //printf("MaxSpeed is %1.2f\n", maxSpeed);

        // Report cheater
        csVector3 angVel;
        csString buf;
        csString type;
        csString sectorName(sector->QueryObject()->GetName());

        // Player has probably been warped
        if (violation & WARPVIOLATION)
        {
            sectorName.Append(" to ");
            sectorName.Append(currUpdate.sectorName);
            type = "Warp Violation";
        }

        if (violation & SPEEDVIOLATION)
        {
            if(!type.IsEmpty())
                type += "|";
            type += "Speed Violation (Hack confirmed)";
        }

        if (violation & DISTVIOLATION)
        {
            if(!type.IsEmpty())
                type += "|";
            type += "Distance Violation";
        }

        if (enforcing)
        {
            actor->ForcePositionUpdate();
        }
        
        actor->pcmove->GetAngularVelocity(angVel);
        buf.Format("%s, %s, %s, %.3f %.3f %.3f, %.3f 0 %.3f, %.3f %.3f %.3f, %.3f %.3f %.3f, %.3f %.3f %.3f, %s\n",
                   client->GetName(), type.GetData(), sectorName.GetData(),oldpos.x, oldpos.y, oldpos.z,
                   max_noncheat_distance, max_noncheat_distance, 
                   currUpdate.pos.x - oldpos.x, currUpdate.pos.y - oldpos.y, currUpdate.pos.z - oldpos.z,
                   vel.x, vel.y, vel.z, angVel.x, angVel.y, angVel.z, PALADIN_VERSION);

        psserver->GetLogCSV()->Write(CSV_PALADIN, buf);

        Debug5(LOG_CHEAT, client->GetClientNum(),"Player %s traversed %1.2fm in %u msec with an accumulated lag allowance of %u ms. Cheat detected!\n",
            client->GetName (),dist,timedelta,client->accumulatedLag);

        client->CountDetectedCheat();
        //printf("Client has %d detected cheats now.\n", client->GetDetectedCheatCount());
        if (client->GetDetectedCheatCount() % warnCount == 0)
        {
            psserver->SendSystemError(client->GetClientNum(),"You have been flagged as using speed hacks.  You will be disconnected if you continue.");
        }
        if (client->GetDetectedCheatCount() >= maxCount)
        {
            //printf("Disconnecting a cheating client.\n");
            psserver->RemovePlayer(client->GetClientNum(),"Paladin has kicked you from the server for cheating.");
            return false;
        }

        return !enforcing;
    }
    else
    {
        return true;
    }
}
Example #22
0
int main(int argc, const char *argv[]) {
   const char **arg1, *a;
   char *mainwaitstring;
   char buff[10];
   double rto;
   int i, argc0, result;
   struct utsname ubuf;
   int lockrc;

   if (mainwaitstring = getenv("SOCAT_MAIN_WAIT")) {
       sleep(atoi(mainwaitstring));
   }
   diag_set('p', strchr(argv[0], '/') ? strrchr(argv[0], '/')+1 : argv[0]);

   /* we must init before applying options because env settings have lower
      priority and are to be overridden by options */
   if (xioinitialize(XIO_MAYALL) != 0) {
      Exit(1);
   }

   xiosetopt('p', "%");
   xiosetopt('o', ":");

   argc0 = argc;	/* save for later use */
   arg1 = argv+1;  --argc;
   while (arg1[0] && (arg1[0][0] == '-')) {
      switch (arg1[0][1]) {
      case 'V': socat_version(stdout); Exit(0);
#if WITH_HELP
      case '?':
      case 'h':
	 socat_usage(stdout);
	 xioopenhelp(stdout, (arg1[0][2]=='?'||arg1[0][2]=='h') ? (arg1[0][3]=='?'||arg1[0][3]=='h') ? 2 : 1 : 0);
	 Exit(0);
#endif /* WITH_HELP */
      case 'd': diag_set('d', NULL); break;
#if WITH_FILAN
      case 'D': xioparams->debug = true; break;
#endif
      case 'l':
	 switch (arg1[0][2]) {
	 case 'm': /* mixed mode: stderr, then switch to syslog; + facility */
	    diag_set('s', NULL);
	    xiosetopt('l', "m");
	    xioparams->logopt = arg1[0][2];
	    xiosetopt('y', &arg1[0][3]);
	    break;
	 case 'y': /* syslog + facility */
	    diag_set(arg1[0][2], &arg1[0][3]);
	    break;
	 case 'f': /* to file, +filename */
	 case 'p': /* artificial program name */
	    if (arg1[0][3]) {
	       diag_set(arg1[0][2], &arg1[0][3]);
	    } else if (arg1[1]) {
	       diag_set(arg1[0][2], arg1[1]);
	       ++arg1, --argc;
	    } else {
	       Error1("option -l%c requires an argument; use option \"-h\" for help", arg1[0][2]);
	    }
	    break;
	 case 's': /* stderr */
	    diag_set(arg1[0][2], NULL);
	    break;
	 case 'u':
	    diag_set('u', NULL);
	    break;
	 case 'h':
	    diag_set_int('h', true);
	    break;
	 default:
	    Error1("unknown log option \"%s\"; use option \"-h\" for help", arg1[0]);
	    break;
	 }
	 break;
      case 'v': xioparams->verbose = true; break;
      case 'x': xioparams->verbhex = true; break;
      case 'b': if (arg1[0][2]) {
	    a = *arg1+2;
	 } else {
	    ++arg1, --argc;
	    if ((a = *arg1) == NULL) {
	       Error("option -b requires an argument; use option \"-h\" for help");
	       Exit(1);
	    }
	 }
	 xioparams->bufsiz = strtoul(a, (char **)&a, 0);
	 break;
      case 's':
	 diag_set_int('e', E_FATAL); break;
      case 't': if (arg1[0][2]) {
	    a = *arg1+2;
	 } else {
	    ++arg1, --argc;
	    if ((a = *arg1) == NULL) {
	       Error("option -t requires an argument; use option \"-h\" for help");
	       Exit(1);
	    }
	 }
	 rto = strtod(a, (char **)&a);
	 xioparams->closwait.tv_sec = rto;
	 xioparams->closwait.tv_usec =
	    (rto-xioparams->closwait.tv_sec) * 1000000; 
	 break;
      case 'T':  if (arg1[0][2]) {
	    a = *arg1+2;
	 } else {
	    ++arg1, --argc;
	    if ((a = *arg1) == NULL) {
	       Error("option -T requires an argument; use option \"-h\" for help");
	       Exit(1);
	    }
	 }
	 rto = strtod(a, (char **)&a);
	 xioparams->total_timeout.tv_sec = rto;
	 xioparams->total_timeout.tv_usec =
	    (rto-xioparams->total_timeout.tv_sec) * 1000000; 
	 break;
      case 'u': xioparams->lefttoright = true; break;
      case 'U': xioparams->righttoleft = true; break;
      case 'g': xioopts_ignoregroups = true; break;
      case 'L': if (socat_opts.lock.lockfile)
	     Error("only one -L and -W option allowed");
	 if (arg1[0][2]) {
	    socat_opts.lock.lockfile = *arg1+2;
	 } else {
	    ++arg1, --argc;
	    if ((socat_opts.lock.lockfile = *arg1) == NULL) {
	       Error("option -L requires an argument; use option \"-h\" for help");
	       Exit(1);
	    }
	 }
	 break;
      case 'W': if (socat_opts.lock.lockfile)
	    Error("only one -L and -W option allowed");
	 if (arg1[0][2]) {
	    socat_opts.lock.lockfile = *arg1+2;
	 } else {
	    ++arg1, --argc;
	    if ((socat_opts.lock.lockfile = *arg1) == NULL) {
	       Error("option -W requires an argument; use option \"-h\" for help");
	       Exit(1);
	    }
	 }
	 socat_opts.lock.waitlock = true;
	 socat_opts.lock.intervall.tv_sec  = 1;
	 socat_opts.lock.intervall.tv_nsec = 0;
	 break;
#if WITH_IP4 || WITH_IP6
#if WITH_IP4
      case '4':
#endif
#if WITH_IP6
      case '6':
#endif
	 xioopts.default_ip = arg1[0][1];
	 xioopts.preferred_ip = arg1[0][1];
	 break;
#endif /* WITH_IP4 || WITH_IP6 */
      case 'c':
	 switch (arg1[0][2]) {
	 case 'S': xioparams->pipetype = XIOCOMM_SOCKETPAIRS; break;
	 case 'P':
	 case 'p': xioparams->pipetype = XIOCOMM_PIPES;       break;
	 case 's': xioparams->pipetype = XIOCOMM_SOCKETPAIR;  break;
	 case 'Y': xioparams->pipetype = XIOCOMM_PTYS;        break;
	 case 'y': xioparams->pipetype = XIOCOMM_PTY;         break;
	 case 't': xioparams->pipetype = XIOCOMM_TCP;         break;
	 case '0': case '1': case '2': case '3': case '4':
	 case '5': case '6': case '7': case '8': case '9':
	    xioparams->pipetype = atoi(&arg1[0][2]); break;
	 default: Error1("bad chain communication type \"%s\"", &arg1[0][2]);
	 }
	 break;
      case '\0':
      case '-':	/*! this is hardcoded "--" */
      case ',':
      case ':': break;	/* this "-" is a variation of STDIO or -- */
      default:
	 xioinqopt('p', buff, sizeof(buff));
	 if (arg1[0][1] == buff[0]) {
	    break;
	 }
	 Error1("unknown option \"%s\"; use option \"-h\" for help", arg1[0]);
	 Exit(1);
      }
      /* the leading "-" might be a form of the first address */
      xioinqopt('p', buff, sizeof(buff));
      if (arg1[0][0] == '-' &&
	  (arg1[0][1] == '\0' || arg1[0][1] == ':' ||
	   arg1[0][1] == ',' || arg1[0][1] == '-'/*!*/ ||
	   arg1[0][1] == buff[0]))
	 break;
      ++arg1; --argc;
   }
#if 0
   Info1("%d address arguments", argc);
#else
   if (argc != 2) {
      Error1("exactly 2 addresses required (there are %d); use option \"-h\" for help", argc);
      Exit(1);
   }
#endif
   if (xioparams->lefttoright && xioparams->righttoleft) {
      Error("-U and -u must not be combined");
   }

   xioinitialize2();
   Info(copyright_socat);
#if WITH_OPENSSL
   Info(copyright_openssl);
   Info(copyright_ssleay);
#endif
   Debug2("socat version %s on %s", socatversion, timestamp);
   xiosetenv("VERSION", socatversion, 1);	/* SOCAT_VERSION */
   uname(&ubuf);	/* ! here we circumvent internal tracing (Uname) */
   Debug4("running on %s version %s, release %s, machine %s\n",
	   ubuf.sysname, ubuf.version, ubuf.release, ubuf.machine);

#if WITH_MSGLEVEL <= E_DEBUG
   for (i = 0; i < argc0; ++i) {
      Debug2("argv[%d]: \"%s\"", i, argv[i]);
   }
#endif /* WITH_MSGLEVEL <= E_DEBUG */

   /* not sure what signal should print a message */
   Signal(SIGHUP, socat_signal);
   Signal(SIGINT, socat_signal);
   Signal(SIGQUIT, socat_signal);
   Signal(SIGILL, socat_signal);
   /* SIGABRT for assert; catching caused endless recursion on assert in libc
      (tzfile.c:498: __tzfile_compute: Assertion 'num_types == 1' failed.) */
   /*Signal(SIGABRT, socat_signal);*/
   Signal(SIGBUS, socat_signal);
   Signal(SIGFPE, socat_signal);
   Signal(SIGSEGV, socat_signal);
   Signal(SIGTERM, socat_signal);
#if HAVE_SIGACTION
   {
      struct sigaction act;
      memset(&act, 0, sizeof(struct sigaction));
      act.sa_flags   = SA_NOCLDSTOP|SA_RESTART|SA_SIGINFO
#ifdef SA_NOMASK
	 |SA_NOMASK
#endif
	 ;
      act.sa_sigaction = xiosigaction_subaddr_ok;
      if (Sigaction(SIGUSR1, &act, NULL) < 0) {
	 /*! Linux man does not explicitely say that errno is defined */
	 Warn1("sigaction(SIGUSR1, {&xiosigaction_subaddr_ok}, NULL): %s", strerror(errno));
      }
   }
#else /* !HAVE_SIGACTION */
   if (Signal(SIGUSR1, xiosigaction_subaddr_ok) == SIG_ERR) {
      Warn1("signal(SIGCHLD, xiosigaction_subaddr_ok): %s", strerror(errno));
   }
#endif /* !HAVE_SIGACTION */

   /* set xio hooks */
   xiohook_newchild = &socat_newchild;

   if (lockrc = socat_lock()) {
      /* =0: goon; >0: locked; <0: error, printed in sub */
      if (lockrc > 0)
	 Error1("could not obtain lock \"%s\"", socat_opts.lock.lockfile);
      Exit(1);
   }

   Atexit(socat_unlock);

   result = socat(argc, arg1[0], arg1[1]);
   Notice1("exiting with status %d", result);
   Exit(result);
   return 0;	/* not reached, just for gcc -Wall */
}