Example #1
0
File: socket.c Project: maxott/oml
/* Connect to remote addr.
 *  If addr is NULL, assume the servAddr is already populated
 */
static int
s_connect(
  SocketInt* self,
  char* addr,
  int port
) {
  if (addr != NULL) {
    struct hostent *server;

    server = gethostbyname(addr);
    if (server == NULL) {
      o_log(O_LOG_ERROR, "socket:%s: Unknown host %s\n", self->name, addr);
      return 0;
    }

    self->servAddr.sin_family = PF_INET;
    self->servAddr.sin_port = htons(port);
    bcopy((char *)server->h_addr,
      (char *)&self->servAddr.sin_addr.s_addr,
      server->h_length);
  }
  if (connect(self->sockfd, (struct sockaddr *)&self->servAddr,
          sizeof(struct sockaddr_in)) < 0) {
    if (errno != EINPROGRESS) {
      o_log(O_LOG_ERROR, "socket:%s: Error connecting to %s:%d: %s\n",
        self->name, addr, port, strerror(errno));
      return 0;
    }
  }
  return 1;
}
Example #2
0
// Create a new session
// FIXME - This is currently open to a DoS attack.
//         but since we have a session limit, just for opendias.
char *create_session() {
  char *session_id;

  // Check upper session count limit
  int current_session_count = sll_count( sll_findFirstElement( sessions ) );
  o_log( DEBUGM, "There are currently %d active sessions", current_session_count);
  if( current_session_count > MAX_SESSIONS ) {
    return NULL;
  }

  // Generate session key
  uuid_t uu;
  char *sid = malloc(36+1);
  uuid_generate(uu);
  uuid_unparse(uu, sid);
  session_id = o_strdup(sid);
  free(sid);
  o_log(DEBUGM, "Generated new session: %s", session_id );

  // Create new session structure
  struct session_data *session_element = malloc( sizeof(struct session_data) );
  session_element->last_accessed = time(NULL);
  session_element->session_container = sll_init();

  // Save and return
  sll_insert( sessions, o_strdup(session_id), session_element );
  return session_id;
}
Example #3
0
extern char *getTagId(char *tagname) {

  struct simpleLinkedList *vars, *rSet;
  char *sql2, *ret = NULL;
  char *sql = o_printf("SELECT tagid FROM tags WHERE tagname = '%s'", tagname);

  rSet = runquery_db(sql);
  if( rSet != NULL ) {
    ret = o_strdup(readData_db(rSet, "tagid"));
  }
  else {
    o_log(DEBUGM, "no tag was found. Adding a new one.");
    sql2 = o_strdup("INSERT INTO tags (tagname) VALUES (?)");

    vars = sll_init();
    sll_append(vars, DB_TEXT );
    sll_append(vars, tagname );

    runUpdate_db(sql2, vars);
    free(sql2);

    ret = itoa(last_insert(), 10);
  }
  free_recordset( rSet );
  free(sql);

  o_log(DEBUGM, "Using tagid of %s", ret);
  return ret;
}
Example #4
0
int main (int argc, char **argv) {

  BASE_DIR = argv[1];
  LOG_DIR = argv[2];
  VERBOSITY = atoi(argv[3]);

  char *command = argv[4];
  char *param = argv[5];

  // Setup
  char *db = o_printf("%s/openDIAS.sqlite3", BASE_DIR);
  o_log(DEBUGM,"database file is %s",db);
  if(open_db (db)) {
    o_log(ERROR, "Could not connect to the database.");
    free(db);
    exit(EXIT_FAILURE);
  }
  free(db);
  locale_init( "en" );

  // Let's do the work
  o_log( INFORMATION, "Worker started and ready to process: %s", command);
  sane_worker( command, param );

  // Finish up now
  close_all();
  exit(EXIT_SUCCESS);
}
Example #5
0
/** Get the peer address of an OSocket.
 *
 * \param s OSocket
 * \param addr memory buffer to return the string in (nil-terminated)
 * \param namelen length of name, using socket_get_addr_sz() is a good idea
 *
 * \see sockaddr_get_name, getsockname(3), socket_get_addr_sz
 */
