예제 #1
0
t_channel	*channel_pop(t_channel *channel, t_channel *container)
{
  t_channel	*tmp;
  t_channel	*backup;

  if (container == channel)
    {
      tmp = channel->next;
      channel_destroy(channel);
      return (tmp);
    }
  else
    {
      for (tmp = container; tmp != NULL; tmp = tmp->next)
	{
	  if (tmp == channel)
	    {
	      backup->next = channel->next;
	      channel_destroy(channel);
	      return (container);
	    }
	  backup = tmp;
	}
    }
  return (NULL);
}
예제 #2
0
int main(int argc, char **argv)
{
    int i, err;
    int nb_writers, nb_readers;
    pthread_t th;
    pthread_t thr[MAX_THREADS];
    pthread_t thw[MAX_THREADS];

    if(argc != 3)
    {
        printf("usage : %s <nb_writers> <nb_readers>\n",argv[0]);
        return EXIT_FAILURE;
    }

    srand(time(NULL));
    nb_writers = atoi(argv[1]);
    nb_readers = atoi(argv[2]);
    chan_s = channel_create(sizeof(msg_t),NB_MSG,CHANNEL_PROCESS_NONBLOCK);
    chan_r = channel_create(sizeof(msg_t),NB_MSG,CHANNEL_PROCESS_NONBLOCK);

    // Create every threads
    for(i = 0; i < nb_writers; i++)
    {
        err = pthread_create(&thw[i],NULL,sendm,NULL);

        if(err != 0)
            perror("pthread_create");
    }

    for(i = 0; i < nb_readers; i++)
    {
        pthread_create(&thr[i],NULL,receive,NULL);
    }

    pthread_create(&th,NULL,forward,NULL);

    printf("Working...\n");

    // Wait for every threads
    for(i = 0; i < nb_writers; i++)
    {
        pthread_join(thw[i],NULL);
    }

    for(i = 0; i < nb_readers; i++)
    {
        pthread_join(thr[i],NULL);
    }

    pthread_join(th,NULL);
    channel_destroy(chan_s);
    channel_destroy(chan_r);
    printf("End of program\n");

    return EXIT_SUCCESS;
}
예제 #3
0
static void channel_rejoin(IRC_SERVER_REC *server, const char *channel)
{
	IRC_CHANNEL_REC *chanrec;
	REJOIN_REC *rec;

	g_return_if_fail(IS_IRC_SERVER(server));
	g_return_if_fail(channel != NULL);

	chanrec = irc_channel_find(server, channel);
	if (chanrec == NULL || chanrec->joined) return;

	rec = rejoin_find(server, channel);
	if (rec != NULL) {
		/* already exists */
		rec->joining = FALSE;

		/* update channel key */
		g_free_and_null(rec->key);
		if (channel_have_key(chanrec))
			rec->key = g_strdup(chanrec->key);
	} else {
		/* new rejoin */
		rec = g_new0(REJOIN_REC, 1);
		rec->channel = g_strdup(channel);
		if (channel_have_key(chanrec))
			rec->key = g_strdup(chanrec->key);

		server->rejoin_channels =
			g_slist_append(server->rejoin_channels, rec);
		signal_emit("channel rejoin new", 2, server, rec);
	}

	chanrec->left = TRUE;
	channel_destroy(CHANNEL(chanrec));
}
예제 #4
0
파일: htsp.c 프로젝트: PeteGashek/showtime
static void
channel_delete_all(htsp_connection_t *hc)
{
  htsp_channel_t *ch;
  while((ch = LIST_FIRST(&hc->hc_channels)) != NULL)
    channel_destroy(ch);
}
예제 #5
0
void async_task_queue_destroy(async_task_queue_t *task_queue)
{
    struct async_task *task;
    
    if (NULL == task_queue)
    {
        return;
    }

    while (NULL != task_queue->async_task)
    {
        task = task_queue->async_task;
        task_queue->async_task = task->next;
        free(task);
    }

    channel_detach(task_queue->channel);
    channel_destroy(task_queue->channel);
    closesocket(task_queue->fds[0]);
    closesocket(task_queue->fds[1]);

    lock_uninit(&task_queue->task_lock);

    free(task_queue);
    
    return;
}
예제 #6
0
channel_t * channel_create( void )
{
	channel_t *new_channel = NULL;
	channel_header_t *new_header = NULL;
	
	new_channel = ( channel_t * ) malloc( sizeof( channel_t ) );

	if( ! new_channel ) return NULL;

	new_header = channel_header_create();

	if( ! new_header )
	{
		channel_destroy( &new_channel );
		return NULL;
	}

	new_channel->header = new_header;

	new_channel->chapter_n = NULL;
	new_channel->chapter_c = NULL;
	new_channel->chapter_p = NULL;
		
	return new_channel;
}
예제 #7
0
/* SYNTAX: CYCLE [<channel>] [<message>] */
static void cmd_cycle(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
{
	CHANNEL_REC *chanrec;
	char *channame, *msg, *joindata;
	void *free_arg;

	g_return_if_fail(data != NULL);
	if (!IS_SERVER(server) || !server->connected)
		cmd_return_error(CMDERR_NOT_CONNECTED);

	if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN,
			    item, &channame, &msg))
		return;
	if (*channame == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);

	chanrec = channel_find(server, channame);
	if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND);

	joindata = chanrec->get_join_data(chanrec);
	window_bind_add(window_item_window(chanrec),
			chanrec->server->tag, chanrec->name);

	/* FIXME: kludgy kludgy... */
	signal_emit("command part", 3, data, server, item);

	if (g_slist_find(channels, chanrec) != NULL) {
		chanrec->left = TRUE;
		channel_destroy(chanrec);
	}

	server->channels_join(server, joindata, FALSE);
	g_free(joindata);

	cmd_params_free(free_arg);
}
예제 #8
0
파일: ustctl.c 프로젝트: phuongtg/lttng-ust
void ustctl_unmap_channel(struct lttng_ust_shm_handle *handle)
{
	struct channel *chan;

	assert(handle);
	chan = shmp(handle, handle->chan);
	channel_destroy(chan, handle, 1);
}
예제 #9
0
static void signal_window_item_destroy(WINDOW_REC *window, WI_ITEM_REC *item)
{
	CHANNEL_REC *channel;

	g_return_if_fail(window != NULL);

	channel = CHANNEL(item);
        if (channel != NULL) channel_destroy(channel);
}
예제 #10
0
static
void unmap_channel(struct lttng_ust_shm_handle *handle)
{
	struct channel *chan;

	chan = shmp(handle, handle->chan);
	/* unmap channel */
	channel_destroy(chan, handle, 1);
}
예제 #11
0
static inline
void delete_udp_peer(udp_peer_t* peer)
{
    channel_detach(peer->channel);
    channel_destroy(peer->channel);
    closesocket(peer->fd);
    free(peer);
    
    return;
}
예제 #12
0
void
muc_part(MUC_REC *channel, const char *reason)
{
	g_return_if_fail(IS_MUC(channel));
	send_part(channel, reason);
	channel->left = TRUE;
	if (channel->ownnick != NULL)
		signal_emit("message part", 5, channel->server, channel->name,
		    channel->ownnick->nick, channel->ownnick->host, reason);
	channel_destroy(CHANNEL(channel));
}
예제 #13
0
void icb_change_channel(ICB_SERVER_REC *server, const char *channel,
			int automatic)
{
	if (g_strcasecmp(server->group->name, channel) == 0)
		return;

	channel_destroy(CHANNEL(server->group));
	server->group = (ICB_CHANNEL_REC *)
		icb_channel_create(server, channel, NULL, automatic);

        icb_command(server, "g", channel, NULL);
}
예제 #14
0
void		channel_release(t_channel *channel)
{
  t_channel	*tmp;
  t_channel	*backup;

  tmp = channel;
  while (tmp)
    {
      backup = tmp->next;
      channel_destroy(tmp);
      tmp = backup;
    }
}
예제 #15
0
static 
void delete_connection(tcp_connection_t *connection)
{
	log_debug("connection to %s:%u will be destroyed", connection->peer_addr.ip, connection->peer_addr.port);

	channel_detach(connection->channel);
	channel_destroy(connection->channel);
	shutdown(connection->fd, SHUT_RDWR);
	close(connection->fd);
	buffer_destory(connection->in_buffer);
	buffer_destory(connection->out_buffer);
	free(connection);

    return;
}
예제 #16
0
파일: htsp.c 프로젝트: PeteGashek/showtime
static void
htsp_channelDelete(htsp_connection_t *hc, htsmsg_t *m)
{
  uint32_t id;
  htsp_channel_t *ch;

  if(htsmsg_get_u32(m, "channelId", &id))
    return;

  hts_mutex_lock(&hc->hc_meta_mutex);

  if((ch = htsp_channel_get(hc, id, 0)) != NULL)
    channel_destroy(ch);
  
  hts_mutex_unlock(&hc->hc_meta_mutex);
}
예제 #17
0
파일: tcp_server.c 프로젝트: tuyooc/tinylib
static
void do_tcp_server_stop(void* userdata)
{
    tcp_server_t *server = (tcp_server_t*)userdata;

    channel_detach(server->channel);
    channel_destroy(server->channel);
    server->channel = NULL;
    close(server->idle_fd);
    server->idle_fd = -1;
    close(server->fd);
    server->fd = -1;
    server->is_started = 0;

    return;
}
예제 #18
0
static
struct lttng_ust_shm_handle *map_channel(struct lttng_ust_object_data *chan_data,
		struct lttng_ust_object_data *stream_datas, int nr_check)
{
	struct lttng_ust_shm_handle *handle;
	struct channel *chan;
	int k, ret;

