コード例 #1
0
/*
  setup the inotify handle - called the first time a watch is added on
  this context
*/
static NTSTATUS inotify_setup(struct sys_notify_context *ctx)
{
	struct inotify_private *in;

	if (!lp_parm_bool(-1, "notify", "inotify", True)) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	in = talloc(ctx, struct inotify_private);
	NT_STATUS_HAVE_NO_MEMORY(in);
	in->fd = inotify_init();
	if (in->fd == -1) {
		DEBUG(0,("Failed to init inotify - %s\n", strerror(errno)));
		talloc_free(in);
		return map_nt_error_from_unix(errno);
	}
	in->ctx = ctx;
	in->watches = NULL;
	in->broken_inotify = False;

	ctx->private_data = in;
	talloc_set_destructor(in, inotify_destructor);

	/* add a event waiting for the inotify fd to be readable */
	event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ, inotify_handler, in);
	
	return NT_STATUS_OK;
}
コード例 #2
0
ファイル: onefs_cbrl.c プロジェクト: 0x24bin/winexe-1
static void onefs_init_cbrl(void)
{
	static bool init_done = false;
	static int cbrl_event_fd;
	static struct fd_event *cbrl_fde;

	if (init_done)
		return;

	DEBUG(10, ("onefs_init_cbrl\n"));

	/* Register the event channel for CBRL. */
	cbrl_event_fd = cbrl_event_register();
	if (cbrl_event_fd == -1) {
		DEBUG(0, ("cbrl_event_register failed: %s\n",
			strerror(errno)));
		return;
	}

	DEBUG(10, ("cbrl_event_fd = %d\n", cbrl_event_fd));

	/* Register the CBRL event_fd with samba's event system */
	cbrl_fde = event_add_fd(smbd_event_context(),
				     NULL,
				     cbrl_event_fd,
				     EVENT_FD_READ,
				     onefs_cbrl_events_handler,
				     NULL);

	init_done = true;
	return;
}
コード例 #3
0
ファイル: connect.c プロジェクト: earthGavinLee/hg556a_source
Conn_t *
conn_add(ConnType_t type, int fd, LecId_t pvc_lecid)
{
  Conn_t *tmp;
  LecId_t lecid = 0;

  if (type != CT_MAIN && type != CT_PVC_CD) {
    /* Find next available LECID */
    for (tmp = connlist; tmp != NULL; tmp = tmp->next){
      if (lecid < tmp->lecid) {
	lecid = tmp->lecid;
      }
    }
    lecid++;
  } else if (type == CT_MAIN) {
    lecid = 0;
  } else /* PVC */
    lecid = pvc_lecid;
  tmp = (Conn_t *)mem_alloc(&conn_unit, sizeof(Conn_t));
  memset(tmp, 0, sizeof(*tmp));
  tmp->fd = fd;
  tmp->state = CS_IDLE;
  tmp->lecid = lecid;
  tmp->type = type;
  tmp->next = connlist;
  tmp->timer = timer_new(&conn_unit);
  tmp->proxy = BL_FALSE;
  connlist = tmp;

  event_add_fd(fd, tmp); 

  return tmp;
}
コード例 #4
0
ファイル: dgramsocket.c プロジェクト: 0x24bin/winexe-1
/*
  initialise a nbt_dgram_socket. The event_ctx is optional, if provided
  then operations will use that event context
*/
struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, 
					      struct tevent_context *event_ctx,
					      struct smb_iconv_convenience *iconv_convenience)
{
	struct nbt_dgram_socket *dgmsock;
	NTSTATUS status;

	dgmsock = talloc(mem_ctx, struct nbt_dgram_socket);
	if (dgmsock == NULL) goto failed;

	dgmsock->event_ctx = event_ctx;
	if (dgmsock->event_ctx == NULL) goto failed;

	status = socket_create("ip", SOCKET_TYPE_DGRAM, &dgmsock->sock, 0);
	if (!NT_STATUS_IS_OK(status)) goto failed;