void
socket_get_peer_addr(Socket *s, char *addr, size_t addr_sz)
{
  int ret;
  sockaddr_t sa;
  socklen_t sa_len = sizeof(sa);
  SocketInt *self = (SocketInt*)s;

  assert(self);
  assert(self->sockfd>=0);
  assert(addr);
  assert(socket_get_addr_sz(s) <= addr_sz);

  memset(&sa, 0, sa_len);

  if(getpeername(self->sockfd, &sa.sa, &sa_len)) {
    o_log(O_LOG_WARN, "%s: Error getting peer address: %s\n",
        self->name, strerror(errno));
    snprintf(addr, addr_sz, "Unknown peer");

  } else if ((ret=getnameinfo(&sa.sa, sa_len, addr, addr_sz, NULL, 0, NI_NUMERICHOST))) {
    o_log(O_LOG_WARN, "%s: Error converting peer address to name: %s\n",
        self->name, gai_strerror(ret));
    snprintf(addr, addr_sz, "Unknown address (AF%d)", sa.sa.sa_family);
  }
}
Example #6
0
File: socket.c Project: maxott/oml
Socket*
socket_mc_in_new(
  char* name,   //! Name used for debugging
  char* addr,   //! IP address of the multicast socket/channel.
  int port, //! Port used
  char* iface //! Name of the interface (eth0/eth1) to bind to
) {
  SocketInt* self;
  if ((self = (SocketInt*)socket_in_new(name, port, FALSE)) == NULL)
    return NULL;

  //  self->addr = addr;
  //self->localport = port;
  self->iface = iface;

  // JOIN multicast group on default interface
  self->imreq.imr_multiaddr.s_addr = inet_addr(addr);
  self->imreq.imr_interface.s_addr = iface2addr(name, iface);

  if (setsockopt(self->sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
         (const void *)&(self->imreq),
         sizeof(struct ip_mreq)) < 0) {
    o_log(O_LOG_ERROR, "socket:%s: Error while joining a multicast group\n", name);
    return NULL;
  }
  o_log(O_LOG_DEBUG, "socket:%s: Ready to receive data on multicast address: %s\n",
    name, addr);
  return (Socket*)self;
}
Example #7
0
/** Terminate sources.
 *
 * Close listening Sockets and shutdown() others
 *
 * XXX: This function is not very efficient (going through the linked list of
 * channels and repeatedly calling functions which do the same), but it's only
 * used for cleanup, so it should be fine.
 *
 * \see eventloop_stop
 */