	/* map metadata channel */
	handle = channel_handle_create(chan_data->shm_fd,
		chan_data->wait_fd,
		chan_data->memory_map_size);
	if (!handle) {
		printf("create handle error\n");
		return NULL;
	}
	chan_data->shm_fd = -1;
	chan_data->wait_fd = -1;
	chan = shmp(handle, handle->chan);

	for (k = 0; k < nr_check; k++) {
		struct lttng_ust_object_data *stream_data = &stream_datas[k];

		if (!stream_data->handle)
			break;
		/* map stream */
		ret = channel_handle_add_stream(handle,
			stream_data->shm_fd,
			stream_data->wait_fd,
			stream_data->memory_map_size);
		if (ret) {
			printf("add stream error\n");
			goto error_destroy;
		}
		stream_data->shm_fd = -1;
		stream_data->wait_fd = -1;
	}
	return handle;

error_destroy:
	channel_destroy(chan, handle, 1);
	return NULL;
}
예제 #19
0
파일: tcp_server.c 프로젝트: tuyooc/tinylib
static
void do_tcp_server_start(void* userdata)
{
    tcp_server_t *server = (tcp_server_t*)userdata;

    do
    {
        server->fd = create_server_socket(server->addr.port, server->addr.ip);
        if (server->fd < 0)
        {
            log_error("do_tcp_server_start: create_server_socket() failed, local addr: %s:%u", server->addr.ip, server->addr.port);
            break;
        }

        server->channel = channel_new(server->fd, server->loop, server_onevent, server);

        if (listen(server->fd, 512) != 0)
        {
            log_error("do_tcp_server_start: listen() failed, errno: %d, local addr: %s:%u", errno, server->addr.ip, server->addr.port);
            break;
        }
        if (channel_setevent(server->channel, EPOLLIN))
        {
            log_error("do_tcp_server_start: channel_setevent() failed, local addr: %s:%u", server->addr.ip, server->addr.port);
            break;
        }

        return;
    } while(0);

    if (server->fd >= 0)
    {
        close(server->fd);
        server->fd = -1;
    }
    channel_destroy(server->channel);
    server->channel = NULL;
    server->is_started = 0;

    return;
}
/*
 * core_channel_close
 * ------------------
 *
 * Closes a previously opened channel.
 *
 * req: TLV_TYPE_CHANNEL_ID -- The channel identifier to close
 */