	socket_set_option(dgmsock->sock, "SO_BROADCAST", "1");

	talloc_steal(dgmsock, dgmsock->sock);

	dgmsock->fde = event_add_fd(dgmsock->event_ctx, dgmsock, 
				    socket_get_fd(dgmsock->sock), 0,
				    dgm_socket_handler, dgmsock);

	dgmsock->send_queue = NULL;
	dgmsock->incoming.handler = NULL;
	dgmsock->mailslot_handlers = NULL;
	dgmsock->iconv_convenience = iconv_convenience;
	
	return dgmsock;

failed:
	talloc_free(dgmsock);
	return NULL;
}
コード例 #5
0
ファイル: clitransport.c プロジェクト: Alexandr-Galko/samba
/*
  create a transport structure based on an established socket
*/
struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock,
					       TALLOC_CTX *parent_ctx, 
					       bool primary, 
					       struct smbcli_options *options)
{
	struct smbcli_transport *transport;

	transport = talloc_zero(parent_ctx, struct smbcli_transport);
	if (!transport) return NULL;

	if (primary) {
		transport->socket = talloc_steal(transport, sock);
	} else {
		transport->socket = talloc_reference(transport, sock);
	}
	transport->negotiate.protocol = PROTOCOL_NT1;
	transport->options = *options;
	transport->negotiate.max_xmit = transport->options.max_xmit;

	/* setup the stream -> packet parser */
	transport->packet = packet_init(transport);
	if (transport->packet == NULL) {
		talloc_free(transport);
		return NULL;
	}
	packet_set_private(transport->packet, transport);
	packet_set_socket(transport->packet, transport->socket->sock);
	packet_set_callback(transport->packet, smbcli_transport_finish_recv);
	packet_set_full_request(transport->packet, packet_full_request_nbt);
	packet_set_error_handler(transport->packet, smbcli_transport_error);
	packet_set_event_context(transport->packet, transport->socket->event.ctx);
	packet_set_nofree(transport->packet);
	packet_set_initial_read(transport->packet, 4);

	smbcli_init_signing(transport);

	ZERO_STRUCT(transport->called);

	/* take over event handling from the socket layer - it only
	   handles events up until we are connected */
	talloc_free(transport->socket->event.fde);
	transport->socket->event.fde = event_add_fd(transport->socket->event.ctx,
						    transport->socket->sock,
						    socket_get_fd(transport->socket->sock),
						    EVENT_FD_READ,
						    smbcli_transport_event_handler,
						    transport);

	packet_set_fde(transport->packet, transport->socket->event.fde);
	packet_set_serialise(transport->packet);
	talloc_set_destructor(transport, transport_destructor);

	return transport;
}
コード例 #6
0
ファイル: winsrepl.c プロジェクト: gojdic/samba
/*
  initialise a wrepl_socket from an already existing connection
*/
struct wrepl_socket *wrepl_socket_merge(TALLOC_CTX *mem_ctx,
                                        struct tevent_context *event_ctx,
                                        struct socket_context *sock,
                                        struct packet_context *pack)
{
    struct wrepl_socket *wrepl_socket;

    wrepl_socket = talloc_zero(mem_ctx, struct wrepl_socket);
    if (wrepl_socket == NULL) goto failed;

    wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx);
    if (wrepl_socket->event.ctx == NULL) goto failed;

    wrepl_socket->sock = sock;
    talloc_steal(wrepl_socket, wrepl_socket->sock);


    wrepl_socket->request_timeout	= WREPL_SOCKET_REQUEST_TIMEOUT;

    wrepl_socket->event.fde = event_add_fd(wrepl_socket->event.ctx, wrepl_socket,
                                           socket_get_fd(wrepl_socket->sock),
                                           EVENT_FD_READ,
                                           wrepl_handler, wrepl_socket);
    if (wrepl_socket->event.fde == NULL) {
        goto failed;
    }

    wrepl_socket->packet = pack;
    talloc_steal(wrepl_socket, wrepl_socket->packet);
    packet_set_private(wrepl_socket->packet, wrepl_socket);
    packet_set_socket(wrepl_socket->packet, wrepl_socket->sock);
    packet_set_callback(wrepl_socket->packet, wrepl_finish_recv);
    packet_set_full_request(wrepl_socket->packet, packet_full_request_u32);
    packet_set_error_handler(wrepl_socket->packet, wrepl_error);
    packet_set_event_context(wrepl_socket->packet, wrepl_socket->event.ctx);
    packet_set_fde(wrepl_socket->packet, wrepl_socket->event.fde);
    packet_set_serialise(wrepl_socket->packet);

    talloc_set_destructor(wrepl_socket, wrepl_socket_destructor);

    return wrepl_socket;

failed:
    talloc_free(wrepl_socket);
    return NULL;
}
コード例 #7
0
ファイル: oplock_irix.c プロジェクト: sprymak/samba
struct kernel_oplocks *irix_init_kernel_oplocks(struct smbd_server_connection *sconn)
{
    struct kernel_oplocks *_ctx;
    struct irix_oplocks_context *ctx;
    int pfd[2];

    if (!irix_oplocks_available())
        return NULL;

    _ctx = talloc_zero(sconn, struct kernel_oplocks);
    if (!_ctx) {
        return NULL;
    }

    ctx = talloc_zero(_ctx, struct irix_oplocks_context);
    if (!ctx) {
        talloc_free(_ctx);
        return NULL;
    }
    _ctx->ops = &irix_koplocks;
    _ctx->private_data = ctx;
    ctx->ctx = _ctx;
    ctx->sconn = sconn;

    if(pipe(pfd) != 0) {
        talloc_free(_ctx);
        DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. "
                 "Error was %s\n", strerror(errno) ));
        return False;
    }

    ctx->read_fd = pfd[0];
    ctx->write_fd = pfd[1];

    ctx->read_fde = event_add_fd(sconn->ev_ctx,
                                 ctx,
                                 ctx->read_fd,
                                 EVENT_FD_READ,
                                 irix_oplocks_read_fde_handler,
                                 ctx);
    return _ctx;
}
コード例 #8
0
ファイル: connect.c プロジェクト: earthGavinLee/hg556a_source
/*
 * State transition functions
 */
static int
join(Conn_t *conn)
{
  int timeout;
  int rfd;

  Debug_unit(&conn_unit, "Join called");
  dump_conn(conn);
  timeout = get_var_int(&conn_unit, "S4");
  timer_alarm(&conn_unit, conn->timer, (unsigned)timeout, conn);
  rfd=atm_connect_back(get_var_addr(&conn_unit, "S1"), 
		       conn, CONTROL_DISTRIBUTE);
  if (rfd<0) {
    conn_remove(conn);
    return 0;
  }
  conn->sfd=rfd;
  event_add_fd(rfd, conn);
  return 1;
}
コード例 #9
0
ファイル: ctdb_io.c プロジェクト: AIdrifter/samba
/*
  setup the fd used by the queue
 */
