⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 client.c

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 C
📖 第 1 页 / 共 2 页
字号:
/*                                                                        * Copyright (c) 2003 Century Software, Inc.   All Rights Reserved.      *                                                                        * This file is part of the PIXIL Operating Environment                  *                                                                        * The use, copying and distribution of this file is governed by one     * of two licenses, the PIXIL Commercial License, or the GNU General     * Public License, version 2.                                            *                                                                        * Licensees holding a valid PIXIL Commercial License may use this file  * in accordance with the PIXIL Commercial License Agreement provided    * with the Software. Others are governed under the terms of the GNU    * General Public License version 2.                                     *                                                                        * This file may be distributed and/or modified under the terms of the   * GNU General Public License version 2 as published by the Free         * Software Foundation and appearing in the file LICENSE.GPL included    * in the packaging of this file.                                       *                                                                        * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING   * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A             * PARTICULAR PURPOSE.                                                   *                                                                        * RESTRICTED RIGHTS LEGEND                                              *                                                                      * Use, duplication, or disclosure by the government is subject to       * restriction as set forth in paragraph (b)(3)(b) of the Rights in      * Technical Data and Computer Software clause in DAR 7-104.9(a).        *                                                                       * See http://www.pixil.org/gpl/ for GPL licensing        * information.                                                          *                                                                       * See http://www.pixil.org/license.html or               * email cetsales@centurysoftware.com for information about the PIXIL    * Commercial License Agreement, or if any conditions of this licensing  * are not clear to you.                                                 */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/un.h>#include <sys/poll.h>#include <ipc/colosseum.h>static int g_socket = 0;/* Define malloc debug if you are afraid that you aren't freeing all your mallocs */#ifdef MALLOC_DEBUGstatic int g_malloc = 0;#define CALLOC(size, count) debug_calloc(size, count)#define FREE(ptr) debug_free(ptr)#else#define CALLOC(size, count) calloc(size, count)#define FREE(ptr) free(ptr)#endif/* Define DEBUG to get lots of annoying printfs */#ifdef DEBUG#define DPRINT(str, args...) printf("DEBUG: "str, ## args)#else#define DPRINT(str, args...)#endif#define ERROR(str, args...) printf("ERROR: "str, ## args)#ifdef MALLOC_DEBUGstatic inline void *debug_calloc(int size, int count){    g_malloc++;    return (calloc(size, count));}static inline voiddebug_free(void *ptr){    g_malloc--;    return (free(ptr));}#endif/* To better handle dynamic packets, we use this structure instead of   the queue structure */typedef struct pbuffer{    cl_packet *packet;    int size;    struct pbuffer *next;}pkt_buff_t;static pkt_buff_t *pkt_queue = 0;static inline voidpkt_free(pkt_buff_t * buf){    if (!buf)	return;    if (buf->packet)	FREE(buf->packet);    FREE(buf);}static intclient_ServerDied(void){    printf("The Colosseum server closed unexpectedly\n");    ClClose();    return (CL_CLIENT_NOSRVR);}static voidclient_QueuePacket(pkt_buff_t * packet){    pkt_buff_t *head = pkt_queue;    if (!head)	pkt_queue = packet;    else {	for (; head->next; head = head->next);	head->next = packet;    }    DPRINT("Queued a packet of size [%d]\n", packet->size);    packet->next = 0;}static intclient_DequeuePacket(pkt_buff_t ** ret){    if (pkt_queue) {	*ret = pkt_queue;	pkt_queue = pkt_queue->next;	return (1);    }    return (0);}static intclient_SendToServer(int sock, unsigned char *data, int len){    int ret;    ret = write(sock, data, len);    if (ret <= 0) {	if (ret == 0)	    return (1);	return (-1);    }    return (0);}/* Grab a packet off of the server */intclient_GetFromServer(int sock, pkt_buff_t ** ret_buffer){    int ret;    int dsize = 0;    pkt_buff_t *buffer;    cl_pkt_header header;    struct pollfd pstruct;    pstruct.fd = sock;    pstruct.events = POLLIN;    ret = poll(&pstruct, 1, 0);    /* No data is available */    if (ret <= 0) {      if (ret == -1)	perror("client_GetFromServer");      return (ret);    }    /* Read the header */    ret = read(sock, &header, sizeof(header));    if (ret <= 0) {	if (errno == EAGAIN || ret == 0) {	  return (0);	}	perror("client_GetFromServer");	return (-1);    }    if (!header.len)	return (0);    buffer = *ret_buffer = (pkt_buff_t *) CALLOC(1, sizeof(pkt_buff_t));    if (!buffer) {	ERROR("Error - Out of memory in client_GetFromServer\n");	return (-1);    }    buffer->packet = (cl_packet *) CALLOC(header.len, 1);    dsize = header.len - sizeof(header);    if (!buffer->packet) {	pkt_free(buffer);	ERROR("Error - Out of memory in client_GetFromServer\n");	return (-1);    }    buffer->size = header.len;    memcpy(buffer->packet, &header, sizeof(header));    /* Now, read in the rest of the packet */    ret =	read(sock, (unsigned char *) buffer->packet + sizeof(header), dsize);    if (ret != dsize) {	/* No matter what, free the existing packet buffer */	pkt_free(buffer);	if (ret < 0) {	    if (errno == EAGAIN)		return (0);	    perror("client_GetFromServer");	    return (-1);	} else {	    ERROR("bad packet size - expected [%d], got [%d].\n", dsize, ret);	    return (-1);	}    }    return (header.len);}static intclient_WaitForData(int sock, int timeout){    fd_set iset, eset;    FD_ZERO(&iset);    FD_ZERO(&eset);    FD_SET(sock, &iset);    FD_SET(sock, &eset);    if (timeout) {	struct timeval tv;	tv.tv_sec = timeout / 1000000;	tv.tv_usec = timeout % 1000000;	return (select(sock + 1, &iset, 0, &eset, &tv));    } else	return (select(sock + 1, &iset, 0, &eset, 0));}static intclient_WaitForServer(int sock, int packet_type,		     pkt_buff_t ** pkt, int timeout){    int qcount = 0;    *pkt = 0;    do {	pkt_buff_t *buffer = 0;	cl_packet *data;	int ret;	/* Wait for the data to come in on the line */	ret = client_WaitForData(sock, timeout);	if (ret == 0)	    return (CL_CLIENT_TIMEOUT);	else if (ret == -1) {	    return (CL_CLIENT_ERROR);	}	ret = client_GetFromServer(sock, &buffer);	if (ret < 0) {	    return (CL_CLIENT_ERROR);	}	else if (ret == 0)	    return (CL_CLIENT_TIMEOUT);	data = (cl_packet *) buffer->packet;	if (data->header.type == packet_type) {	    *pkt = buffer;	    if (qcount)		write(sock, 0, 0);	    return (0);	}	if (data->header.type == CL_PKT_MESSAGE) {	    client_QueuePacket(buffer);	    DPRINT("While waiting for a %d, a Message packet was queued\n",		   packet_type);	    qcount++;	} else	    ERROR("Got type [%d] when expecting type [%d]\n",		  data->header.type, packet_type);    } while (1);}static intclient_MakeRequest(int sock, int packet_type,		   cl_packet * packet, int len, int timeout){    pkt_buff_t *buffer = 0;    int ret;    int size = 0;    packet->header.type = packet_type;    packet->header.len = len;    ret = client_SendToServer(sock, (unsigned char *) packet, len);    if (ret == -1) {	return (CL_CLIENT_ERROR);    } else if (ret == 1)	return (client_ServerDied());    bzero(packet, len);    ret = client_WaitForServer(sock, packet_type, &buffer, timeout);    if (ret < 0 || buffer == 0) {	ERROR("Got an error from client_WaitForServer\n");	pkt_free(buffer);	return (ret);    }    /* This is where we actually transfer the packet */    if (buffer->size != len)	ERROR("Unexpected size [%d] in client_MakeRequest\n", buffer->size);    if (buffer->size > CL_MAX_PKT_SIZE) {	ERROR("I refuse to try and handle a packet of size [%d]\n",	      buffer->size);	pkt_free(buffer);	return (CL_CLIENT_INVALID);    }    size = (len > buffer->size) ? buffer->size : len;    bzero(packet, len);    memcpy(packet, buffer->packet, size);    pkt_free(buffer);		/* Free the buffer - very important */    return (size);}static intlocal_Register(unsigned char *name, int inflags, int *outflags){    struct sockaddr_un saddr;    cl_pkt_reg pkt;    int ret;    if (!name)	return (CL_CLIENT_INVALID);    if (g_socket)	return (CL_CLIENT_CONNECTED);    /* First, create a socket and try to connect */    g_socket = socket(AF_UNIX, SOCK_STREAM, 0);    if (!g_socket) {	perror("Socket Error: ");	return (CL_CLIENT_SOCK_ERROR);    }    /* Try to connect to the named socket */    saddr.sun_family = AF_UNIX;    strncpy(saddr.sun_path, CL_NAMED_SOCKET, sizeof(saddr.sun_path));    /* Try to connect.  If the connection is refused, then we will */    /* assume that no server is available */    if (connect(g_socket, (struct sockaddr *) &saddr, sizeof(saddr)) == -1) {	close(g_socket);	g_socket = 0;	if ((errno == ECONNREFUSED) || (errno == ENOENT))	    return (CL_CLIENT_NOSRVR);	else	    return (CL_CLIENT_SOCK_ERROR);    }#ifdef NOTUSED    /* Now, make the socket non blocking */    if (fcntl(g_socket, F_SETFL, O_NONBLOCK)) {	close(g_socket);	g_socket = 0;	return (CL_CLIENT_SOCK_ERROR);    }#endif    bzero(&pkt, sizeof(pkt));    strncpy(pkt.name, name, CL_MAX_NAME_LEN);    pkt.start_flags = inflags;    ret = client_MakeRequest(g_socket, CL_PKT_REGISTER, (cl_packet *) & pkt,			     sizeof(pkt), 0);    if (ret < 0)	return (ret);    switch (pkt.header.resp) {    case CL_E_APPEXISTS:	return (CL_CLIENT_BADNAME);    case 0:	if (outflags)	    *outflags = pkt.start_flags;	return (g_socket);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -