#include #include #include #include using namespace std; static int no_link = 0xdeaddead; static char from_node[128], to_node[128], bridge_name[128]; static int from_port, to_port; static char *services = 0, *eservices = 0; static char *sstrings = 0, *rstrings = 0, *myown = 0; int n_replaces = 0; int max_replaces = 10; int poll_interval = 30; void get_srv_name_pub(char *srv_name, char *srv_name_pub) { char *p1, *p2, *ptrs, *ptrr; int i; strcpy(srv_name_pub, srv_name); if (n_replaces) { ptrs = sstrings; ptrr = rstrings; for (i = 0; i < n_replaces; i++) { p1 = strstr(srv_name_pub, ptrs); if (p1) { p2 = srv_name + (p1 - srv_name_pub); p2 += strlen(ptrs); *p1 = '\0'; strcat(p1, ptrr); strcat(p1, p2); } ptrs += strlen(ptrs) + 1; ptrr += strlen(ptrr) + 1; } } } class BridgeService: public DimStampedInfo { char srv_name[256]; char srv_name_pub[256]; char srv_format[256]; int declared; DimService *srv; void *srv_data, *data; int srv_size; int cmnd; int found; int copyFlag; time_t timestamp; int milliseconds; int quality; void infoHandler() { char *server; data = DimStampedInfo::getData(); srv_size = DimStampedInfo::getSize(); timestamp = getTimestamp(); milliseconds = getTimestampMillisecs(); quality = getQuality(); // Sometimes gets a packet from DIS_DNS not understood why!!!" server = DimClient::getServerName(); if(strstr(server,"DIS_DNS") != 0) { //dim_print_date_time(); //cout << "received from " << server << " size = " << srv_size << endl; if(strstr(srv_name,"DIS_DNS") == 0) return; } srv_data = data; if(*(int *)srv_data == no_link) { if(srv) { // dim_print_date_time(); // cout << "Deleting Service (no link)" << srv_name << endl; delete(srv); srv = 0; } declared = 0; // cout << "Disconnecting bridge for: " << srv_name << endl; poll_interval = 5; } else if(!declared) { // DimServer::setDnsNode(to_node); srv = new DimService(srv_name_pub, srv_format, srv_data, srv_size); if(copyFlag) srv->setData(srv_data, srv_size); srv->setQuality(quality); srv->setTimestamp(timestamp, milliseconds); DimServer::start(bridge_name); declared = 1; // DimClient::setDnsNode(from_node); } else { if(srv) { srv->setQuality(quality); srv->setTimestamp(timestamp, milliseconds); if (copyFlag) { srv->setData(srv_data, srv_size); srv->updateService(); } else { srv->updateService(srv_data, srv_size); } } } } public: BridgeService(char *name, char *format, int copy): DimStampedInfo(name, &no_link, sizeof(no_link)), declared(0), srv(0), copyFlag(copy) { strcpy(srv_format, format); strcpy(srv_name, name); get_srv_name_pub(srv_name, srv_name_pub); cmnd = 0; found = 1; // cout << "Bridging Service: " << name << endl; } BridgeService(char *name, char *format, int rate, int copy): DimStampedInfo(name, rate, &no_link, sizeof(no_link)), declared(0), srv(0), copyFlag(copy) { strcpy(srv_format, format); strcpy(srv_name, name); get_srv_name_pub(srv_name, srv_name_pub); cmnd = 0; found = 1; // cout << "Bridging Service: " << name << ", rate = " << rate << " seconds" << endl; } ~BridgeService() { if(declared) { if(srv) { delete(srv); srv = 0; } } declared = 0; // cout << "Stopped bridge for: " << srv_name << endl; } char *getName() { return srv_name; }; char *getNamePub() { return srv_name_pub; }; void clear() { found = 0; }; void set() {found = 1;}; int find() {return found;}; int isCmnd() { return cmnd;}; }; class BridgeCommand: public DimCommandHandler { char srv_name[256]; char srv_name_pub[256]; char srv_format[256]; int declared; // DimService *srv; DimCommand *srv; void *srv_data; int srv_size; int cmnd; int found; void commandHandler() { // srv_data = DimCommand::getData(); // srv_size = DimCommand::getSize(); srv_data = srv->getData(); srv_size = srv->getSize(); DimClient::sendCommandNB(srv_name, srv_data, srv_size); } public: BridgeCommand(char *name, char *format)/*:*/ // DimCommand(name, format) { cmnd = 1; found = 1; strcpy(srv_name, name); get_srv_name_pub(srv_name, srv_name_pub); srv = new DimCommand(srv_name_pub, format, this); DimServer::start(bridge_name); // cout << "Bridging Command: " << name << endl; } ~BridgeCommand() { // if (declared) // { if (srv) { // dim_print_date_time(); // cout << "Deleting Command " << srv_name << endl; delete(srv); srv = 0; } // } // declared = 0; // cout << "Stopped bridge for: " << srv_name << endl; } char *getName() { return srv_name; }; char *getNamePub() { return srv_name_pub; }; void clear() { found = 0; }; void set() {found = 1;}; int find() {return found;}; int isCmnd() { return cmnd;}; }; void print_usage_old() { cout << "Usage: DimBridge [from_node] to_node services [time_interval] [-copy]" << endl; cout << " from_node - by default DIM_DNS_NODE" << endl; cout << " to_node - the complete node name of the new DNS" << endl; cout << " services - the list of service names (wildcards allowed)" << endl; cout << " time_interval - the interval in seconds to be used for updating the services" << endl; cout << " -copy - copy internally the service data" << endl; } void print_usage() { cout << "Usage: DimBridge [-f(rom) [:]] -t(o) [:] -s [-e ] [-i(nterval) ] [-c(opy)] ([-r(replace) ])* " << endl; cout << " -f, -from\t\tfrom_node - the DNS node name (optionally a port number), by default DIM_DNS_NODE (DIM_DNS_PORT)" << endl; cout << " -t, -to\t\tto_node - the complete node name of the new DNS (optionally a port number)" << endl; cout << " -s, -services\tservices - the list of service names to bridge as a comma separated list of patterns" << endl; cout << " -e, -exclude\tservices - a list of service names to be excluded as a comma separated list of patterns" << endl; cout << " -i, -interval\ttime_interval - the interval in seconds to be used for updating the services" << endl; cout << " -c, -copy\t\tcopy internally the service data" << endl; cout << " -r, -replace\tsearch_string, replace_string - replace a part of the service name when bridging, can be repeated" << endl; } int parse_cmd_line(int argc, char **argv, int *rate, int *copyFlag) { int index = 1; char *ptrs, *ptrr; int size; char *ptr, *ptr1; int i; strcpy(from_node, DimClient::getDnsNode()); strcpy(to_node, ""); n_replaces = 0; *rate = 0; *copyFlag = 0; if (argc < 2) return 0; if (argv[1][0] != '-') // old style command line return -1; while (index < argc) { //cout << "arg" << index << " " << argv[index] << endl; if (argv[index][0] != '-') // bad command line return 0; if (argv[index][1] == 'f') { index++; if (index >= argc) return 0; strcpy(from_node, argv[index]); } else if (argv[index][1] == 't') { index++; if (index >= argc) return 0; strcpy(to_node, argv[index]); } else if (argv[index][1] == 's') { index++; if (index >= argc) return 0; services = (char *)malloc(strlen(argv[index])+1); strcpy(services, argv[index]); } else if (argv[index][1] == 'e') { index++; if (index >= argc) return 0; eservices = (char *)malloc(strlen(argv[index]) + 1); strcpy(eservices, argv[index]); } else if (argv[index][1] == 'i') { index++; if (index >= argc) return 0; sscanf(argv[index], "%d", rate); } else if (argv[index][1] == 'c') { *copyFlag = 1; } else if (argv[index][1] == 'r') { if (n_replaces == 0) { sstrings = (char *)malloc(max_replaces * MAX_NAME); rstrings = (char *)malloc(max_replaces * MAX_NAME); strcpy(sstrings, ""); strcpy(rstrings, ""); ptrs = sstrings; ptrr = rstrings; } index++; if (index >= argc) return 0; strcpy(ptrs, argv[index]); index++; if (index >= argc) return 0; strcpy(ptrr, argv[index]); ptrs += strlen(ptrs) + 1; ptrr += strlen(ptrr) + 1; n_replaces++; if (n_replaces == max_replaces) { max_replaces += 10; sstrings = (char *)realloc(sstrings, max_replaces * MAX_NAME); rstrings = (char *)realloc(rstrings, max_replaces * MAX_NAME); } } index++; } if (n_replaces) { size = n_replaces * MAX_NAME; myown = (char *)malloc(size); ptr = myown; ptr1 = rstrings; for (i = 0; i < (n_replaces - 1); i++) { strcpy(ptr, "*"); strcat(ptr, ptr1); strcat(ptr, "*,"); ptr += strlen(ptr); ptr1 += strlen(ptr1) + 1; } strcpy(ptr, "*"); strcat(ptr, ptr1); strcat(ptr, "*"); } if (!services) return 0; if ((to_node[0] == '\0') || (services[0] == '\0')) return 0; return 1; } int parse_cmd_line_old(int argc, char **argv, int *rate, int *copyFlag) { if (argc < 3) { return 0; } else if (argc == 3) { strcpy(from_node, DimClient::getDnsNode()); strcpy(to_node, argv[1]); services = (char *)malloc(strlen(argv[2]) + 1); strcpy(services, argv[2]); } else if (argc == 4) { // if(sscanf(argv[3],"%d", &rate)) if (isdigit(argv[3][0])) { sscanf(argv[3], "%d", rate); strcpy(from_node, DimClient::getDnsNode()); strcpy(to_node, argv[1]); services = (char *)malloc(strlen(argv[2]) + 1); strcpy(services, argv[2]); } else if (argv[3][0] == '-') { *rate = 0; strcpy(from_node, DimClient::getDnsNode()); strcpy(to_node, argv[1]); services = (char *)malloc(strlen(argv[2]) + 1); strcpy(services, argv[2]); *copyFlag = 1; } else { *rate = 0; strcpy(from_node, argv[1]); strcpy(to_node, argv[2]); services = (char *)malloc(strlen(argv[3]) + 1); strcpy(services, argv[3]); } } else if (argc == 5) { // if(sscanf(argv[4],"%d", &rate)) if (isdigit(argv[4][0])) { sscanf(argv[4], "%d", rate); strcpy(from_node, argv[1]); strcpy(to_node, argv[2]); services = (char *)malloc(strlen(argv[3]) + 1); strcpy(services, argv[3]); } else if (argv[4][0] == '-') { *copyFlag = 1; // if(sscanf(argv[3],"%d", &rate)) if (isdigit(argv[3][0])) { sscanf(argv[3], "%d", rate); strcpy(from_node, DimClient::getDnsNode()); strcpy(to_node, argv[1]); services = (char *)malloc(strlen(argv[2]) + 1); strcpy(services, argv[2]); } else { *rate = 0; strcpy(from_node, argv[1]); strcpy(to_node, argv[2]); services = (char *)malloc(strlen(argv[3]) + 1); strcpy(services, argv[3]); } } } else if (argc == 6) { strcpy(from_node, argv[1]); strcpy(to_node, argv[2]); services = (char *)malloc(strlen(argv[3]) + 1); strcpy(services, argv[3]); sscanf(argv[4], "%d", rate); *copyFlag = 1; } else { return 0; } return 1; } char ServerList_no_link[10] = ""; char ServiceList_no_link[10] = ""; typedef struct serv { struct serv *next; struct serv *prev; char name[MAX_NAME]; int type; char format[MAX_NAME]; int registered; void *serverPtr; void *browserServicePtr; } SERVICE; int multiple_match(const char*, const char*, int case_sensitive); int bridge_hash_service_init(); int bridge_hash_service_insert(SERVICE *); int bridge_hash_service_registered(int, SERVICE *); int bridge_hash_service_remove(SERVICE *); SERVICE *bridge_hash_service_exists(char *); SERVICE *bridge_hash_service_get_next(int *, SERVICE *, int); int bridge_hash_service_remove_many(int); /* class ServerInfo : public DimInfo, public SLLItem { char name[256]; void infoHandler() { char *data, *list, *format; char *ptr, *ptr1, *ptr2, *ptr3; int mode = 0, type; SERVICE *servp; data = DimInfo::getString(); // cout << "***** Received from Server : " << data << endl; list = new char[(int)strlen(data) + 1]; strcpy(list, data); ptr = list; if (*ptr == '\0') { } else if (*ptr == '+') { mode = 1; ptr++; } else if (*ptr == '-') { mode = -1; ptr++; } else { mode = 1; } while (*ptr) { if ((ptr1 = strchr(ptr, '\n'))) { *ptr1 = '\0'; ptr1++; } else { ptr1 = ptr; ptr1 += strlen(ptr); } if ((ptr2 = strchr(ptr, '|'))) { *ptr2 = '\0'; ptr2++; if ((ptr3 = strchr(ptr2, '|'))) { *ptr3 = '\0'; format = ptr2; ptr3++; if (*ptr3 == '\0') type = DimSERVICE; else if (*ptr3 == 'C') type = DimCOMMAND; else if (*ptr3 == 'R') type = DimRPC; } // cout << "***** Checking Service " << ptr << endl; if (!strcmp(ptr, bridge_name)) { ptr = ptr1; continue; } if (!strcmp(ptr, "DIS_DNS")) { ptr = ptr1; continue; } if (mode == 1) { if (type != DimRPC) { if (multiple_match(ptr, services, 1)) { poll_interval = 3; servp = (SERVICE *)malloc(sizeof(SERVICE)); strncpy(servp->name, ptr, (size_t)MAX_NAME); servp->type = type; strcpy(servp->format, format); servp->serverPtr = (void *)this; servp->registered = 0; bridge_hash_service_insert(servp); } } } else if (mode == -1) { poll_interval = 3; servp = bridge_hash_service_exists(ptr); if (servp) { // bridge_hash_service_remove(servp); // free(servp); servp->registered = -1; } } } ptr = ptr1; } } public: ServerInfo(char *server_name, char *service_name) : DimInfo(service_name, ServiceList_no_link) { strcpy(name, server_name); } ~ServerInfo() { SERVICE *servp; int hash_index; hash_index = -1; servp = 0; while ((servp = bridge_hash_service_get_next(&hash_index, servp, 0))) { if (servp->serverPtr == (void *)this) { servp->registered = -1; } } } char *getName(){ return name; } }; */ //int GotInitialList = 0; class ServerList : public DimInfo { // ServerInfo *srv, *aux_srv; char name[256], srv_name[256]; SLList servers; // char *serverList; // int serverListSize; void infoHandler() { char *data; // int size; // char *ptr; data = DimInfo::getString(); // dim_print_date_time(); // cout << "***** Received from DNS " << data << endl; /* size = (int)strlen(data) + 1; if (!serverListSize) { serverList = new char[size]; } else if (size > serverListSize) { delete serverList; serverList = new char[size]; serverListSize = size; } strcpy(serverList, data); if ((serverList[0] == '+') || (serverList[0] == '-')) */ if ((data[0] == '+') || (data[0] == '-')) { poll_interval = 3; // parseServerList(); } else if (data[0] == '\0') { poll_interval = 0; dim_print_date_time(); cout << "Disconnected from " << DimClient::getServerName() << endl; } else { poll_interval = 30; dim_print_date_time(); cout << "Connected to " << DimClient::getServerName() << endl; } // GotInitialList = 1; } public: ServerList(char *name) : DimInfo(name, ServerList_no_link) { } ~ServerList() { } // int parseServerList(); }; /* int ServerList::parseServerList() { char *ptr, *ptr1, *ptr2; int mode = 0; ptr = serverList; if (*ptr == '\0') { } else if (*ptr == '+') { mode = 1; ptr++; } else if (*ptr == '-') { mode = -1; ptr++; } else { mode = 1; } while (*ptr) { if ((ptr1 = strchr(ptr, '|'))) { *ptr1 = '\0'; ptr1++; } else { ptr1 = ptr; ptr1 += strlen(ptr); } if ((ptr2 = strchr(ptr, '@'))) { *ptr2 = '\0'; // dim_print_date_time(); // cout << "***** Checking Server " << ptr << endl; if (!strcmp(ptr, bridge_name)) { ptr = ptr1; continue; } if (!strcmp(ptr, "DIS_DNS")) { ptr = ptr1; continue; } if (mode == 1) { strcpy(srv_name, ptr); strcat(srv_name, "/SERVICE_LIST"); strcpy(name, ptr); dim_print_date_time(); cout << "***** Subscribing Server " << ptr << " " << srv_name << endl; srv = new ServerInfo(name, srv_name); servers.add(srv); } else if (mode == -1) { srv = (ServerInfo *)servers.getHead(); while (srv) { aux_srv = 0; // cout << "Checking remove " << ptr << " " << srv->getName() << endl; if (!(strcmp(srv->getName(), ptr))) { dim_print_date_time(); cout << "***** Removing Server " << srv->getName() << endl; servers.remove(srv); aux_srv = srv; break; } srv = (ServerInfo *)servers.getNext(); } if (aux_srv) { delete aux_srv; } } } ptr = ptr1; } return 1; } */ int checkBridgeServices() { SERVICE *servp; int hash_index; servp = 0; hash_index = -1; // dbr.getServices(services); // while ((type = dbr.getNextService(service, format))) while ((servp = bridge_hash_service_get_next(&hash_index, servp, 0))) { // if (servp->registered == 2) servp->registered = 1; } return 1; } int doBridgeService(char *service, char *format, int type) { SERVICE *servp; int ret = 0; if (!(servp = bridge_hash_service_exists(service))) { if (multiple_match(service, services, 1)) { if ((multiple_match(service, myown, 1)) || (multiple_match(service, eservices, 1))) { // poll_interval = 3; servp = (SERVICE *)malloc(sizeof(SERVICE)); strncpy(servp->name, service, (size_t)MAX_NAME); servp->type = type; strcpy(servp->format, format); // servp->serverPtr = (void *)this; servp->registered = 2; servp->browserServicePtr = (void *)0; bridge_hash_service_insert(servp); // cout << "Scanning " << service << "registered " << servp->registered << endl; ret = 1; } else { poll_interval = 3; servp = (SERVICE *)malloc(sizeof(SERVICE)); strncpy(servp->name, service, (size_t)MAX_NAME); servp->type = type; strcpy(servp->format, format); servp->browserServicePtr = (void *)0; servp->registered = 0; bridge_hash_service_insert(servp); // cout << "Scanning " << service << " registered " << servp->registered << endl; ret = 1; } } } else { servp->registered = 2; // cout << "Scanning " << service << "registered " << servp->registered << endl; ret = 2; } return ret; } int dontBridgeServices() { SERVICE *servp; int hash_index; servp = 0; hash_index = -1; // dbr.getServices(services); // while ((type = dbr.getNextService(service, format))) while ((servp = bridge_hash_service_get_next(&hash_index, servp, 0))) { if (servp->registered == 1) servp->registered = -1; } return 1; } int main(int argc, char **argv) { DimBrowser dbr; char *service, *format, *p; int type, known; BridgeService *ptrs; BridgeCommand *ptrc; int rate = 0; int copyFlag = 0; int i, ret, done; ServerList *serverList; SERVICE *servp; int hash_index; char *sptr, *rptr; //dic_set_debug_on(); // cout << "n pars " << argc << endl; // for (i = 0; i < argc; i++) // cout << "arg " << i << " " << argv[i] << endl; bridge_hash_service_init(); ret = parse_cmd_line(argc, argv, &rate, ©Flag); if (ret == -1) { ret = parse_cmd_line_old(argc, argv, &rate, ©Flag); if (!ret) { print_usage_old(); return 0; } } else if (!ret) { print_usage(); return 0; } cout << "Starting DimBridge from " << from_node << " to " << to_node << endl; cout << "for " << services << endl; if (eservices) { cout << "excluding " << eservices << endl; } if (n_replaces) { sptr = sstrings; rptr = rstrings; for (i = 0; i < n_replaces; i++) { cout << "replacing " << sptr << " by " << rptr << endl; sptr += strlen(sptr) + 1; rptr += strlen(rptr) + 1; } } if ((rate) || (copyFlag)) cout << "option(s):"; if (rate) cout << " update interval=" << rate; if ((rate) && (copyFlag)) cout << ","; if (copyFlag) cout << " internal data copy"; if ((rate) || (copyFlag)) cout << endl; strcpy(bridge_name,"Bridge_"); strcat(bridge_name, from_node); if ((p = strchr(bridge_name, ':'))) *p = '\0'; if ((p = strchr(bridge_name, ','))) *p = '\0'; if ((p = strchr(bridge_name, '.'))) *p = '\0'; /* strcat(bridge_name, "_"); strcat(bridge_name, to_node); if ((p = strchr(bridge_name, ':'))) *p = '\0'; if ((p = strchr(bridge_name, ','))) *p = '\0'; if ((p = strchr(bridge_name, '.'))) *p = '\0'; */ p = bridge_name + strlen(bridge_name); #ifndef WIN32 sprintf(p,"_%d",getpid()); #else sprintf(p,"_%d",_getpid()); #endif from_port = 0; to_port = 0; if ((p = strchr(from_node, ':'))) { *p = '\0'; p++; sscanf(p, "%d", &from_port); } if ((p = strchr(to_node, ':'))) { *p = '\0'; p++; sscanf(p, "%d", &to_port); } // cout << "Starting1 DimBridge from " << from_node << ":" << from_port <<" to " << to_node << ":" << to_port <<" for " << services << endl; if (!from_port) DimClient::setDnsNode(from_node); else DimClient::setDnsNode(from_node, from_port); if(!to_port) DimServer::setDnsNode(to_node); else DimServer::setDnsNode(to_node, to_port); serverList = new ServerList((char *)"DIS_DNS/SERVER_LIST"); if (serverList){} // to avoid a warning // while (!GotInitialList) // sleep(1); // serverList->parseServerList(); while (1) { done = 0; checkBridgeServices(); dbr.getServices("*"); while ((type = dbr.getNextService(service, format))) { doBridgeService(service, format, type); } dontBridgeServices(); servp = 0; hash_index = -1; while ((servp = bridge_hash_service_get_next(&hash_index, servp, 0))) { service = servp->name; type = servp->type; format = servp->format; // dim_print_date_time(); // cout << "Checking " << service << " reg "<< servp->registered << " type " << type << endl; known = servp->registered; if (known == 0) { done = 1; if(type == DimSERVICE) { dim_print_date_time(); cout << "Start Bridging Service: " << service << endl; if (!rate) ptrs = new BridgeService(service, format, copyFlag); else ptrs = new BridgeService(service, format, rate, copyFlag); servp->browserServicePtr = (void *)ptrs; } else if (type == DimCOMMAND) { dim_print_date_time(); cout << "Start Bridging Command: " << service << endl; // DimClient::setDnsNode(to_node); ptrc = new BridgeCommand(service, format); servp->browserServicePtr = (void *)ptrc; // DimClient::setDnsNode(from_node); } servp->registered = 1; } else if (known == -1) { done = -1; if (type == DimSERVICE) { ptrs = (BridgeService *)servp->browserServicePtr; if (ptrs) { dim_print_date_time(); cout << "Stop Bridging Service: " << ptrs->getName() << endl; delete ptrs; } } else if (type == DimCOMMAND) { ptrc = (BridgeCommand *)servp->browserServicePtr; if (ptrc) { dim_print_date_time(); cout << "Stop Bridging Command: " << ptrc->getName() << endl; delete ptrc; } } servp->registered = -2; } } if (poll_interval == 2) { // sleep(2); // dbr.getServices("*"); poll_interval = 5; // continue; } if (!done) { poll_interval = 30; } else if (done < 0) { bridge_hash_service_remove_many(-2); poll_interval = 2; } else { poll_interval = 5; } // cout << "done " << done << ", poll_interval " << poll_interval << endl; for (i = 0; i < poll_interval; i++) { sleep(1); if (poll_interval == 0) i = -2; } // cout << "out of sleep, poll_interval " << poll_interval << endl; } return 1; } ///////////////////////////// //////// Function for glob pattern matching. See http://www.cse.yorku.ca/~oz/ /* * robust glob pattern matcher * ozan s. yigit/dec 1994 * public domain * * glob patterns: * * matches zero or more characters * ? matches any single character * [set] matches any character in the set * [^set] matches any character NOT in the set * where a set is a group of characters or ranges. a range * is written as two characters seperated with a hyphen: a-z denotes * all characters between a to z inclusive. * [-set] set matches a literal hypen and any character in the set * []set] matches a literal close bracket and any character in the set * * char matches itself except where char is '*' or '?' or '[' * \char matches char, including any pattern character * * examples: * a*c ac abc abbc ... * a?c acc abc aXc ... * a[a-z]c aac abc acc ... * a[-a-z]c a-c aac abc ... * * $Log: glob.c,v $ * Revision 1.3 1995/09/14 23:24:23 oz * removed boring test/main code. * * Revision 1.2 94/12/11 10:38:15 oz * cset code fixed. it is now robust and interprets all * variations of cset [i think] correctly, including [z-a] etc. * * Revision 1.1 94/12/08 12:45:23 oz * Initial revision */ #ifndef NEGATE #define NEGATE '^' /* std cset negation char */ #endif #define TRUE 1 #define FALSE 0 int amatch(char *str, char *p) { int negate; int match; int c; while (*p) { if (!*str && *p != '*') return FALSE; switch (c = *p++) { case '*': while (*p == '*') p++; if (!*p) return TRUE; if (*p != '?' && *p != '[' && *p != '\\') while (*str && *p != *str) str++; while (*str) { if (amatch(str, p)) return TRUE; str++; } return FALSE; case '?': if (*str) break; return FALSE; /* * set specification is inclusive, that is [a-z] is a, z and * everything in between. this means [z-a] may be interpreted * as a set that contains z, a and nothing in between. */ case '[': if (*p != NEGATE) negate = FALSE; else { negate = TRUE; p++; } match = FALSE; while (!match && (c = *p++)) { if (!*p) return FALSE; if (*p == '-') { /* c-c */ if (!*++p) return FALSE; if (*p != ']') { if (*str == c || *str == *p || (*str > c && *str < *p)) match = TRUE; } else { /* c-] */ if (*str >= c) match = TRUE; break; } } else { /* cc or c] */ if (c == *str) match = TRUE; if (*p != ']') { if (*p == *str) match = TRUE; } else break; } } if (negate == match) return FALSE; /* * if there is a match, skip past the cset and continue on */ while (*p && *p != ']') p++; if (!*p++) /* oops! */ return FALSE; break; case '\\': if (*p) c = *p++; default: if (c != *str) return FALSE; break; } str++; } return !*str; } /////////////////////////////// END OF CODE FROM http://www.cse.yorku.ca/~oz/ char *strlwr(char *str) { unsigned char *p = (unsigned char *)str; while (*p) { *p = tolower((unsigned char)*p); p++; } return str; } // ps is a comma separated list of patterns. The function returns 1 as soon as one pattern matches int multiple_match(const char* str, const char* ps, int case_sensitive) { if (ps == 0) return 0; if (strlen(ps) == 0) return 0; char* str2 = new char[strlen(str) + 1]; strcpy(str2, str); char* p; // the pattern must be copied in new memory because strtok modifies the string char* p2 = new char[strlen(ps) + 1]; strcpy(p2, ps); if (case_sensitive == 0) { strlwr(str2); strlwr(p2); } p = strtok(p2, ","); int result = 0; while (p != NULL) { if (amatch(str2, p) == 1) { result = 1; break; } p = strtok(NULL, ","); } delete(p2); p2 = NULL; delete(str2); str2 = NULL; return result; } #define MAX_HASH_ENTRIES 5000 static SERVICE *BridgeService_hash_table[MAX_HASH_ENTRIES]; static int Service_new_entries[MAX_HASH_ENTRIES]; int bridge_hash_service_init() { int i; static int done = 0; dim_lock(); if (!done) { for (i = 0; i < MAX_HASH_ENTRIES; i++) { /* BridgeService_hash_table[i] = (SERVICE *) malloc(sizeof(SERVICE)); dll_init((DLL *) BridgeService_hash_table[i]); */ BridgeService_hash_table[i] = 0; Service_new_entries[i] = 0; } done = 1; } dim_unlock(); return(1); } int bridge_hash_service_insert(SERVICE *servp) { int index; dim_lock(); index = HashFunction(servp->name, MAX_HASH_ENTRIES); if (!BridgeService_hash_table[index]) { BridgeService_hash_table[index] = (SERVICE *)malloc(sizeof(SERVICE)); dll_init((DLL *)BridgeService_hash_table[index]); } Service_new_entries[index]++; dll_insert_queue((DLL *)BridgeService_hash_table[index], (DLL *)servp); dim_unlock(); return(1); } int bridge_hash_service_registered(int index, SERVICE *servp) { dim_lock(); servp->registered = 1; Service_new_entries[index]--; if (Service_new_entries[index] < 0) Service_new_entries[index] = 0; dim_unlock(); return 1; } int bridge_hash_service_remove(SERVICE *servp) { int index; dim_lock(); index = HashFunction(servp->name, MAX_HASH_ENTRIES); if (!BridgeService_hash_table[index]) { dim_unlock(); return(0); } dll_remove((DLL *)servp); dim_unlock(); return(1); } SERVICE *bridge_hash_service_exists(char *name) { int index; SERVICE *servp; dim_lock(); index = HashFunction(name, MAX_HASH_ENTRIES); if (!BridgeService_hash_table[index]) { dim_unlock(); return((SERVICE *)0); } if ((servp = (SERVICE *)dll_search( (DLL *)BridgeService_hash_table[index], name, (int)strlen(name) + 1))) { dim_unlock(); return(servp); } dim_unlock(); return((SERVICE *)0); } SERVICE *bridge_hash_service_get_next(int *curr_index, SERVICE *prevp, int new_entries) { int index; SERVICE *servp = 0; /* if(!prevp) { index = -1; } */ dim_lock(); index = *curr_index; if (index == -1) { index++; prevp = BridgeService_hash_table[index]; } if (!prevp) { prevp = BridgeService_hash_table[index]; } do { if (prevp) { if ((!new_entries) || (Service_new_entries[index] > 0)) { servp = (SERVICE *)dll_get_next( (DLL *)BridgeService_hash_table[index], (DLL *)prevp); if (servp) break; } } index++; if (index == MAX_HASH_ENTRIES) { *curr_index = -1; dim_unlock(); return((SERVICE *)0); } prevp = BridgeService_hash_table[index]; } while (!servp); *curr_index = index; dim_unlock(); return(servp); } int bridge_hash_service_remove_many(int registered) { SERVICE *servp, *prevp; int hash_index, old_index; int n = 0; dim_lock(); prevp = 0; hash_index = -1; old_index = -1; while ((servp = bridge_hash_service_get_next(&hash_index, prevp, 0))) { if (servp->registered == registered) { servp->registered = 0; bridge_hash_service_remove(servp); free(servp); n++; if (old_index != hash_index) prevp = 0; } else { prevp = servp; old_index = hash_index; } } dim_unlock(); return(n); }