int ctdb_queue_set_fd(struct ctdb_queue *queue, int fd)
{
	queue->fd = fd;
	talloc_free(queue->fde);
	queue->fde = NULL;

	if (fd != -1) {
		queue->fde = event_add_fd(queue->ctdb->ev, queue, fd, EVENT_FD_READ,
					  queue_io_handler, queue);
		if (queue->fde == NULL) {
			return -1;
		}
		tevent_fd_set_auto_close(queue->fde);

		if (queue->out_queue) {
			EVENT_FD_WRITEABLE(queue->fde);		
		}
	}

	return 0;
}
コード例 #10
0
ファイル: tcp_connect.c プロジェクト: AIdrifter/samba
/*
  listen on our own address
*/
int ctdb_tcp_listen(struct ctdb_context *ctdb)
{
	struct ctdb_tcp *ctcp = talloc_get_type(ctdb->private_data,
						struct ctdb_tcp);
        ctdb_sock_addr sock;
	int sock_size;
	int one = 1;
	struct tevent_fd *fde;

	/* we can either auto-bind to the first available address, or we can
	   use a specified address */
	if (!ctdb->address.address) {
		return ctdb_tcp_listen_automatic(ctdb);
	}

	ZERO_STRUCT(sock);
	if (ctdb_tcp_get_address(ctdb, ctdb->address.address, 
				 &sock) != 0) {
		goto failed;
	}
	
	switch (sock.sa.sa_family) {
	case AF_INET:
		sock.ip.sin_port = htons(ctdb->address.port);
		sock_size = sizeof(sock.ip);
		break;
	case AF_INET6:
		sock.ip6.sin6_port = htons(ctdb->address.port);
		sock_size = sizeof(sock.ip6);
		break;
	default:
		DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
			sock.sa.sa_family));
		goto failed;
	}
#ifdef HAVE_SOCK_SIN_LEN
	sock.ip.sin_len = sock_size;
#endif

	ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
	if (ctcp->listen_fd == -1) {
		ctdb_set_error(ctdb, "socket failed\n");
		return -1;
	}

	set_close_on_exec(ctcp->listen_fd);

        if (setsockopt(ctcp->listen_fd,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)) == -1) {
		DEBUG(DEBUG_WARNING, ("Failed to set REUSEADDR on fd - %s\n",
				      strerror(errno)));
	}

	if (bind(ctcp->listen_fd, (struct sockaddr * )&sock, sock_size) != 0) {
		DEBUG(DEBUG_ERR,(__location__ " Failed to bind() to socket. %s(%d)\n", strerror(errno), errno));
		goto failed;
	}

	if (listen(ctcp->listen_fd, 10) == -1) {
		goto failed;
	}

	fde = event_add_fd(ctdb->ev, ctcp, ctcp->listen_fd, EVENT_FD_READ,
		     ctdb_listen_event, ctdb);	
	tevent_fd_set_auto_close(fde);

	return 0;

failed:
	if (ctcp->listen_fd != -1) {
		close(ctcp->listen_fd);
	}
	ctcp->listen_fd = -1;
	return -1;
}
コード例 #11
0
ファイル: tcp_connect.c プロジェクト: AIdrifter/samba
/*
  automatically find which address to listen on
*/
static int ctdb_tcp_listen_automatic(struct ctdb_context *ctdb)
{
	struct ctdb_tcp *ctcp = talloc_get_type(ctdb->private_data,
						struct ctdb_tcp);
        ctdb_sock_addr sock;
	int lock_fd, i;
	const char *lock_path = VARDIR "/run/ctdb/.socket_lock";
	struct flock lock;
	int one = 1;
	int sock_size;
	struct tevent_fd *fde;

	/* If there are no nodes, then it won't be possible to find
	 * the first one.  Log a failure and short circuit the whole
	 * process.
	 */
	if (ctdb->num_nodes == 0) {
		DEBUG(DEBUG_CRIT,("No nodes available to attempt bind to - is the nodes file empty?\n"));
		return -1;
	}

	/* in order to ensure that we don't get two nodes with the
	   same adddress, we must make the bind() and listen() calls
	   atomic. The SO_REUSEADDR setsockopt only prevents double
	   binds if the first socket is in LISTEN state  */
	lock_fd = open(lock_path, O_RDWR|O_CREAT, 0666);
	if (lock_fd == -1) {
		DEBUG(DEBUG_CRIT,("Unable to open %s\n", lock_path));
		return -1;
	}

	lock.l_type = F_WRLCK;
	lock.l_whence = SEEK_SET;
	lock.l_start = 0;
	lock.l_len = 1;
	lock.l_pid = 0;

	if (fcntl(lock_fd, F_SETLKW, &lock) != 0) {
		DEBUG(DEBUG_CRIT,("Unable to lock %s\n", lock_path));
		close(lock_fd);
		return -1;
	}

	for (i=0; i < ctdb->num_nodes; i++) {
		if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
			continue;
		}
		ZERO_STRUCT(sock);
		if (ctdb_tcp_get_address(ctdb,
				ctdb->nodes[i]->address.address, 
				&sock) != 0) {
			continue;
		}
	
		switch (sock.sa.sa_family) {
		case AF_INET:
			sock.ip.sin_port = htons(ctdb->nodes[i]->address.port);
			sock_size = sizeof(sock.ip);
			break;
		case AF_INET6:
			sock.ip6.sin6_port = htons(ctdb->nodes[i]->address.port);
			sock_size = sizeof(sock.ip6);
			break;
		default:
			DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
				sock.sa.sa_family));
			continue;
		}