DWORD remote_request_core_channel_close(Remote *remote, Packet *packet)
{
	Packet *response = packet_create_response(packet);
	DWORD res = ERROR_SUCCESS, channelId;
	Channel *channel = NULL;

	dprintf("[CHANNEL] remote_request_core_channel_close.");

	do
	{
		// Get the channel identifier
		channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);

		// Try to locate the specified channel
		if (!(channel = channel_find_by_id(channelId)))
		{
			res = ERROR_NOT_FOUND;
			break;
		}

		// Destroy the channel
		channel_destroy(channel, packet);

		if (response)
		{
			packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channelId);
		}

	} while (0);

	// Transmit the acknowledgement
	if (response)
	{
		packet_add_tlv_uint(response, TLV_TYPE_RESULT, res);

		res = PACKET_TRANSMIT(remote, response, NULL);
	}

	return res;
}
예제 #21
0
static void event_part(IRC_SERVER_REC *server, const char *data, const char *nick)
{
    char *params, *channel, *reason;
    CHANNEL_REC *chanrec;

    g_return_if_fail(data != NULL);

    if (g_ascii_strcasecmp(nick, server->nick) != 0) {
        /* someone else part, no need to do anything here */
        return;
    }

    params = event_get_params(data, 2, &channel, &reason);

    chanrec = channel_find(SERVER(server), channel);
    if (chanrec != NULL && chanrec->joined) {
        chanrec->left = TRUE;
        channel_destroy(chanrec);
    }

    g_free(params);
}
예제 #22
0
static void check_join_failure(IRC_SERVER_REC *server, const char *channel)
{
    CHANNEL_REC *chanrec;
    char *chan2;

    if (channel[0] == '!' && channel[1] == '!')
        channel++; /* server didn't understand !channels */

    chanrec = channel_find(SERVER(server), channel);
    if (chanrec == NULL && channel[0] == '!') {
        /* it probably replied with the full !channel name,
           find the channel with the short name.. */
        chan2 = g_strdup_printf("!%s", channel+6);
        chanrec = channel_find(SERVER(server), chan2);
        g_free(chan2);
    }

    if (chanrec != NULL && !chanrec->joined) {
        chanrec->left = TRUE;
        channel_destroy(chanrec);
    }
}
예제 #23
0
파일: servers.c 프로젝트: svn2github/irssi
static int server_remove_channels(SERVER_REC *server)
{
	GSList *tmp, *next;
	int found;

	g_return_val_if_fail(server != NULL, FALSE);

	found = FALSE;
	for (tmp = server->channels; tmp != NULL; tmp = next) {
		CHANNEL_REC *channel = tmp->data;

		next = tmp->next;
		channel_destroy(channel);
		found = TRUE;
	}

	while (server->queries != NULL)
		query_change_server(server->queries->data, NULL);

	g_slist_free(server->channels);
	g_slist_free(server->queries);

	return found;
}
/*
 * core_channel_close (response)
 * ------------------
 *
 * Removes the local instance of the channel
 *
 * req: TLV_TYPE_CHANNEL_ID -- The channel identifier to close
 */