static void terminate_fds(void)
{
  Channel *ch = self.channels, *next;

  while (ch != NULL) {
    next = ch->next;
    o_log(O_LOG_DEBUG4, "EventLoop: Terminating channel %s\n", ch->name);
    if (!ch->is_active ||
        socket_is_disconnected(ch->socket) ||
        socket_is_listening(ch->socket)) {
      o_log(O_LOG_DEBUG3, "EventLoop: Releasing listening channel %s\n", ch->name);
      eventloop_socket_release((SockEvtSource*)ch);
    } else if (self.force_stop) {
      o_log(O_LOG_DEBUG3, "EventLoop: Closing down %s\n", ch->name);
      eventloop_socket_release((SockEvtSource*)ch);
      socket_close(ch->socket);
    } else {
      o_log(O_LOG_DEBUG3, "EventLoop: Shutting down %s\n", ch->name);
      socket_shutdown(ch->socket);
      ch->is_shutting_down = 1;
    }
    ch = next;
  }

  update_fds();
}
Example #8
0
void ocrImage( char *uuid, int docid, int page, int request_resolution, PIX *pix, char *lang ) {
  char *ocrText;
  char *ocrLang;

  ocrLang = getScanParam(uuid, SCAN_PARAM_DO_OCR);
#ifdef CAN_OCR
  if(ocrLang && 0 != strcmp(ocrLang, "-") ) {

    if(request_resolution >= 300 && request_resolution <= 400) {
      char *ocrScanText;

      o_log(INFORMATION, "Attempting OCR in lang of %s", ocrLang);
      updateScanProgress(uuid, SCAN_PERFORMING_OCR, 10);

      ocrScanText = getTextFromImage(pix, request_resolution, ocrLang);

      ocrText = o_printf( getString("LOCAL_page_delimiter", lang), page, ocrScanText);
      free(ocrScanText);
    }
    else {
      o_log(DEBUGM, "OCR was requested, but the specified resolution means it's not safe to be attempted");
      ocrText = o_printf( getString("LOCAL_resolution_outside_range_to_attempt_ocr", lang) );
    }
  }
  else
#endif /* CAN_OCR */
    ocrText = o_strdup("");
  free(ocrLang);

  updateScanProgress(uuid, SCAN_DB_WORKING, 0);
  updateNewScannedPage(docid, ocrText, page);
  free(ocrText);

}
Example #9
0
/** Execute the status-change callback of a channel, if defined.
 *
 * Otherwise, a default behaviour is implemented, cleaning up ch->socket on
 * SOCKET_CONN_CLOSED, SOCKET_CONN_REFUSED SOCKET_DROPPED and SOCKET_IDLE.
 *
 * \param ch Channel which just changed state
 * \param status SocketStatus new status for the socket
 * \param error errno related to that status
 *
 * \see o_el_state_socket_callback, SocketStatus
 */
static void do_status_callback (Channel *ch, SocketStatus status, int error)
{
  if (ch->status_cbk && !ch->is_removable) {
    ch->status_cbk ((SockEvtSource*)ch, status, error, ch->handle);

  } else if (!ch->status_cbk) {
    o_log(O_LOG_DEBUG, "EventLoop: Channel '%s' has changed state but no defined callback\n",  ch->name);

    switch(status) {
    case SOCKET_WRITEABLE:
      break;
    case SOCKET_CONN_CLOSED:
    case SOCKET_CONN_REFUSED:
    case SOCKET_DROPPED:
    case SOCKET_IDLE:
      o_log(O_LOG_DEBUG, "EventLoop: Closing socket '%s' due to status %d\n", ch->name, status);
      eventloop_socket_release((SockEvtSource*)ch);
      break;
    case SOCKET_UNKNOWN:
    default:
      o_log(O_LOG_WARN, "EventLoop: Unexpected status on socket '%s': %d\n", ch->name, status);
      break;
    }
  }
}
Example #10
0
/* load a file into a buffer */
size_t load_file_to_memory(const char *p_filename, char **result) {

    size_t size = 0;
    FILE *p_f = fopen(p_filename, "r");

    if (p_f == NULL) {
        *result = NULL;
        o_log(ERROR, "Could not open file: %s", p_filename);
        return (size_t)0; // means file opening fail
    }

    fseek(p_f, 0, SEEK_END);
    size = (size_t)ftell(p_f);
    fseek(p_f, 0, SEEK_SET);

    if((*result = (char *)malloc(size+1)) == NULL) {
        o_log(ERROR, "Out of memory while reading file information");
        fclose(p_f);
        return (size_t)0;
    }

    if (size != fread(*result, sizeof(char), size, p_f)) {
        free(*result);
        o_log(ERROR, "Error reading from file");
        fclose(p_f);
        return (size_t)0; // means file reading fail
    }

    fclose(p_f);
    (*result)[size] = 0;
    return size;

}
Example #11
0
File: socket.c Project: maxott/oml
int
socket_sendto(
  Socket* socket,
  char* buf,
  int buf_size
) {
  SocketInt *self = (SocketInt*)socket;
  int sent;

  // TODO: Catch SIGPIPE signal if other side is half broken
  if ((sent = sendto(self->sockfd, buf, buf_size, 0,
                    (struct sockaddr *)&(self->servAddr),
                    sizeof(self->servAddr))) < 0) {
    if (errno == EPIPE || errno == ECONNRESET) {
      // The other end closed the connection.
      self->is_disconnected = 1;
      o_log(O_LOG_ERROR, "socket:%s: The remote peer closed the connection: %s\n",
            self->name, strerror(errno));
    } else if (errno == EINTR) {
      o_log(O_LOG_WARN, "socket:%s: Sending data interrupted: %s\n",
            self->name, strerror(errno));
      return 0;
    } else {
      o_log(O_LOG_ERROR, "socket(%s): Sending data failed: %s\n",
            self->name, strerror(errno));
    }
    return -1;
  }
  return sent;
}
Example #12
0
File: socket.c Project: maxott/oml
/** Create an IP Socket object bound to ADDR and PORT.
 *
 * This function binds the newly-created socket, but doesn't listen on it just yet.
 *
 * \param name name of the object, used for debugging
 * \param port port used
 * \param is_tcp true if TCP, false for UDP XXX: This should be more generic
 * \return a pointer to the SocketInt object, cast as a Socket
 */