#ifdef HAVE_SOCK_SIN_LEN
		sock.ip.sin_len = sock_size;
#endif

		ctcp->listen_fd = socket(sock.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
		if (ctcp->listen_fd == -1) {
			ctdb_set_error(ctdb, "socket failed\n");
			continue;
		}

		set_close_on_exec(ctcp->listen_fd);

	        if (setsockopt(ctcp->listen_fd,SOL_SOCKET,SO_REUSEADDR,
			       (char *)&one,sizeof(one)) == -1) {
			DEBUG(DEBUG_WARNING, ("Failed to set REUSEADDR on fd - %s\n",
					      strerror(errno)));
		}

		if (bind(ctcp->listen_fd, (struct sockaddr * )&sock, sock_size) == 0) {
			break;
		}

		if (errno == EADDRNOTAVAIL) {
			DEBUG(DEBUG_DEBUG,(__location__ " Failed to bind() to socket. %s(%d)\n",
					strerror(errno), errno));
		} else {
			DEBUG(DEBUG_ERR,(__location__ " Failed to bind() to socket. %s(%d)\n",
					strerror(errno), errno));
		}
	}
	
	if (i == ctdb->num_nodes) {
		DEBUG(DEBUG_CRIT,("Unable to bind to any of the node addresses - giving up\n"));
		goto failed;
	}
	ctdb->address.address = talloc_strdup(ctdb, ctdb->nodes[i]->address.address);
	ctdb->address.port    = ctdb->nodes[i]->address.port;
	ctdb->name = talloc_asprintf(ctdb, "%s:%u", 
				     ctdb->address.address, 
				     ctdb->address.port);
	ctdb->pnn = ctdb->nodes[i]->pnn;
	DEBUG(DEBUG_INFO,("ctdb chose network address %s:%u pnn %u\n", 
		 ctdb->address.address, 
		 ctdb->address.port, 
		 ctdb->pnn));
	
	if (listen(ctcp->listen_fd, 10) == -1) {
		goto failed;
	}

	fde = event_add_fd(ctdb->ev, ctcp, ctcp->listen_fd, EVENT_FD_READ,
			   ctdb_listen_event, ctdb);
	tevent_fd_set_auto_close(fde);

	close(lock_fd);

	return 0;
	
failed:
	close(lock_fd);
	if (ctcp->listen_fd != -1) {
		close(ctcp->listen_fd);
		ctcp->listen_fd = -1;
	}
	return -1;
}
コード例 #12
0
ファイル: tcp_connect.c プロジェクト: AIdrifter/samba
/*
  called when we should try and establish a tcp connection to a node
*/
void ctdb_tcp_node_connect(struct event_context *ev, struct timed_event *te, 
			   struct timeval t, void *private_data)
{
	struct ctdb_node *node = talloc_get_type(private_data,
						 struct ctdb_node);
	struct ctdb_tcp_node *tnode = talloc_get_type(node->private_data, 
						      struct ctdb_tcp_node);
	struct ctdb_context *ctdb = node->ctdb;
        ctdb_sock_addr sock_in;
	int sockin_size;
	int sockout_size;
        ctdb_sock_addr sock_out;