DWORD remote_response_core_channel_close(Remote *remote, Packet *packet)
{
	DWORD res = ERROR_SUCCESS, channelId;
	Channel *channel = NULL;

	do
	{
		// Get the channel identifier
		channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);

		// Try to locate the specified channel
		if (!(channel = channel_find_by_id(channelId)))
		{
			res = ERROR_NOT_FOUND;
			break;
		}

		// Destroy the channel
		channel_destroy(channel, packet);

	} while (0);

	return res;
}
예제 #25
0
static void event_kick(IRC_SERVER_REC *server, const char *data)
{
    CHANNEL_REC *chanrec;
    char *params, *channel, *nick, *reason;

    g_return_if_fail(data != NULL);

    params = event_get_params(data, 3, &channel, &nick, &reason);

    if (g_ascii_strcasecmp(nick, server->nick) != 0) {
        /* someone else was kicked, no need to do anything */
        g_free(params);
        return;
    }

    chanrec = channel_find(SERVER(server), channel);
    if (chanrec != NULL) {
        irc_server_purge_output(server, channel);
        chanrec->kicked = TRUE;
        channel_destroy(chanrec);
    }

    g_free(params);
}
예제 #26
0
static void event_duplicate_channel(IRC_SERVER_REC *server, const char *data)
{
    CHANNEL_REC *chanrec;
    char *params, *channel, *p;

    g_return_if_fail(data != NULL);

    /* this new addition to ircd breaks completely with older
       "standards", "nick Duplicate ::!!channel ...." */
    params = event_get_params(data, 3, NULL, NULL, &channel);
    p = strchr(channel, ' ');
    if (p != NULL) *p = '\0';

    if (channel[0] == '!') {
        chanrec = channel_find(SERVER(server),
                               channel+(channel[1] == '!'));
        if (chanrec != NULL && !chanrec->names_got) {
            chanrec->left = TRUE;
            channel_destroy(chanrec);
        }
    }

    g_free(params);
}
예제 #27
0
void journal_destroy( journal_t **journal )
{
	unsigned int i = 0;

	if( ! journal ) return;
	if( ! *journal) return;

	for( i = 0 ; i < MAX_MIDI_CHANNELS ; i++ )
	{
		if( (*journal)->channels[i] )
		{
			channel_destroy( &( (*journal)->channels[i] ) );
		}
	}

	if( (*journal)->header )
	{
		journal_header_destroy( &( (*journal)->header ) );
		(*journal)->header = NULL;
	}

	free( *journal );
	*journal = NULL;
}
예제 #28
0
/*!
 * @brief Allocates a streaming TCP server channel.
 * @param remote Pointer to the remote instance.
 * @param packet Pointer to the request packet.
 * @returns Indication of success or failure.
 * @retval ERROR_SUCCESS Opening the server channel completed successfully.
 */
