/* return 0 if good, 1 if not */ GOOD_OR_BAD Cache_Add_SlaveSpecific(const void *data, const size_t datasize, const struct internal_prop *ip, const struct parsedname *pn) { struct tree_node *tn; time_t duration; //printf("Cache_Add_SlaveSpecific\n"); if (!pn) { return gbGOOD; // do check here to avoid needless processing } duration = TimeOut(ip->change); if (duration <= 0) { return gbGOOD; /* in case timeout set to 0 */ } tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + datasize); if (!tn) { return gbBAD; } LEVEL_DEBUG("Adding internal data for "SNformat " size=%d", SNvar(pn->sn), (int) datasize); LoadTK( pn->sn, ip->name, EXTENSION_INTERNAL, tn ); tn->expires = duration + NOW_TIME; tn->dsize = datasize; if (datasize) { memcpy(TREE_DATA(tn), data, datasize); } //printf("ADD INTERNAL name= %s size=%d \n",tn->tk.p.nm,tn->dsize); //printf(" ADD INTERNAL data[0]=%d size=%d \n",((BYTE *)data)[0],datasize); switch (ip->change) { case fc_persistent: return Add_Stat(&cache_pst, Cache_Add_Persistent(tn)); default: return Add_Stat(&cache_int, Cache_Add_Common(tn)); } }
/* return 0 if good, 1 if not */ GOOD_OR_BAD Cache_Add_Device(const int bus_nr, const BYTE * sn) { time_t duration = TimeOut(fc_presence); struct tree_node *tn; if (duration <= 0) { return gbGOOD; /* in case timeout set to 0 */ } if ( sn[0] == 0 ) { //bad serial number return gbGOOD ; } tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + sizeof(int)); if (!tn) { return gbBAD; } LEVEL_DEBUG("Adding device location " SNformat " bus=%d", SNvar(sn), (int) bus_nr); LoadTK(sn, Device_Marker, 0, tn ); tn->expires = duration + NOW_TIME; tn->dsize = sizeof(int); memcpy(TREE_DATA(tn), &bus_nr, sizeof(int)); return Add_Stat(&cache_dev, Cache_Add_Common(tn)); }
static struct family_node * create_family_node( char * s_family ) { int l_family = strlen(s_family)+1; struct family_node * s = owmalloc( sizeof(struct family_node) + l_family ) ; if ( s==NULL) { return NULL ; } memset( s, 0, sizeof(struct family_node) + l_family ) ; s->family = s->payload ; strcpy( s->family, s_family ) ; // fill some of device fields s->dev.count_of_filetypes = 0 ; // until known s->dev.family_code = s->family ; s->dev.readable_name = s->family ; s->dev.filetype_array = NULL ; // until known s->dev.flags = 0 ; s->dev.g_read = NULL ; s->dev.g_write = NULL ; return s ; }
/* Parse a path/file combination */ ZERO_OR_ERROR FS_ParsedNamePlus(const char *path, const char *file, struct parsedname *pn) { ZERO_OR_ERROR ret = 0; char *fullpath; if (path == NO_PATH) { path = "" ; } if (file == NULL) { file = "" ; } fullpath = owmalloc(strlen(file) + strlen(path) + 2); if (fullpath == NO_PATH) { RETURN_CODE_RETURN( 79 ) ; // unable to allocate memory } strcpy(fullpath, path); if (fullpath[strlen(fullpath) - 1] != '/') { strcat(fullpath, "/"); } strcat(fullpath, file); //printf("PARSENAMEPLUS path=%s pre\n",fullpath) ; ret = FS_ParsedName(fullpath, pn); //printf("PARSENAMEPLUS path=%s post\n",fullpath) ; owfree(fullpath); //printf("PARSENAMEPLUS free\n") ; return ret; }
// Delete a serial number's alias // Safe to call if no alias exists // Also deletes from linked alias_sn file void Cache_Del_Alias(const BYTE * sn) { ASCII * alias_name ; struct tree_node *tn; size_t size ; alias_name = Cache_Get_Alias( sn ) ; if ( alias_name == NULL ) { // doesn't exist // (or a memory error -- unlikely) return ; } LEVEL_DEBUG("Deleting alias %s from "SNformat, alias_name, SNvar(sn)) ; size = strlen( alias_name ) ; tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + size + 1 ); if ( tn != NULL ) { tn->expires = NOW_TIME; tn->dsize = size; memcpy((ASCII *)TREE_DATA(tn), alias_name, size+1); // includes NULL LoadTK( sn, Alias_Marker, 0, tn ) ; Del_Stat(&cache_pst, Cache_Del_Persistent(tn)); Cache_Del_Alias_SN( alias_name ) ; } owfree( alias_name ) ; }
GOOD_OR_BAD OWQ_allocate_write_buffer( const char * write_buffer, size_t buffer_length, off_t offset, struct one_wire_query * owq ) { char * buffer_copy ; if ( buffer_length == 0 ) { // Buffer size is zero. Allowed, but make it NULL and no cleanup needed. OWQ_size(owq) = 0 ; OWQ_offset(owq) = 0 ; return gbGOOD ; } buffer_copy = owmalloc( buffer_length+1) ; if ( buffer_copy == NULL) { // cannot allocate space for buffer LEVEL_DEBUG("Cannot allocate %ld bytes for buffer", buffer_length) ; OWQ_size(owq) = 0 ; OWQ_offset(owq) = 0 ; return gbBAD ; } memcpy( buffer_copy, write_buffer, buffer_length) ; buffer_copy[buffer_length] = '\0' ; // make sure it's zero-ended OWQ_buffer(owq) = buffer_copy ; OWQ_size(owq) = buffer_length ; OWQ_length(owq) = buffer_length ; OWQ_offset(owq) = offset ; OWQ_cleanup(owq) |= owq_cleanup_buffer ; // buffer needs cleanup return gbGOOD ; }
/* Create the Parsename structure and create the buffer */ struct one_wire_query * OWQ_create_from_path(const char *path) { int sz = sizeof( struct one_wire_query ) + OWQ_DEFAULT_READ_BUFFER_SIZE; struct one_wire_query * owq = owmalloc( sz ); LEVEL_DEBUG("%s", path); if ( owq== NO_ONE_WIRE_QUERY) { LEVEL_DEBUG("No memory to create object for path %s",path) ; return NO_ONE_WIRE_QUERY ; } memset(owq, 0, sz); OWQ_cleanup(owq) = owq_cleanup_owq ; if ( GOOD( OWQ_parsename(path,owq) ) ) { if ( GOOD( OWQ_allocate_array(owq)) ) { /* Add a 1 byte buffer by default. This distinguishes from filesystem calls at end of buffer */ /* Read bufer is provided by OWQ_assign_read_buffer or OWQ_allocate_read_buffer */ OWQ_buffer(owq) = (char *) (& owq[1]) ; // point just beyond the one_wire_query struct OWQ_size(owq) = OWQ_DEFAULT_READ_BUFFER_SIZE ; return owq ; } OWQ_destroy(owq); } return NO_ONE_WIRE_QUERY ; }
/* Use an single OWQ as a template for the aggregate one */ struct one_wire_query * OWQ_create_aggregate( struct one_wire_query * owq_single ) { int sz = sizeof( struct one_wire_query ) + OWQ_DEFAULT_READ_BUFFER_SIZE; struct one_wire_query * owq_all = owmalloc( sz ); LEVEL_DEBUG("%s with extension ALL", PN(owq_single)->path); if ( owq_all == NO_ONE_WIRE_QUERY) { LEVEL_DEBUG("No memory to create object for extension ALL") ; return NO_ONE_WIRE_QUERY ; } memset(owq_all, 0, sz); OWQ_cleanup(owq_all) = owq_cleanup_owq ; memcpy( PN(owq_all), PN(owq_single), sizeof(struct parsedname) ) ; PN(owq_all)->extension = EXTENSION_ALL ; OWQ_buffer(owq_all) = (char *) (& owq_all[1]) ; // point just beyond the one_wire_query struct OWQ_size(owq_all) = OWQ_DEFAULT_READ_BUFFER_SIZE ; OWQ_offset(owq_all) = 0 ; if ( BAD( OWQ_allocate_array(owq_all)) ) { OWQ_destroy(owq_all); return NO_ONE_WIRE_QUERY ; } return owq_all ; }
static struct sensor_node * create_sensor_node( char * s_name, char * s_family, char * s_description, char * s_data ) { int l_name = strlen(s_name)+1; int l_family = strlen(s_family)+1; int l_description = strlen(s_description)+1; int l_data = strlen(s_data)+1; struct sensor_node * s = owmalloc( sizeof(struct sensor_node) + l_name + l_family + l_description + l_data ) ; if ( s==NULL) { return NULL ; } memset( s, 0, sizeof(struct sensor_node) + l_name + l_family + l_description + l_data ) ; s->name = s->payload ; strcpy( s->name, s_name ) ; s->family = s->name + l_name ; strcpy( s->family, s_family ) ; s->description = s->family + l_family ; strcpy( s->description, s_description ) ; s->data = s->description + l_description ; strcpy( s->data, s_data ) ; return s ; }
/* return 0 if good, 1 if not */ GOOD_OR_BAD Cache_Add_Dir(const struct dirblob *db, const struct parsedname *pn) { time_t duration = TimeOut(fc_directory); struct tree_node *tn; size_t size = DirblobElements(db) * SERIAL_NUMBER_SIZE; struct parsedname pn_directory; if (pn==NO_PARSEDNAME || pn->selected_connection==NO_CONNECTION) { return gbGOOD; // do check here to avoid needless processing } switch ( get_busmode(pn->selected_connection) ) { case bus_fake: case bus_tester: case bus_mock: case bus_w1: case bus_bad: case bus_unknown: return gbGOOD ; default: break ; } if (duration <= 0) { return 0; /* in case timeout set to 0 */ } if ( DirblobElements(db) < 1 ) { // only cache long directories. // zero (or one?) entry is possibly an error and needs to be repeated more quickly LEVEL_DEBUG("Won\'t cache empty directory"); Cache_Del_Dir( pn ) ; return gbGOOD ; } // allocate space for the node and data tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + size); if (!tn) { return gbBAD; } LEVEL_DEBUG("Adding directory for " SNformat " elements=%d", SNvar(pn->sn), DirblobElements(db)); // populate node with directory name and dirblob FS_LoadDirectoryOnly(&pn_directory, pn); LoadTK( pn_directory.sn, Directory_Marker, pn->selected_connection->index, tn ); tn->expires = duration + NOW_TIME; tn->dsize = size; if (size) { memcpy(TREE_DATA(tn), db->snlist, size); } return Add_Stat(&cache_dir, Cache_Add_Common(tn)); }
static struct BrowseStruct *Browse_Struct_Create(const char *name, const char *type, const char *domain) { struct BrowseStruct *browse_struct = owmalloc(sizeof(struct BrowseStruct)); if ( browse_struct == NULL ) { return NULL ; } browse_struct->name = ( name != NULL ) ? owstrdup(name) : NULL; browse_struct->type = ( type != NULL ) ? owstrdup(type) : NULL; browse_struct->domain = ( domain != NULL ) ? owstrdup(domain) : NULL; return browse_struct; }
/* allocate buffer but free unless able to read and parse nlm fully */ static GOOD_OR_BAD Get_and_Parse_Pipe( FILE_DESCRIPTOR_OR_ERROR file_descriptor, struct netlink_parse * nlp ) { struct nlmsghdr peek_nlm ; struct nlmsghdr * nlm ; size_t payload_length ; // first read start of message to get length and details if ( read( file_descriptor, &peek_nlm, W1_NLM_LENGTH ) != W1_NLM_LENGTH ) { ERROR_DEBUG("Pipe (w1) read header error"); return gbBAD ; } LEVEL_DEBUG("Pipe header: len=%u type=%u seq=%u|%u pid=%u ",peek_nlm.nlmsg_len,peek_nlm.nlmsg_type,NL_BUS(peek_nlm.nlmsg_seq),NL_SEQ(peek_nlm.nlmsg_seq),peek_nlm.nlmsg_pid); // allocate space nlm = owmalloc( peek_nlm.nlmsg_len ) ; nlp->nlm = nlm ; if ( nlm == NULL ) { LEVEL_DEBUG("Netlink (w1) Cannot allocate %d byte buffer for data", peek_nlm.nlmsg_len ) ; return gbBAD ; } memcpy( nlm, &peek_nlm, W1_NLM_LENGTH ) ; // copy header // read rest of packet if ( peek_nlm.nlmsg_len <= W1_NLM_LENGTH ) { owfree(nlm) ; LEVEL_DEBUG( "W1 packet error. Length is too short." ) ; return gbBAD ; } payload_length = peek_nlm.nlmsg_len - W1_NLM_LENGTH ; if ( read( file_descriptor, NLMSG_DATA(nlm), payload_length ) != (ssize_t) payload_length ) { owfree(nlm) ; nlp->nlm = NULL ; ERROR_DEBUG("Pipe (w1) read payload error"); return gbBAD ; } if ( BAD( Netlink_Parse_Buffer( nlp )) ) { LEVEL_DEBUG("Buffer parsing error"); owfree(nlm) ; nlp->nlm = NULL ; return gbBAD ; } // Good, the receiving routine should owfree buffer LEVEL_DEBUG("Pipe read --------------------"); Netlink_Parse_Show( nlp ) ; return gbGOOD ; }
/* HTTP encode */ char * httpescape( const char * original_string ) { const char * original_p = original_string ; char * escaped_string ; char * escaped_p ; if ( original_string == NULL ) { return NULL ; } escaped_p = escaped_string = owmalloc( strlen(original_string)*3 + 1 ) ; if ( escaped_string == NULL ) { return NULL ; } while (1) { switch ( *original_p ) { case '\0': *escaped_p = '\0' ; return escaped_string ; case ' ': case '!': case '"': case '#': case '$': case '%': case '@': case '\'': case '(': case ')': case '<': case '>': case ';': case ':': case '+': case ',': case '=': UCLIBCLOCK; escaped_p += sprintf( escaped_p, "%%%.2X", *original_p++ ) ; UCLIBCUNLOCK; break ; default: *escaped_p++ = *original_p++ ; break ; } } }
/* Alias name must be a null-terminated string */ static void Cache_Del_Alias_SN(const ASCII * alias_name) { // allocate space for the node and data size_t datasize = strlen(alias_name) ; struct alias_tree_node *atn = (struct alias_tree_node *) owmalloc(sizeof(struct alias_tree_node) + datasize + 1); if (atn==NULL) { return ; } // populate the node structure with data atn->expires = NOW_TIME; atn->size = datasize; memcpy( ALIAS_TREE_DATA(atn), alias_name, datasize+1 ) ; Cache_Del_Alias_Persistent( atn ) ; }
// create the buffer of size filesize GOOD_OR_BAD OWQ_allocate_read_buffer(struct one_wire_query * owq ) { struct parsedname * pn = PN(owq) ; size_t size = FullFileLength(pn); if ( size > 0 ) { char * buffer = owmalloc(size+1) ; if ( buffer == NULL ) { return gbBAD ; } memset(buffer,0,size+1) ; OWQ_buffer(owq) = buffer ; OWQ_size(owq) = size ; OWQ_offset(owq) = 0 ; OWQ_cleanup(owq) |= owq_cleanup_buffer ; } return gbGOOD; }
struct connection_out *NewOut(void) { size_t len = sizeof(struct connection_out); struct connection_out *now = (struct connection_out *) owmalloc(len); if (now) { memset(now, 0, len); now->next = Outbound_Control.head; Outbound_Control.head = now; now->index = Outbound_Control.next_index++; ++Outbound_Control.active ; // Zero sref's -- done with struct memset //now->sref0 = 0 ; //now->sref1 = 0 ; } else { LEVEL_DEFAULT("Cannot allocate memory for server structure,"); } return now; }
/* Return NULL if there is a problem */ char *DS9490_device_name(const struct usb_list *ul) { size_t len = 32 ; int sn_ret ; char * return_string = owmalloc(len+1); if ( return_string == NULL ) { return NULL ; } UCLIBCLOCK ; sn_ret = snprintf(return_string, len, "%.d:%.d", ul->usb_bus_number, ul->usb_dev_number) ; UCLIBCUNLOCK ; if (sn_ret <= 0) { SAFEFREE(return_string) ; } return return_string; }
/* return 0 if good, 1 if not */ GOOD_OR_BAD Cache_Add_Simul(const enum simul_type type, const struct parsedname *pn) { // Note: pn already points to directory time_t duration = TimeOut(fc_volatile); struct tree_node *tn; if (pn==NO_PARSEDNAME || pn->selected_connection==NO_CONNECTION) { return gbGOOD; // do check here to avoid needless processing } switch ( get_busmode(pn->selected_connection) ) { case bus_fake: case bus_tester: case bus_mock: case bus_bad: case bus_unknown: return gbGOOD ; default: break ; } if (duration <= 0) { return gbGOOD; /* in case timeout set to 0 */ } // allocate space for the node and data LEVEL_DEBUG("Adding for conversion time for "SNformat, SNvar(pn->sn)); tn = (struct tree_node *) owmalloc(sizeof(struct tree_node)); if (!tn) { return gbBAD; } LEVEL_DEBUG(SNformat, SNvar(pn->sn)); // populate node with directory name and dirblob LoadTK( pn->sn, Simul_Marker[type], pn->selected_connection->index, tn) ; LEVEL_DEBUG("Simultaneous add type=%d",type); tn->expires = duration + NOW_TIME; tn->dsize = 0; return Add_Stat(&cache_dir, Cache_Add_Common(tn)); }
/* returns null-terminated string */ ASCII * Cache_Get_Alias(const BYTE * sn) { struct tree_node tn; struct tree_opaque *opaque; ASCII * alias_name = NULL ; LoadTK(sn, Alias_Marker, 0, &tn ) ; PERSISTENT_RLOCK; opaque = tfind(&tn, &cache.persistent_tree, tree_compare) ; if ( opaque != NULL ) { alias_name = owmalloc( opaque->key->dsize + 1 ) ; if ( alias_name != NULL ) { memcpy( alias_name, (ASCII *)TREE_DATA(opaque->key), opaque->key->dsize+1 ) ; LEVEL_DEBUG("Retrieving " SNformat " alias=%s", SNvar(sn), alias_name ); } } PERSISTENT_RUNLOCK; return alias_name ; }
/* Alias name must be a null-terminated string */ INDEX_OR_ERROR Cache_Get_Alias_Bus(const ASCII * alias_name) { // allocate space for the node and data size_t datasize = strlen(alias_name) ; struct alias_tree_node *atn = (struct alias_tree_node *) owmalloc(sizeof(struct alias_tree_node) + datasize + 1); if (atn==NULL) { return INDEX_BAD ; } if (datasize==0) { owfree(atn) ; return INDEX_BAD ; } // populate the node structure with data atn->size = datasize; memcpy( ALIAS_TREE_DATA(atn), alias_name, datasize+1 ) ; return Cache_Get_Alias_Common( atn ) ; }
/* Alias name must be a null-terminated string */ GOOD_OR_BAD Cache_Get_Alias_SN(const ASCII * alias_name, BYTE * sn ) { // allocate space for the node and data size_t datasize = strlen(alias_name) ; struct alias_tree_node *atn ; if (datasize==0) { return gbBAD ; } atn = (struct alias_tree_node *) owmalloc(sizeof(struct alias_tree_node) + datasize+1); if (atn==NULL) { return gbBAD ; } // populate the node structure with data atn->size = datasize; memcpy( ALIAS_TREE_DATA(atn), alias_name, datasize+1 ) ; return Cache_Get_Alias_Persistent( sn, atn )==ctr_ok ? gbGOOD : gbBAD ; }
/* Add new license into device */ ZERO_OR_ERROR FS_w_PBM_activationcode(struct one_wire_query *owq) { struct connection_in * in = PN(owq)->selected_connection ; size_t size = OWQ_size(owq) ; BYTE * cmd_string = owmalloc( size+5 ) ; if ( cmd_string == NULL ) { return -ENOMEM ; } cmd_string[0] = 'k'; cmd_string[1] = 'a'; memcpy(&cmd_string[2], OWQ_buffer(owq), size ) ; cmd_string[size+2] = '\r'; // Writes from and to cmd_string PBM_SendCMD(cmd_string, size + 3, cmd_string, size + 3, in, 500); owfree(cmd_string) ; return 0; }
/* return 0 if good, 1 if not */ static GOOD_OR_BAD Cache_Add(const void *data, const size_t datasize, const struct parsedname *pn) { struct tree_node *tn; time_t duration; int persistent ; if (!pn || IsAlarmDir(pn)) { return gbGOOD; // do check here to avoid needless processing } // Special handling of Mock persistent = IsThisPersistent(pn) ; if ( persistent ) { duration = 1 ; } else { duration = TimeOut(pn->selected_filetype->change); if (duration <= 0) { return gbGOOD; /* in case timeout set to 0 */ } } // allocate space for the node and data tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + datasize); if (!tn) { return gbBAD; } LEVEL_DEBUG(SNformat " size=%d", SNvar(pn->sn), (int) datasize); // populate the node structure with data LoadTK( pn->sn, pn->selected_filetype, pn->extension, tn ); tn->expires = duration + NOW_TIME; tn->dsize = datasize; if (datasize) { memcpy(TREE_DATA(tn), data, datasize); } return persistent ? Add_Stat(&cache_pst, Cache_Add_Persistent(tn)) : Add_Stat(&cache_ext, Cache_Add_Common(tn)) ; }
GOOD_OR_BAD Netlink_Parse_Get( struct netlink_parse * nlp ) { struct nlmsghdr peek_nlm ; // first peek at message to get length and details LEVEL_DEBUG("Wait to peek at message"); int recv_len = recv( Inbound_Control.w1_monitor->pown->file_descriptor, &peek_nlm, W1_NLM_LENGTH, MSG_PEEK ); // Set time of last read _MUTEX_LOCK(Inbound_Control.w1_monitor->master.w1_monitor.read_mutex) ; timernow( &(Inbound_Control.w1_monitor->master.w1_monitor.last_read) ); _MUTEX_UNLOCK(Inbound_Control.w1_monitor->master.w1_monitor.read_mutex) ; LEVEL_DEBUG("Pre-parse header: %u bytes len=%u type=%u seq=%u|%u pid=%u",recv_len,peek_nlm.nlmsg_len,peek_nlm.nlmsg_type,NL_BUS(peek_nlm.nlmsg_seq),NL_SEQ(peek_nlm.nlmsg_seq),peek_nlm.nlmsg_pid); if (recv_len < 0) { ERROR_DEBUG("Netlink (w1) recv header error"); return gbBAD ; } // allocate space nlp->nlm = owmalloc( peek_nlm.nlmsg_len ) ; if ( nlp->nlm == NULL ) { LEVEL_DEBUG("Netlink (w1) Cannot allocate %d byte buffer for data",peek_nlm.nlmsg_len) ; return gbBAD ; } // read whole packet recv_len = recv( Inbound_Control.w1_monitor->pown->file_descriptor, &(nlp->nlm[0]), peek_nlm.nlmsg_len, 0 ); if (recv_len == -1) { ERROR_DEBUG("Netlink (w1) recv body error"); return gbBAD ; } if ( GOOD( Netlink_Parse_Buffer( nlp )) ) { LEVEL_DEBUG("Netlink read -----------------"); Netlink_Parse_Show( nlp ) ; return gbGOOD ; } return gbBAD ; }
/* return 0 if good, 1 if not */ GOOD_OR_BAD Cache_Add_Alias(const ASCII *name, const BYTE * sn) { struct tree_node *tn; size_t size = strlen(name) ; if ( size == 0 ) { return gbGOOD ; } tn = (struct tree_node *) owmalloc(sizeof(struct tree_node) + size + 1 ); if (!tn) { return gbBAD; } LEVEL_DEBUG("Adding alias for " SNformat " = %s", SNvar(sn), name); LoadTK( sn, Alias_Marker, 0, tn ); tn->expires = NOW_TIME; tn->dsize = size; memcpy((ASCII *)TREE_DATA(tn), name, size+1 ); // includes NULL Cache_Add_Alias_SN( name, sn ) ; return Add_Stat(&cache_pst, Cache_Add_Persistent(tn)); }
// Add a reg comp to tree if doesn't already exist static enum e_regcomp_test regcomp_test( regex_t * reg ) { struct s_regex * pnode = owmalloc( sizeof( struct s_regex ) ) ; struct s_regex * found ; void * result ; if ( pnode == NULL ) { LEVEL_DEBUG("memory exhuasted") ; return e_regcomp_error ; } pnode->reg = reg ; result = tsearch( (void *) pnode, ®ex_tree, reg_compare ) ; found = *(struct s_regex **) result ; if ( found == pnode ) { // new entry return e_regcomp_new ; } // existing entry owfree( pnode ) ; return e_regcomp_exists ; }
/* Use an aggregate OWQ as a template for a single element */ struct one_wire_query * OWQ_create_separate( int extension, struct one_wire_query * owq_aggregate ) { int sz = sizeof( struct one_wire_query ) + OWQ_DEFAULT_READ_BUFFER_SIZE; struct one_wire_query * owq_sep = owmalloc( sz ); LEVEL_DEBUG("%s with extension %d", PN(owq_aggregate)->path,extension); if ( owq_sep== NO_ONE_WIRE_QUERY) { LEVEL_DEBUG("No memory to create object for extension %d",extension) ; return NO_ONE_WIRE_QUERY ; } memset(owq_sep, 0, sz); OWQ_cleanup(owq_sep) = owq_cleanup_owq ; memcpy( PN(owq_sep), PN(owq_aggregate), sizeof(struct parsedname) ) ; PN(owq_sep)->extension = extension ; OWQ_buffer(owq_sep) = (char *) (& owq_sep[1]) ; // point just beyond the one_wire_query struct OWQ_size(owq_sep) = OWQ_DEFAULT_READ_BUFFER_SIZE ; OWQ_offset(owq_sep) = 0 ; return owq_sep ; }
/* Alias name must be a null-terminated string */ static void Cache_Add_Alias_SN(const ASCII * alias_name, const BYTE * sn) { // allocate space for the node and data size_t datasize = strlen(alias_name) ; struct alias_tree_node *atn = (struct alias_tree_node *) owmalloc(sizeof(struct alias_tree_node) + datasize + 1); if (atn==NULL) { return ; } if (datasize==0) { owfree(atn) ; return ; } // populate the node structure with data atn->expires = NOW_TIME; atn->size = datasize; memcpy( atn->sn, sn, SERIAL_NUMBER_SIZE ) ; memcpy( ALIAS_TREE_DATA(atn), alias_name, datasize+1 ) ; Cache_Add_Alias_Persistent( atn ) ; }
/* alias_name is a null-terminated string */ void Cache_Add_Alias_Bus(const ASCII * alias_name, INDEX_OR_ERROR bus) { // allocate space for the node and data size_t datasize = strlen(alias_name) ; struct alias_tree_node *atn = (struct alias_tree_node *) owmalloc(sizeof(struct alias_tree_node) + datasize + 1 ); time_t duration = TimeOut(fc_presence); if (atn==NULL) { return ; } if (datasize==0) { owfree(atn) ; return ; } // populate the node structure with data atn->expires = duration + NOW_TIME; atn->size = datasize ; atn->bus = bus ; memcpy( ALIAS_TREE_DATA(atn), alias_name, datasize + 1 ) ; Cache_Add_Alias_Common( atn ) ; }
// wrapper for regcomp // pmatch rm_so abd rm_eo handled internally // allocates (with owcalloc) and fills match_strings // Can be nmatch==0 and matched_strings==NULL for just a test with no return int ow_regexec( const regex_t * rex, const char * string, struct ow_regmatch * orm ) { if ( orm == NULL ) { // special case -- no matches saved if ( regexec( rex, string, 0, NULL, 0 ) != 0 ) { return -1 ; } return 0 ; } else { // case with saved matches int i ; int number = orm->number ; int len = strlen( string ) ; regmatch_t pmatch[ number + 2 ] ; // try the regexec on the string if ( regexec( rex, string, number+1, pmatch, 0 ) != 0 ) { LEVEL_DEBUG("Not found"); return -1 ; } // allocate space for the array of matches -- pointer array first orm->pre = owcalloc( sizeof( char * ) , 3*(number+1) ) ; if ( orm->pre == NULL ) { LEVEL_DEBUG("Memory allocation error"); return -1 ; } orm->match = orm->pre + number+1 ; orm->post = orm->match + number+1 ; for ( i=0 ; i < number+1 ; ++i ) { // Note last index is kept null orm->pre[i] = NULL ; orm->match[i] = NULL ; orm->post[i] = NULL ; } // not actual string array -- allocated as a buffer with space for pre,match and post // only need to allocat once per matched number for ( i=0 ; i < number+1 ; ++i ) { int s = pmatch[i].rm_so ; int e = pmatch[i].rm_eo ; if ( s != -1 && e != -1 ) { int l = e - s ; // each buffer is only slightly longer than original string (since contains string plus some EOS nulls orm->pre[i] = owmalloc( len + 3 ) ; if ( orm->pre[i] == NULL ) { LEVEL_DEBUG("Memory problem") ; ow_regexec_free( orm ) ; return -1 ; } // pre at start memset( orm->pre[i], 0 , len+3 ) ; memcpy( orm->pre[i], string, s ) ; // match next orm->match[i] = orm->pre[i] + s + 1 ; memcpy( orm->match[i], &string[s], l ) ; // then post orm->post[i] = orm->match[i] + l + 1 ; memcpy( orm->post[i], &string[e], len-e+1 ) ; LEVEL_DEBUG("%d: %d->%d found <%s><%s><%s>",i,s,e,orm->pre[i],orm->match[i],orm->post[i]) ; } } return 0 ; } }