	ctdb_tcp_stop_connection(node);

	ZERO_STRUCT(sock_out);
#ifdef HAVE_SOCK_SIN_LEN
	sock_out.ip.sin_len = sizeof(sock_out);
#endif
	if (ctdb_tcp_get_address(ctdb, node->address.address, &sock_out) != 0) {
		return;
	}
	switch (sock_out.sa.sa_family) {
	case AF_INET:
		sock_out.ip.sin_port = htons(node->address.port);
		break;
	case AF_INET6:
		sock_out.ip6.sin6_port = htons(node->address.port);
		break;
	default:
		DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
			sock_out.sa.sa_family));
		return;
	}

	tnode->fd = socket(sock_out.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
	if (tnode->fd == -1) {
		DEBUG(DEBUG_ERR, (__location__ "Failed to create socket\n"));
		return;
	}
	set_nonblocking(tnode->fd);
	set_close_on_exec(tnode->fd);

	DEBUG(DEBUG_DEBUG, (__location__ " Created TCP SOCKET FD:%d\n", tnode->fd));

	/* Bind our side of the socketpair to the same address we use to listen
	 * on incoming CTDB traffic.
	 * We must specify this address to make sure that the address we expose to
	 * the remote side is actually routable in case CTDB traffic will run on
	 * a dedicated non-routeable network.
	 */
	ZERO_STRUCT(sock_in);
	if (ctdb_tcp_get_address(ctdb, ctdb->address.address, &sock_in) != 0) {
		DEBUG(DEBUG_ERR, (__location__ " Failed to find our address. Failing bind.\n"));
		close(tnode->fd);
		return;
	}

	/* AIX libs check to see if the socket address and length
	   arguments are consistent with each other on calls like
	   connect().   Can not get by with just sizeof(sock_in),
	   need sizeof(sock_in.ip).
	*/
	switch (sock_in.sa.sa_family) {
	case AF_INET:
		sockin_size = sizeof(sock_in.ip);
		sockout_size = sizeof(sock_out.ip);
		break;
	case AF_INET6:
		sockin_size = sizeof(sock_in.ip6);
		sockout_size = sizeof(sock_out.ip6);
		break;
	default:
		DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
			sock_in.sa.sa_family));
		close(tnode->fd);
		return;
	}
#ifdef HAVE_SOCK_SIN_LEN
	sock_in.ip.sin_len = sockin_size;
	sock_out.ip.sin_len = sockout_size;
#endif
	if (bind(tnode->fd, (struct sockaddr *)&sock_in, sockin_size) == -1) {
		DEBUG(DEBUG_ERR, (__location__ "Failed to bind socket %s(%d)\n",
				  strerror(errno), errno));
		close(tnode->fd);
		return;
	}

	if (connect(tnode->fd, (struct sockaddr *)&sock_out, sockout_size) != 0 &&
	    errno != EINPROGRESS) {
		ctdb_tcp_stop_connection(node);
		tnode->connect_te = event_add_timed(ctdb->ev, tnode, 
						    timeval_current_ofs(1, 0),
						    ctdb_tcp_node_connect, node);
		return;
	}

	/* non-blocking connect - wait for write event */
	tnode->connect_fde = event_add_fd(node->ctdb->ev, tnode, tnode->fd, 
					  EVENT_FD_WRITE|EVENT_FD_READ, 
					  ctdb_node_connect_write, node);

	/* don't give it long to connect - retry in one second. This ensures
	   that we find a node is up quickly (tcp normally backs off a syn reply
	   delay by quite a lot) */
	tnode->connect_te = event_add_timed(ctdb->ev, tnode, timeval_current_ofs(1, 0), 
					    ctdb_tcp_node_connect, node);
}