DWORD request_net_tcp_server_channel_open(Remote * remote, Packet * packet)
{
    DWORD dwResult = ERROR_SUCCESS;
    TcpServerContext * ctx = NULL;
    Packet * response = NULL;
    char * localHost = NULL;
    StreamChannelOps chops = { 0 };
    USHORT localPort = 0;
    BOOL v4Fallback = FALSE;

    do
    {
        response = packet_create_response(packet);
        if (!response)
        {
            BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. response == NULL", ERROR_NOT_ENOUGH_MEMORY);
        }

        ctx = (TcpServerContext *)malloc(sizeof(TcpServerContext));
        if (!ctx)
        {
            BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. ctx == NULL", ERROR_NOT_ENOUGH_MEMORY);
        }

        memset(ctx, 0, sizeof(TcpServerContext));

        ctx->remote = remote;

        localPort = (USHORT)(packet_get_tlv_value_uint(packet, TLV_TYPE_LOCAL_PORT) & 0xFFFF);
        if (!localPort)
        {
            BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. localPort == NULL", ERROR_INVALID_HANDLE);
        }

        localHost = packet_get_tlv_value_string(packet, TLV_TYPE_LOCAL_HOST);

        ctx->fd = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
        if (ctx->fd == INVALID_SOCKET)
        {
            v4Fallback = TRUE;
        }
        else
        {
            int no = 0;
            if (setsockopt(ctx->fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&no, sizeof(no)) == SOCKET_ERROR)
            {
                // fallback to ipv4 - we're probably running on Windows XP or earlier here, which means that to
                // support IPv4 and IPv6 we'd need to create two separate sockets. IPv6 on XP isn't that common
                // so instead, we'll just revert back to v4 and listen on that one address instead.
                closesocket(ctx->fd);
                v4Fallback = TRUE;
            }
        }

        struct sockaddr_in6 sockAddr = { 0 };
        DWORD sockAddrSize = 0;

        if (v4Fallback)
        {
            struct sockaddr_in* v4Addr = (struct sockaddr_in*)&sockAddr;
            v4Addr->sin_addr.s_addr = localHost == NULL ? htons(INADDR_ANY) : inet_addr(localHost);
            v4Addr->sin_family = AF_INET;
            v4Addr->sin_port = htons(localPort);
            sockAddrSize = sizeof(struct sockaddr_in);
        }
        else
        {
            // TODO: add IPv6 address binding support
            sockAddr.sin6_addr = in6addr_any;
            sockAddr.sin6_family = AF_INET6;
            sockAddr.sin6_port = htons(localPort);
            sockAddrSize = sizeof(struct sockaddr_in6);
        }

        if (bind(ctx->fd, (SOCKADDR *)&sockAddr, sockAddrSize) == SOCKET_ERROR)
        {
            BREAK_ON_WSAERROR("[TCP-SERVER] request_net_tcp_server_channel_open. bind failed");
        }

        if (listen(ctx->fd, SOMAXCONN) == SOCKET_ERROR)
        {
            BREAK_ON_WSAERROR("[TCP-SERVER] request_net_tcp_server_channel_open. listen failed");
        }

        ctx->notify = WSACreateEvent();
        if (ctx->notify == WSA_INVALID_EVENT)
        {
            BREAK_ON_WSAERROR("[TCP-SERVER] request_net_tcp_server_channel_open. WSACreateEvent failed");
        }

        if (WSAEventSelect(ctx->fd, ctx->notify, FD_ACCEPT) == SOCKET_ERROR)
        {
            BREAK_ON_WSAERROR("[TCP-SERVER] request_net_tcp_server_channel_open. WSAEventSelect failed");
        }

        ctx->ipv6 = !v4Fallback;

        memset(&chops, 0, sizeof(StreamChannelOps));
        chops.native.context = ctx;
        chops.native.close = tcp_channel_server_close;

        ctx->channel = channel_create_stream(0, CHANNEL_FLAG_SYNCHRONOUS, &chops);
        if (!ctx->channel)
        {
            BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. channel_create_stream failed", ERROR_INVALID_HANDLE);
        }

        scheduler_insert_waitable(ctx->notify, ctx, NULL, (WaitableNotifyRoutine)tcp_channel_server_notify, NULL);

        packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(ctx->channel));

        dprintf("[TCP-SERVER] request_net_tcp_server_channel_open. tcp server %s:%d on channel %d", localHost, localPort, channel_get_id(ctx->channel));

    } while (0);

    packet_transmit_response(dwResult, remote, response);

    do
    {
        if (dwResult == ERROR_SUCCESS)
        {
            break;
        }

        dprintf("[TCP-SERVER] Error encountered %u 0x%x", dwResult, dwResult);

        if (!ctx)
        {
            break;
        }

        if (ctx->fd)
        {
            dprintf("[TCP-SERVER] Destroying socket");
            closesocket(ctx->fd);
        }

        if (ctx->channel)
        {
            dprintf("[TCP-SERVER] Destroying channel");
            channel_destroy(ctx->channel, packet);
        }

        free(ctx);

    } while (0);

    return dwResult;
}
예제 #29
0
/*
 * Handles the open request for a file channel and returns a valid channel
 * identifier to the requestor if the file is opened successfully
 */
DWORD request_fs_file_channel_open(Remote *remote, Packet *packet)
{
	Packet *response = NULL;
	PCHAR filePath, mode;
	DWORD res = ERROR_SUCCESS;
	DWORD flags = 0;
	Channel *newChannel = NULL;
	PoolChannelOps chops = { 0 };
	FileContext *ctx;
	LPSTR expandedFilePath = NULL;

	do
	{
		// Allocate a response
		response = packet_create_response(packet);

		// Get the channel flags
		flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS);

		// Allocate storage for the file context
		if (!(ctx = (FileContext *)malloc(sizeof(FileContext))))
		{
			res = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Get the file path and the mode
		filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
		mode     = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_MODE);

		// No file path? bogus.
		if (!filePath)
		{
			res = ERROR_INVALID_PARAMETER;
			break;
		}

		// Expand the file path
		if (!(expandedFilePath = fs_expand_path(filePath)))
		{
			res = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}
	
		if (!mode)
			mode = "rb";

		// Invalid file?
		if (!(ctx->fd = fopen(expandedFilePath, mode)))
		{
			res = GetLastError();
			break;
		}

		memset(&chops, 0, sizeof(chops));

		// Initialize the pool operation handlers
		chops.native.context = ctx;
		chops.native.write   = file_channel_write;
		chops.native.close   = file_channel_close;
		chops.read           = file_channel_read;
		chops.eof            = file_channel_eof;
		chops.seek           = file_channel_seek;
		chops.tell           = file_channel_tell;

		// Check the response allocation & allocate a un-connected
		// channel
		if ((!response) ||
		    (!(newChannel = channel_create_pool(0, flags,
				&chops))))
		{
			res = ERROR_NOT_ENOUGH_MEMORY;
			break;
		}

		// Add the channel identifier to the response
		packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, 
				channel_get_id(newChannel));

	} while (0);

	// Transmit the packet if it's valid
	packet_transmit_response(res, remote, response);

	// Clean up on failure
	if (res != ERROR_SUCCESS)
	{
		if (newChannel)
			channel_destroy(newChannel, NULL);
		if (ctx)
			free(ctx);
	}

	// Free the expanded file path if it was allocated
	if (expandedFilePath)
		free(expandedFilePath);

	return res;
}
예제 #30
0
static void event_join(IRC_SERVER_REC *server, const char *data, const char *nick, const char *address)
{
    char *params, *channel, *tmp, *shortchan;
    IRC_CHANNEL_REC *chanrec;

    g_return_if_fail(data != NULL);

    if (g_ascii_strcasecmp(nick, server->nick) != 0) {
        /* someone else joined channel, no need to do anything */
        return;
    }

    if (server->userhost == NULL)
        server->userhost = g_strdup(address);

    params = event_get_params(data, 1, &channel);
    tmp = strchr(channel, 7); /* ^G does something weird.. */
    if (tmp != NULL) *tmp = '\0';

    if (*channel != '!' || strlen(channel) < 7)
        shortchan = NULL;
    else {
        /* !channels have 5 chars long identification string before
           it's name, it's not known when /join is called so rename
           !channel here to !ABCDEchannel */
        shortchan = g_strdup_printf("!%s", channel+6);
        chanrec = channel_find_unjoined(server, shortchan);
        if (chanrec != NULL) {
            channel_change_name(CHANNEL(chanrec), channel);
            g_free(chanrec->name);
            chanrec->name = g_strdup(channel);
        } else {
            /* well, did we join it with full name? if so, and if
               this was the first short one, change it's name. */
            chanrec = channel_find_unjoined(server, channel);
            if (chanrec != NULL &&
                    irc_channel_find(server, shortchan) == NULL) {
                channel_change_visible_name(CHANNEL(chanrec),
                                            shortchan);
            }
        }
    }

    chanrec = irc_channel_find(server, channel);
    if (chanrec != NULL && chanrec->joined) {
        /* already joined this channel - probably a broken proxy that
           forgot to send PART between */
        chanrec->left = TRUE;
        channel_destroy(CHANNEL(chanrec));
        chanrec = NULL;
    }

    if (chanrec == NULL) {
        /* look again, because of the channel name cut issues. */
        chanrec = channel_find_unjoined(server, channel);
    }

    if (chanrec == NULL) {
        /* didn't get here with /join command.. */
        chanrec = irc_channel_create(server, channel, shortchan, TRUE);
    }

    chanrec->joined = TRUE;
    if (g_strcmp0(chanrec->name, channel) != 0) {
        g_free(chanrec->name);
        chanrec->name = g_strdup(channel);
    }

    g_free(shortchan);
    g_free(params);
}