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

📄 pushregistry.c

📁 用于移动设备上的java虚拟机源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * @(#)pushregistry.c	1.42 02/10/22 @(#) * * Copyright (c) 1999-2002 Sun Microsystems, Inc.  All rights reserved. * PROPRIETARY/CONFIDENTIAL * Use is subject to license terms. *//*========================================================================= * Virtual Machine *========================================================================= * SYSTEM:    MIDP native * SUBSYSTEM: Push Registry Persistent File Management * FILE:      pushregistry.c * OVERVIEW:  Opens the push registry file and caches the contents in *            memory at startup. Subsequent additions and deletions *            update the cache and rewrite the persistent data file. *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include "kni.h"#include <stdio.h>#include "midpMalloc.h"#include "storage.h"#ifdef UNIX#include <poll.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#else#include <windows.h>#ifndef atoll#define atoll(x) _atoi64(x)#endif /* atoll */#ifdef GCC#include <winsock.h>#else#ifndef _WINSOCKAPI_#include <winsock2.h>#endif /* _WINSOCKAPI_ */#endif /* GCC */#endif /* UNIX */#include <errno.h>static char *appdir = NULL;static char *pushpathname = NULL;static char *alarmpathname = NULL;static int  pushfd; static char *errStr = NULL;/* buffer size for line parsing */#define MAX_LINE 512#ifndef MAX_HOST_LENGTH#define MAX_HOST_LENGTH 256#endif /* MAX_HOST_LENGTH */#ifndef MAX_DATAGRAM_LENGTH#define MAX_DATAGRAM_LENGTH 1500#endif /* MAX_DATAGRAM_LENGTH */typedef struct _datagramentry {    int ipAddress;    int port;    int length;    char buffer[MAX_DATAGRAM_LENGTH];} DatagramEntry;typedef struct _pushentry {    struct _pushentry *next;    char *value;    char *storagename;    char *filter;    int fd;     int fdsock;     int port;     int state;    DatagramEntry *dg; } PushEntry;typedef struct _alarmentry {    struct _alarmentry *next;    char *midlet;    char *storagename;    jlong wakeup;} AlarmEntry;#define LAUNCH_PENDING  (-4)#define CHECKED_IN  (-3)#define CHECKED_OUT (-2)#define AVAILABLE   (-1)static PushEntry *pushlist = NULL;static AlarmEntry *alarmlist = NULL;static int pushlength = 0;static void pushProcessPort(char *buffer, int *fd, int *port);static void alarmopen();static void alarmsave();static int alarmadd(char *str, jlong alarm, jlong *lastalarm);static jlong alarmcheck(jlong time);static void pushListFree();static void alarmListFree();static char *pushfindfd(jlong fd);static int parsePushList ();static int checkfilter(char *filter, char *ip);static void pushcheckinentry(PushEntry *p);static void pushcleanupentry(PushEntry *p);/* * Extract the storage name from the connection value string */static char *pushstorage(char *value, int field) {    char *storagefield;    char *storagename= NULL;    int comma = 0 ;        for (storagefield = value; *storagefield; storagefield++) {	if (*storagefield == ',')	    comma ++;	/* Push entry contains "connection, midletname, filter, storage" */	/* Alarm entry contains "midletname, alarm, storage" */	if (comma == field) {	    storagename = storagefield + 1;	    break;	}    }    return storagename;}/* * Extract the filter from the connection value string */static char *pushfilter(char *value) {    char *filterfield = NULL;    char filter[MAX_HOST_LENGTH];    int i = 0 ;        /* Push entry contains "connection, midletname, filter, storage" */    for (filterfield = pushstorage(value, 2); *filterfield; filterfield++) {	if (*filterfield == ',')	    break;	filter[i++] = *filterfield;    }    filter[i] = '\0';    return midpStrdup(filter);}/* * Open the Push Registry file, if it exists and populate * an in memory cache of the file contents. */void pushopen() {    /* Make sure the network is properly in itialized. */    networkInit();    /* Get the storage directory. */    if (appdir == NULL) {	/*	 * On first use initialize the fully qualified pathnames	 * of the push and alarm persistent files.	 */	if ((appdir = getStorageRoot()) != NULL) {	    if (pushpathname = (char*) midpMalloc(strlen(appdir) +  13)) {		strcpy(pushpathname, appdir);		strcat(pushpathname, "pushlist.txt");	    }	    if (alarmpathname = (char*) midpMalloc(strlen(appdir) +  14)) {		strcpy(alarmpathname, appdir);		strcat(alarmpathname, "alarmlist.txt");	    }	} else {	    /* NYI - no storage directory found. */	}        /*         * If no memory can be allocated, exit.         */        if (appdir == NULL || pushpathname == NULL || alarmpathname == NULL) {            fprintf(stderr, "Error: pushopen out of memory.\n");            exit(-1);        }    }    /* Now read the registered connections.*/    if ((pushfd = storageOpen(&errStr, pushpathname, OPEN_READ)) != -1){	/* Read through the file one line at a time */	if (parsePushList() == -2) {        fprintf(stderr, "Error: pushopen out of memory "                        "when parsing push list.\n");        exit(-1);    }		/* Close the storage handle */	storageClose (&errStr, pushfd);    } else {	if (errStr != NULL) {	    /*	    fprintf (stderr, "Warning: could not open push registration file(%s): %s\n",		    pushpathname, errStr); */	    storageFreeError(errStr);	}    }    alarmopen();}/* * Destroy the push and alarm memory resources. Maintain the push * registrations in the push registry file. */void pushclose() {    pushListFree();    alarmListFree();    midpFree(pushpathname);    midpFree(alarmpathname);}/* * Save the in memory cache of push registrations to a persistent * file for use in subsequent runs. */static void pushsave() {    PushEntry *p;    if ((pushfd = storageOpen(&errStr, pushpathname, OPEN_READ_WRITE_TRUNCATE)) != -1){	/* Write a new list of push registrations to the persistent file */	for (p = pushlist; p != NULL ; p = p->next) {	    storageWrite(&errStr, pushfd, p->value, strlen(p->value));	    storageWrite(&errStr, pushfd, "\n", 1);	}	/* Close the storage handle */	storageClose (&errStr, pushfd);    } else {	if (errStr != NULL) {	    fprintf (stderr, "Warning: could not write push registration file(%s): %s\n",		     pushpathname, errStr); 	    storageFreeError(errStr);	    return;	}    }}/* * Add one entry to the push registry. * If the entry already exists return an error. * On succesful registration, write a new copy of the file to disk. * Return -2 if out of memory */static int pushadd(char *str){    PushEntry *p;    PushEntry *pe;    int comma;    char *cp;    /* Count the characters up to the first comma. */    for (comma = 0, cp = str; *cp; comma++, cp++) {	if (*cp == ',') {	    break;	}    }    /* Check if the entry already exists? */    for (p = pushlist; p != NULL ; p = p->next) {	if (strncmp (str, p->value, comma) == 0) {	    return -1 ;	}    }    /* Add the new entry. */    if (pe = (PushEntry *) midpMalloc (sizeof(PushEntry))){        pe->next = pushlist ;        pe->value = midpStrdup(str);        pe->storagename = midpStrdup(pushstorage(pe->value, 3));        if ((pe->value == NULL) || (pe->storagename == NULL)) {            midpFree(pe->value);            midpFree(pe->storagename);            midpFree(pe);            return -2;        } else {            pe->filter = pushfilter(pe->value);            pushProcessPort(str, &(pe->fd), &(pe->port));            pe->state = AVAILABLE ;            pe->fdsock = -1;            pe->dg = NULL;            pushlist = pe ;            pushlength++;        }    }    if (pe != NULL) {        pushsave();        return 0;     }    return -2;}/* * Remove one entry from the push registry. * If the entry is not registered return an error. * On successful deletion, write a new copy of the file to disk. */static int pushdel(char *str, char *store) {    PushEntry *p;     PushEntry *lastp = pushlist;    PushEntry *tmp;    /* Find the entry to remove */    for (p = pushlist; p != NULL ; p = tmp) {	tmp = p->next;	if (strncmp (str, p->value, strlen(str)) == 0) {	    /* Check if the connection belongs to another suite. */	    if (strcmp(store, p->storagename) != 0) {		return -2 ;	    }	    /* 	     * Close the socket connection if the entry is being removed.	     * Only close the connection, if it is not already opened	     * by the application or in the middle of fielding a	     * connection notification.	     */	    if (p->fd != -1 &&		p->state != LAUNCH_PENDING &&		p->state != CHECKED_OUT) {		prim_com_sun_midp_io_j2me_serversocket_Protocol_close(p->fd);		p->fd = -1;	    }	    /* Clear the pending notification flag. */	    if (p->state != LAUNCH_PENDING) { 		p->state = AVAILABLE;	    }            pushcleanupentry(p);            /* Remove the registration entry. */            if (p == pushlist){                /* Replace the top of the list. */                pushlist = p->next;            } else {                lastp->next = p->next;            }            pushlength-- ;		            midpFree(p->value);            p->value = NULL;		            midpFree(p->filter);            p->filter = NULL;		            midpFree(p->storagename);            p->storagename = NULL;		            midpFree(p);            pushsave();	    return 0;	}	lastp = p ;    }    return -1; }/* *  Fetch a buffer datagram */int pusheddatagram (int fd, int *ip, int *port, char *buf, int len) {    PushEntry *p;     PushEntry *tmp;    int length = -1;    /* Find the entry to pass off the open file descriptor. */    for (p = pushlist; p != NULL ; p = tmp) {	tmp = p->next;	if (p->fd == fd) {	    /* Return the cached data. */	    if (p->dg == NULL) {		return -1;	    }	    *ip = p->dg->ipAddress;	    *port = p->dg->port;	    length = p->dg->length;	    if (length > 0) {		memcpy(buf, p->dg->buffer, (len < length? len : length));	    }	    	    /* Destroy the cached entry after it has been read. */	    midpFree(p->dg);	    p->dg = NULL;	    return length;	}    }    return -1; }/* * Check out the file descriptor for the requested server socket. */int pushcheckoutaccept(int fd) {    PushEntry *p;     PushEntry *tmp;    int temp;    /* Find the entry to pass off the open file descriptor. */    for (p = pushlist; p != NULL ; p = tmp) {	tmp = p->next;	if (p->fd == fd) {	    temp = p->fdsock;	    p->fdsock = -1;	    return temp;	}    }    return -1; }/* * Check out the file descriptor for the requested connection. * Returns -1 if the connection is not found, other wise returns * the previously opened file descriptor. The CHECKED_OUT token  * is left in the table to indicate that an application is * actively using the connection. */int pushcheckout(char* protocol, int port, char * store) {    PushEntry *p;     PushEntry *tmp;    int fd;    /* Find the entry to pass off the open file descriptor. */    for (p = pushlist; p != NULL ; p = tmp) {	tmp = p->next;	if (p->port == port &&	    strncmp(p->value, protocol, strlen(protocol)) == 0) {	    /* Check if the current suite reserved the port. */	    if (strcmp(store, p->storagename) != 0) { 		return -2;	    }	    fd = p->fd;	    p->state = CHECKED_OUT;	    return fd;	}    }    return -1; }/* * Check in the file descriptor for the requested connection. * Returns 0 on success, or -1 on failure to check in the  * file descriptor to the cached push registry. */int pushcheckin(int fd) {    PushEntry *p;     PushEntry *lastp = pushlist;    PushEntry *tmp;    /* Find the entry to pass off the open file descriptor. */    for (p = pushlist; p != NULL ; p = tmp) {	tmp = p->next;	if (p->fd == fd) {            if (p->state == CHECKED_OUT) {                pushcheckinentry(p);            }	    return 0;	}	lastp = p ;    }    return -1; }/* * Check in the connections. Used between VM starts by main. */void pushcheckinall() {    PushEntry *p;     PushEntry *lastp = pushlist;    PushEntry *tmp;    /* Find the entry to pass off the open file descriptor. */    for (p = pushlist; p != NULL ; p = tmp) {	tmp = p->next;        pushcheckinentry(p);	lastp = p ;    }}/* * Check in the file descriptor connection for the requested connection, * given the connection name. * Returns 0 on success, or -1 on failure to check in the  * file descriptor to the cached push registry. */int pushcheckinbyname(char* str) {    PushEntry *p;     PushEntry *lastp = pushlist;    PushEntry *tmp;    /* Find the entry to remove */    for (p = pushlist; p != NULL ; p = tmp) {	tmp = p->next;	if (strncmp (str, p->value, strlen(str)) == 0) {            pushcheckinentry(p);            return 0;	}	lastp = p ;    }    return -1; }/* * Check in the push entry and cleanup anything the MIDlet did not get. */static void pushcheckinentry(PushEntry *p) {    p->state = CHECKED_IN;    pushcleanupentry(p);}/* * Cleanup anything the MIDlet did not get. */static void pushcleanupentry(PushEntry *p) {    /* Close any accepted socket not accessed, yet (if any). */    if (p->fdsock != -1) {        prim_com_sun_midp_io_j2me_socket_Protocol_close0(p->fdsock);        p->fdsock = -1;    }    /* Remove the cached datagram (if any). */    if (p->dg != NULL) {        midpFree(p->dg);        p->dg = NULL;    }}/*

⌨️ 快捷键说明

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