Socket*
socket_in_new(
  char* name,
  int port,
  int is_tcp
) {
  SocketInt* self;
  if ((self = (SocketInt*)socket_new(name, is_tcp)) == NULL)
    return NULL;


//  o_log(O_LOG_DEBUG, "socket:%s: Attempt to join %s:%d\n", name, addr, port);

  self->servAddr.sin_family = PF_INET;
  self->servAddr.sin_port = htons(port);
  self->servAddr.sin_addr.s_addr = htonl(INADDR_ANY);

  if(bind(self->sockfd, (struct sockaddr *)&self->servAddr,
      sizeof(struct sockaddr_in)) < 0) {
    o_log(O_LOG_ERROR, "socket:%s: Error binding socket to interface: %s\n",
          name, strerror(errno));
    return NULL;
  }

  self->localport = ntohs(self->servAddr.sin_port);
  o_log(O_LOG_DEBUG, "socket:%s: Socket bound to port: %d\n", name, self->localport);

  self->next = instances;
  instances = self;
  return (Socket*)self;
}
Example #13
0
File: socket.c Project: maxott/oml
/** Prevent the remote sender from trasmitting more data.
 *
 * \param socket Socket object for which to shut communication down
 *
 * \see shutdown(3)
 */
int socket_shutdown(Socket *socket) {
  int ret = -1;

  o_log(O_LOG_DEBUG, "socket:%s: Shutting down for R/W\n", socket->name);
  ret = shutdown(((SocketInt *)socket)->sockfd, SHUT_RDWR);
  if(ret) o_log(O_LOG_WARN, "socket:%s: Failed to shut down: %s\n", socket->name, strerror(errno));

  return ret;
}
Example #14
0
/** Send a message through the socket
 *
 * If a disconnection occurs, 0 will be returned, as no data was sent.  To
 * differentiate from cases where data couldn't be written just yet, the socket
 * should be inspected with socket_is_disconnected().
 *
 * \param socket Socket to send message through
 * \param buf data to send
 * \param buf_size amount of data to read from buf
 * \return the amount of data sent, or -1 on error
 *
 * \see socket_is_disconnected, sendto(3)
 */
int
socket_sendto(Socket* socket, char* buf, int buf_size)
{
  SocketInt *self = (SocketInt*)socket;
  int sent;


  if (self->is_disconnected) {
    if(!s_connect(self)) {
      return 0;
    }

  } else if((sent = recv(self->sockfd, NULL, 0, MSG_DONTWAIT)) == 0) {
    /* Test that the server kept the other side of the connection alive */
    if (!(sent < 0 && EAGAIN == errno)) {
      /* EAGAIN is the expected case: connection alive but no data,
       * everything else is a problem */
      logwarn("socket(%s): Server appears to have closed the connection\n", self->name);

      self->is_disconnected = 1;
      /* We want higher levels to be aware of this disconnection */
      return 0;
    }

  }

  if ((sent = sendto(self->sockfd, buf, buf_size, MSG_NOSIGNAL,
                    &(self->servAddr.sa),
                    sizeof(self->servAddr.sa_stor))) < 0) {
    if (errno == EPIPE || errno == ECONNRESET) {
      // The other end closed the connection.
      self->is_disconnected = 1;
      o_log(O_LOG_ERROR, "socket(%s): The remote peer closed the connection: %s\n",
            self->name, strerror(errno));
      return 0;
    } else if (errno == ECONNREFUSED) {
      self->is_disconnected = 1;
      o_log(O_LOG_DEBUG, "socket(%s): Connection refused, trying next AI\n",
            self->name);
      self->rp = self->rp->ai_next;
      return 0;
    } else if (errno == EINTR) {
      o_log(O_LOG_WARN, "socket(%s): Sending data interrupted: %s\n",
            self->name, strerror(errno));
      return 0;
    } else {
      o_log(O_LOG_ERROR, "socket(%s): Sending data failed: %s\n",
            self->name, strerror(errno));
    }
    return -1;
  }
  return sent;
}
Example #15
0
void createDir_ifRequired(char *dir) {

    if ( 0 != access(dir, F_OK) ) {
        // Create the directory
        o_log(INFORMATION, "Created directory.");
        mkdir( dir, 5570 );
        if ( 0 != access(dir, F_OK) ) {
            // Major error - do something!
            o_log(ERROR, "Could not get to new directory.");
            exit(1);
        }
    }

}
Example #16
0
Socket*
socket_mc_out_new(
  char* name,   //! Name used for debugging
  char* mcast_addr,   //! IP address of the multicast socket/channel.
  int mcast_port, //! Port used
  char* iface //! Name of the interface (eth0/eth1) to bind to
) {
  SocketInt* self;
//  if ((self = (SocketInt*)socket_new(name, mcast_addr, 0)) == NULL)
//    return NULL;
  if ((self = (SocketInt*)socket_new(name, FALSE)) == NULL)
    return NULL;

  // Multicast parameters
  unsigned char ttl = 3;
  unsigned char one = 3;  // loopback

  struct in_addr addr;
  addr.s_addr = iface2addr(name, iface);
  o_log(O_LOG_DEBUG, "socket:%s: Binding to %x\n", name, addr.s_addr);
  if (setsockopt(self->sockfd, IPPROTO_IP, IP_MULTICAST_IF, &addr, sizeof(addr)) < 0) {
    o_log (O_LOG_ERROR, "socket:%s: Setting outgoing interface for socket\n\t%s",
       name, strerror(errno));
    socket_free((Socket*)socket);
    return NULL;
  }

  if (setsockopt(self->sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
        sizeof(unsigned char)) < 0) {
    o_log(O_LOG_ERROR, "socket:%s: While setting TTL parameter for multicast socket\n\t%s",
      name, strerror(errno));
    socket_free((Socket*)socket);
    return NULL;
  }
  if (setsockopt(self->sockfd, IPPROTO_IP, IP_MULTICAST_LOOP,
         &one, sizeof(unsigned char)) < 0) {
    o_log(O_LOG_ERROR, "socket%s: While setting the loopback on multicast socket\n\t%s",
      name, strerror(errno));
    socket_free((Socket*)socket);
    return NULL;
  }

  //  self->addr = mcast_addr;
  self->servAddr.sin_port = htons(mcast_port);
  self->servAddr.sin_addr.s_addr = inet_addr(mcast_addr);
  o_log(O_LOG_DEBUG, "socket:%s: Ready to send data on: %s:%d\n",
    name, mcast_addr, mcast_port);
  return (Socket*)self;
}
Example #17
0
File: socket.c Project: maxott/oml
static in_addr_t
iface2addr(
  char* name,
  char* iface //! Name of the interface (eth0/eth1) to bind to
) {
  if (iface == NULL) {
    // use DEFAULT interface
    return INADDR_ANY;
  }

  struct ifreq ifr;
  int ufd;
  memset(&ifr, 0, sizeof(ifr));
  strncpy(ifr.ifr_name, iface, IFNAMSIZ);
  ifr.ifr_addr.sa_family = AF_INET;

  if (((ufd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
      || ioctl(ufd, SIOCGIFADDR, &ifr) < 0)
    {
      o_log(O_LOG_ERROR, "socket:%s: Unable to resolve outgoing interface: %s",
        name, iface);
      return -1;
    }
  close(ufd);

  return ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr;
}
Example #18
0
BufferChain*
createBufferChain(
  BufferedWriter* self
) {
  //  BufferChain* chain = (BufferChain*)malloc(sizeof(BufferChain) + self->chainLength);

  MBuffer* buf = mbuf_create2(self->chainLength, (size_t)(0.1 * self->chainLength));
  if (buf == NULL) return NULL;

  BufferChain* chain = (BufferChain*)xmalloc(sizeof(BufferChain));
  if (chain == NULL) {
    mbuf_destroy(buf);
    return NULL;
  }
  memset(chain, 0, sizeof(BufferChain));

  // set state
  chain->mbuf = buf;
  chain->targetBufSize = self->chainLength;

  /**
  buf->writeP = buf->readP = &buf->buf;
  buf->endP = &buf->buf + (buf->bufLength = self->chainLength);
  */

  self->chainsAvailable--;
  o_log (O_LOG_DEBUG, "Created new buffer chain of size %d with %d remaining.\n",
        self->chainLength, self->chainsAvailable);
  return chain;
}
Example #19
0
/** Deallocate memory for a TimerInt
 * \param timer TimerInt to deallocate
 * \see eventloop_every, eventloop_timer_stop
 */
static void eventloop_timer_free(TimerInt* timer) {
  if (!timer) {
    o_log(O_LOG_DEBUG, "EventLoop: %s: Trying to free NULL pointer\n", __FUNCTION__);
  } else {
    oml_free(timer);
  }
}
Example #20
0
void sll_destroy( struct simpleLinkedList *element ) {
  if( element && ( element != NULL ) ) {
    o_log(SQLDEBUG, "preparing to delete element: %x, with prev=%x, and next=%x", element, element->prev, element->next);
    sll_destroy( sll_getNext( element ) );
    sll_delete( element );
  }
}
Example #21
0
File: socket.c Project: maxott/oml
/** Eventloop callback called when a new connection is received on a listening Socket.
 *
 * This function accept()s the connection, and creates a SocketInt to wrap
 * the underlying system socket. It then runs the user-supplied callback
 * (passed to socket_server_new() when creating the listening Socket) on this
 * new object, passing it the handle (passed to socket_server_new( too))
 *
 * \param source source from which the event was received (e.g., an OComm Channel)
 * \param handle pointer to opaque data passed when creating the listening Socket
 */
static void
on_client_connect(
  SockEvtSource* source,
  //  SocketStatus status,
  void* handle
) {
  (void)source; // FIXME: Check why source parameter is unused
  socklen_t cli_len;

  SocketInt* self = (SocketInt*)handle;

  SocketInt* newSock = initialize(NULL);
  cli_len = sizeof(newSock->servAddr);
  newSock->sockfd = accept(self->sockfd,
                (struct sockaddr*)&newSock->servAddr,
                 &cli_len);
  if (newSock->sockfd < 0) {
    o_log(O_LOG_ERROR, "socket:%s: Error on accept: %s\n",
          self->name, strerror(errno));
    free(newSock);
    return;
  }

  sprintf(newSock->name, "%s-io:%d", self->name, newSock->sockfd);

  if (self->connect_callback) {
    self->connect_callback((Socket*)newSock, self->connect_handle);
  }
}
Example #22
0
void close_all() {

  o_log(DEBUGM, "|Finished");
  close_db ();
  free(BASE_DIR);
  free(LOG_DIR);
}
Example #23
0
static bool user_db_can_reply(	const struct user_cap *user_cap,
								const char *reply,
								uid_t con_uid,
								in_port_t fport)
{
	struct passwd *pw;

	pw = getpwnam(reply);
	if (pw != NULL) {
		/*
		** A user can always reply with her own username.
		*/

		if (pw->pw_uid == con_uid)
			return (true);

		if (user_db_have_cap(user_cap, CAP_SPOOF_ALL) == false) {
			o_log(LOG_INFO, "User %s tried to masquerade as user %s",
				reply, pw->pw_name);

			return (false);
		}
	}

	if (user_db_have_cap(user_cap, CAP_SPOOF) == false)
		return (false);

	if (fport < 1024 &&
		user_db_have_cap(user_cap, CAP_SPOOF_PRIVPORT) == false)
	{
		return (false);
	}

	return (true);
}
Example #24
0
/** Update the number of currently active Channels
 * \return the number of active channels
 */
static int update_fds(void)
{
  Channel* ch = self.channels;
  int i = 0;

  while (ch != NULL) {
    if (ch->is_active) {
      if (self.length <= i) {
        // Need to increase size of fds array
        int l = (self.length > 0 ? 2 * self.length : DEF_FDS_LENGTH);
        self.fds = (struct pollfd *)realloc(self.fds, l * sizeof(struct pollfd));
        self.fds_channels = (Channel **)realloc(self.fds_channels, l * sizeof(Channel*));
        self.length = l;
      }
      self.fds[i].fd = ch->fds_fd;
      self.fds[i].events = ch->fds_events;
      self.fds_channels[i] = ch;
      i++;
    }
    ch = ch->next;
  }
  o_log(O_LOG_DEBUG, "EventLoop: %d active channel%s\n", i, i>1?"s":"");

  self.size = i;
  self.fds_dirty = 0;

  return i;
}
Example #25
0
/** Open a new system socket and link it to the SocketInt object.
 *
 * Also, take care of closing old sockets if they were still there.
 *
 * \param self OComm socket to link the system socket to
 * \return 1 on success, 0 otherwise
 */
static int s_socket(SocketInt* self) {
  if(self->sockfd > 0) {
    close(self->sockfd);
  }
  if((self->sockfd = socket(PF_INET,
                self->is_tcp ? SOCK_STREAM : SOCK_DGRAM, IPPROTO_IP)) < 0) {
    o_log (O_LOG_ERROR, "socket: Error creating socket: %s\n", strerror(errno));
    return 0;
  }
  if (nonblocking_mode) {
    fcntl(self->sockfd, F_SETFL, O_NONBLOCK);
  }
  o_log(O_LOG_DEBUG, "socket:%s: Socket %d successfully created\n",
    self->name, self->sockfd);
  return 1;
}
Example #26
0
/** Eventloop callback called when a new connection is received on a listening Socket.
 *
 * This function accept()s the connection, and creates a SocketInt to wrap
 * the underlying system socket. It then runs the user-supplied callback
 * (passed to socket_server_new() when creating the listening Socket) on this
 * new object, passing it the handle (passed to socket_server_new( too))
 *
 * \param source source from which the event was received (e.g., an OComm Channel)
 * \param handle pointer to opaque data passed when creating the listening Socket
 */
static void
on_client_connect(SockEvtSource* source, void* handle)
{
  (void)source; // FIXME: Check why source parameter is unused
  char host[ADDRLEN], serv[SERVLEN];
  size_t namesize;
  *host = 0;
  *serv = 0;

  socklen_t cli_len;
  SocketInt* self = (SocketInt*)handle;
  SocketInt* newSock = socket_initialize(NULL);
  cli_len = sizeof(newSock->servAddr.sa_stor);
  newSock->sockfd = accept(self->sockfd,
                &newSock->servAddr.sa,
                 &cli_len);

  if (newSock->sockfd < 0) {
    o_log(O_LOG_ERROR, "socket(%s): Error on accept: %s\n",
          self->name, strerror(errno));
    oml_free(newSock);
    return;
  }

  /* XXX: Duplicated somewhat with socket_in_new and s_connect */
  if (!getnameinfo(&newSock->servAddr.sa, cli_len,
        host, ADDRLEN, serv, SERVLEN,
        NI_NUMERICHOST|NI_NUMERICSERV)) {
    namesize =  strlen(host) + strlen(serv) + 3 + 1;
    newSock->name = oml_realloc(newSock->name, namesize);
    snprintf(newSock->name, namesize, "[%s]:%s", host, serv);

  } else {
    namesize =  strlen(host) + 4 + 10 + 1; /* XXX: 10 is arbitrarily chosen for the
                                              number of characters in sockfd's decimal
                                              representation */
    newSock->name = oml_realloc(newSock->name, namesize);
    snprintf(newSock->name, namesize, "%s-io:%d", self->name, newSock->sockfd);
    o_log(O_LOG_WARN, "socket(%s): Error resolving new client source, defaulting to %s: %s\n",
        self->name, newSock->name, strerror(errno));
  }

  if (self->connect_callback) {
    self->connect_callback((Socket*)newSock, self->connect_handle);
  }
}
Example #27
0
/** Execute the monitoring callback of a channel, if defined.
 *
 * \param ch Channel which just changed state
 *
 * \see o_el_monitor_socket_callback
 */
static void do_monitor_callback (Channel *ch)
{
  if (ch->monitor_cbk) {
    ch->monitor_cbk((SockEvtSource*)ch, ch->handle);
  } else {
    o_log(O_LOG_DEBUG, "EventLoop: Channel '%s' has fresh data but no defined callback\n",  ch->name);
  }
}
Example #28
0
/** Execute the data-read callback of a channel, if defined.
 *
 * \param ch Channel just read from
 * \param buffer pointer to a buffer containing the read data
 * \param buf_size size of data in buffer
 *
 * \see o_el_read_socket_callback
 */
static void do_read_callback (Channel *ch, void *buffer, int buf_size)
{
  if (ch->read_cbk && !ch->is_removable) {
    ch->read_cbk ((SockEvtSource*)ch, ch->handle, buffer, buf_size);
  } else {
    o_log(O_LOG_DEBUG, "EventLoop: Channel '%s' has fresh data but no defined callback\n",  ch->name);
  }
}
Example #29
0
File: socket.c Project: maxott/oml
static void
on_self_connected(
  Socket* source,
  SocketStatus status,
  void* handle
) {
  (void)handle;  // FIXME: Check why this parameter is unused.
  SocketInt* self = (SocketInt*)source;

  switch (status) {
  case SOCKET_CONN_REFUSED:
    o_log(O_LOG_ERROR, "socket:%s: Connection refused\n", self->name);
    break;
  default:
    o_log(O_LOG_ERROR, "socket:%s: Unknown socket status '%d'\n", self->name, status);
  }
}
Example #30
0
/** Terminate Channel and free its allocated memory
 *
 * The file descriptor in ch->socket is *NOT* cleaned up here, as all Channels are created through eventloop_on_* functions which first argument is a Socket, socket or file descriptor. The caller of these functions is in charge of cleaning
 *
 * \param ch Channel to terminate and free
 *
 * \see channel_new
 * \see oml_free
 */
static void channel_free(
    Channel *ch
) {
  if (!ch) {
    o_log(O_LOG_DEBUG, "EventLoop: %s: Trying to free NULL pointer\n", __FUNCTION__);
  } else {
    oml_free(ch);
  }
}