char * om_string_implode(om_list_ptr list, const char sep) { int items = om_list_count(list); char separ[] = {sep,'\0'}; char *ret=OM_NULL; char *t=OM_NULL; for( int i=0; i<items; i++ ) { char *ptr = om_string_copy( om_list_get(list,i) ); if(ret==OM_NULL) { ret=ptr; } else { t=ret; ret = om_string_append(t,ptr); om_free(t); om_free(ptr); if( ret==OM_NULL ) { return OM_NULL; } } if( i<items-1 ) { t=ret; ret = om_string_append(t,separ); om_free(t); if( ret==OM_NULL ) { return OM_NULL; } } } return ret; }
int __om_unzip_makedir (om_unzip_archive_ptr archive, const char *rootExportPath, char *newdir) { char *buffer = om_string_copy(newdir); if( buffer==OM_NULL ) { return UNZ_INTERNALERROR; } char *p; int len = (int)strlen(newdir); if (len <= 0) return 0; // prefix with the location where we want to create the dir structure if( buffer[0]==OM_FS_FILE_SEP ) { p = om_string_append(rootExportPath,buffer); } else { p = om_string_format("%s%c%s",rootExportPath,OM_FS_FILE_SEP,buffer); } om_free(buffer); buffer = p; p = OM_NULL; // if the path ended with a '/', // then take that off if (buffer[len-1] == '/') { buffer[len-1] = '\0'; } if (__om_unzip_mymkdir(archive,buffer) == 0) { om_free(buffer); return 1; } p = buffer+1; while (1) { char hold; // we shouldn't need to create the rootExportPath if( strcmp(rootExportPath,buffer)==0 ) break; while(*p && *p != '\\' && *p != '/') p++; hold = *p; *p = 0; if ( (__om_unzip_mymkdir(archive,buffer) == -1) && (errno == ENOENT) ) { __om_unzip_append_error(archive,om_string_format("couldn't create directory %s\n",buffer)); om_free(buffer); return 0; } if ( hold == 0 ) break; *p++ = hold; } om_free(buffer); return 1; }
om_bool om_unzip_close_archive(om_unzip_archive_ptr archive) { om_bool ret = OM_TRUE; om_list_release(archive->error_log); om_free(archive->global_info_ptr); if( unzClose(archive->file) != UNZ_OK ) { ret=OM_FALSE; } om_free(archive); return ret; }
om_hash_enum om_hash_string_to_enum(const char * algorithm) { char *copy = om_string_toupper(algorithm); if( strcmp(copy,OmHashTypeMd5)==0 ) { om_free(copy);return OM_HASH_MD5; } if( strcmp(copy,OmHashTypeSha1)==0 ) { om_free(copy);return OM_HASH_SHA1; } om_free(copy);return 0; }
om_update_type_enum om_update_string_to_type_enum(const char *str) { char *copy = om_string_toupper(str); if( strcmp(copy,OmUpdateTypeRequired)==0 ) { om_free(copy);return OM_UPDATE_TYPE_REQUIRED; } if( strcmp(copy,OmUpdateTypeOptional)==0 ) { om_free(copy);return OM_UPDATE_TYPE_OPTIONAL; } if( strcmp(copy,OmUpdateTypeImmediate)==0 ) { om_free(copy);return OM_UPDATE_TYPE_IMMEDIATE; } if( strcmp(copy,OmUpdateTypeNone)==0 ) { om_free(copy);return OM_UPDATE_TYPE_NONE; } return 0; }
om_uint32 om_uint32_update_parse_helper( \ om_update_parse_type type, const char *str_in) { char * str = om_string_toupper(str_in); om_uint32 ret = 0; switch(type) { // update type enumeration case OM_UPDATE_TYPE: ret = (om_uint32)om_update_string_to_type_enum(str); break; case OM_UPDATE_HASH_TYPE: ret = (om_uint32)om_hash_string_to_enum(str); break; // om_uint32 products case OM_UPDATE_INSTALL_NEEDS: case OM_UPDATE_STORAGE_NEEDS: ret = (om_uint32)atoi(str); break; default: ret = 0; break; } om_free(str); return ret; }
void om_error_set_code(om_error_code code) { if( last_message!=OM_NULL ) { om_free(last_message); last_message=OM_NULL; } om_last_error_code = code; }
void om_error_clear() { om_last_error_code = OM_ERR_NONE; if( last_message!=OM_NULL ) { om_free(last_message); last_message=OM_NULL; } }
void om_error_set_format(om_error_code code, const char *format, ...) { char *str = om_malloc(OM_STRING_FORMAT_LIMIT+1); va_list ap; va_start(ap,format); vsnprintf(str, OM_STRING_FORMAT_LIMIT, format, ap); va_end(ap); om_error_set(code,str); om_free(str); }
void om_error_set(om_error_code code, const char * message) { om_error_set_code(code); if( last_message!=OM_NULL ) { om_free(last_message); last_message=OM_NULL; } if( om_last_error_code != OM_ERR_MALLOC ) last_message = om_string_copy(message); }
om_bool om_update_decision(om_config_ptr cfg) { om_uint32 * lastUpdate = om_config_get(cfg,OM_CFG_UPDATE_LAST_ATTEMPT); om_uint32 * updateFreq = om_config_get(cfg,OM_CFG_UPDATE_FREQ); om_bool * shouldPullUpdates = om_config_get(cfg,OM_CFG_UPDATE_SHOULD_PULL); om_bool shouldUpdate = OM_TRUE; if( //lastUpdate == OM_NULL || // may be null, if they've never attempted to update updateFreq == OM_NULL || shouldPullUpdates == OM_NULL ) { om_free(lastUpdate); om_free(updateFreq); om_free(shouldPullUpdates); return OM_FALSE; } if( shouldUpdate && lastUpdate!=OM_NULL ) { om_uint32 now = om_time(NULL); shouldUpdate = *updateFreq != 0 ? (now - *lastUpdate > *updateFreq) : OM_FALSE; } shouldUpdate = (*shouldPullUpdates) && shouldUpdate; om_free(lastUpdate); om_free(updateFreq); om_free(shouldPullUpdates); return shouldUpdate; }
char * om_string_format(const char *formatting, ...) { char *str = om_malloc(OM_STRING_FORMAT_LIMIT+1); if( str==OM_NULL ) return OM_NULL; va_list ap; va_start(ap,formatting); vsnprintf(str, OM_STRING_FORMAT_LIMIT, formatting, ap); va_end(ap); char *ret = om_string_copy(str); om_free(str); if( ret==OM_NULL ) return OM_NULL; return ret; }
om_unzip_archive_ptr om_unzip_open_archive(const char *file_path) { int err; unz_global_info * gip = om_malloc(sizeof(unz_global_info)); if( gip==OM_NULL ) { return OM_NULL; } unzFile uf = unzOpen(file_path); err = unzGetGlobalInfo(uf,gip); if( err!=UNZ_OK ) { om_free(gip); om_error_set(OM_ERR_ZIP_GLOBALINFO,"Error getting global info for the zip archive."); return OM_NULL; } om_list_ptr error_log = om_list_new(); if( error_log==OM_NULL ) { om_free(gip); return OM_NULL; } om_unzip_archive_ptr arch = om_malloc(sizeof(om_unzip_archive)); if( arch==OM_NULL ) { om_list_release(error_log); om_free(gip); return OM_NULL; } arch->error_log = error_log; arch->file = uf; arch->global_info_ptr = gip; return arch; }
OM_PRIVATE_FUNC char * __om_digest_md5_string(char *str) { cvs_MD5Context_t ctx; cvs_MD5Context_t *pctx=&ctx; memset(pctx,sizeof(cvs_MD5Context_t),0); unsigned char buffer[OM_DIGEST_BUFFER_LEN_MD5]; memset(buffer,0,OM_DIGEST_BUFFER_LEN_MD5); int r=0; unsigned char digest[16]; // update the md5 context for each chunk // of the md5 context cvs_MD5Init(pctx); char *end = str; end += strlen(str); for( str=str; str < end; str+=OM_DIGEST_BUFFER_LEN_MD5 ) { char * new_str = om_string_substr(str, 0, OM_DIGEST_BUFFER_LEN_MD5); r = strlen(new_str); cvs_MD5Update(pctx,new_str,r); om_free(new_str); } if( r==(-1) ) return OM_NULL; cvs_MD5Final(digest,pctx); // put the final md5 sum into a character array // and pass back int i; char * p = om_malloc(33); if( p==NULL ) return OM_NULL; unsigned char * ret = p; memset(p,33,0); for (i = 0; i < 16; i++) { sprintf (p, "%02x", digest[i]); p+=2; } return ret; }
OM_PRIVATE_FUNC char * __om_digest_sha1_string(char *str) { SHA1Context ctx; SHA1Context *pctx=&ctx; memset(pctx,0,sizeof(SHA1Context)); unsigned char buffer[OM_DIGEST_BUFFER_LEN_SHA1]; memset(buffer,0,OM_DIGEST_BUFFER_LEN_SHA1); int r=0; // update the md5 context for each chunk // of the md5 context SHA1Reset(pctx); char *end = str; end += strlen(str); for( str=str; str < end; str+=OM_DIGEST_BUFFER_LEN_MD5 ) { char * new_str = om_string_substr(str, 0, OM_DIGEST_BUFFER_LEN_MD5); r = strlen(new_str); SHA1Input(pctx,new_str,r); om_free(new_str); } if( r==(-1) ) return OM_NULL; SHA1Result(pctx); // put the final sha1 sum into a character array // and pass back char * p = om_malloc(41); if( p==NULL ) return OM_NULL; sprintf(p,"%08x%08x%08x%08x%08x", ctx.Message_Digest[0], ctx.Message_Digest[1], ctx.Message_Digest[2], ctx.Message_Digest[3], ctx.Message_Digest[4]); return p; }
/** * Makes the first run hit to usage.openmeap.com. * * Dear Developer/Project Management, * * We've created this function to make a single hit to our tracking url * per unique install. An effort has been made to make it secure and * non-reversible. An effort has been made so that, even should it fail, * it only happens once. * * We're hoping you'll leave this code functional in your production * release so that we can build-up value by tracking unique installs. * * Yours truly, OpenMEAP */ void om_first_run_check(om_config_ptr cfg) { // don't bother doing this in development mode. uint32 *d = om_config_get(cfg,OM_CFG_DEV_MODE); if( d!=OM_NULL ) { if( *d==1 ) { om_free(d); return; } else { om_free(d); } } uint32 *n = om_config_get(cfg,OM_CFG_NOT_FIRST_RUN); if( n==OM_NULL ) { // set this first, so even if the request fails // it never happens again. n = om_malloc(sizeof(uint32)); *n=1; om_config_set(cfg,OM_CFG_NOT_FIRST_RUN,n); // TODO: determine MAC hash and request to usage.openmeap.com/tracker.gif char * mac_address = om_net_get_mac_address(); char * mac_with_salt = om_string_format("%s.OPENMEAP#$!@3__234",mac_address); char * hash = om_digest_hash_string(mac_with_salt,OM_HASH_MD5); char * url = om_string_format("http://usage.openmeap.com/tracker.gif?hash=%s",hash); om_free(mac_with_salt); om_free(mac_address); om_free(hash); om_net_do_http_post(url,OM_NULL); om_free(url); } else { om_free(n); } }
void om_props_release(om_props_ptr props) { om_dict_release(props->device_data); om_free(props); }
void om_net_release_response(om_http_response_ptr response) { om_free(response->result); om_free(response); }
void om_dict_release_default_func(void *key, void *value, void *release_data) { om_free(key); om_free(value); }
void om_dict_release_prefs_by_name_func(void *key, void *value, void *release_data) { om_free(key); om_prefs_release(value); }
void __om_dict_release_entry_func(void* entry, void *release_data) { om_dict_entry_ptr ent = (om_dict_entry_ptr)entry; om_dict_ptr dict = (om_dict_ptr)release_data; __om_dict_free_key_value(dict,ent->key,ent->value); om_free(ent); }
void om_dict_release(om_dict_ptr dict) { om_dict_clear(dict); om_free(dict->buckets); om_free(dict); }
void om_prefs_release(om_prefs_ptr prefs) { om_dict_release((om_dict_ptr)prefs->device_data); om_free(prefs); }
void om_substring_release(om_substring_ptr str) { om_free(str); }
void om_mock_prefs_dict_release_entry(void * key, void * value, void * release_data) { om_free(key); om_free(value); }
void __om_malloc_debug_release_func(void *key, void *value, void *release_data) { // we don't free the key, as the key was a pointer value that had been alloc'd om_free(value); }
int __om_unzip_extract_currentfile( om_unzip_archive_ptr archive, const char *rootExportPath, om_uint32 options, const char *password ) { unzFile uf = archive->file; char filename_inzip[256]; char *filename_withoutpath; char *p; int err=UNZ_OK; FILE *fout=NULL; void *buf; uInt size_buf; unz_file_info file_info; uLong ratio = 0; err = unzGetCurrentFileInfo(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); if (err!=UNZ_OK) { __om_unzip_append_error(archive,om_string_format("error %d with zipfile in unzGetCurrentFileInfo\n",err)); return err; } size_buf = OM_ZIP_WRITEBUFFERSIZE; buf = (void*)om_malloc(size_buf); if (buf==NULL) { // Error allocating memory for the write buffer return UNZ_INTERNALERROR; } // this appears to be a string copy // some zip files do not put in a path p = filename_withoutpath = filename_inzip; while ((*p) != '\0') { // if the current character is a dir path separator // then the next character starts either a directory segment // or a file name if (((*p)=='/') || ((*p)=='\\')) filename_withoutpath = p+1; p++; } // if the element after the last '/' was a '\0', then this is a directory if ( (*filename_withoutpath) == '\0' ) { if( ! options & OM_ZIP_OPTS_NOPATH ) { char * full_file_path = om_string_format("%s%c%s",rootExportPath,OM_FS_FILE_SEP,filename_inzip); if(full_file_path==OM_NULL) { om_free(buf); return UNZ_INTERNALERROR; } __om_unzip_mymkdir(archive,full_file_path); om_free(full_file_path); } } // otherwise it was a file name else { char* write_filename; int skip=0; if( options & OM_ZIP_OPTS_NOPATH ) { write_filename = filename_withoutpath; } else { write_filename = filename_inzip; } err = unzOpenCurrentFilePassword(uf,password); if ( err != UNZ_OK ) { __om_unzip_append_error(archive,om_string_format("error %d with zipfile in unzOpenCurrentFilePassword\n",err)); return err; } // removed a file existence test here if ( skip == 0 && err == UNZ_OK ) { // the write_filename should, at this point, // have the relative directory on it // now we have to prepend with our rootExportPath char * full_file_path = om_string_format("%s%c%s",rootExportPath,OM_FS_FILE_SEP,write_filename); fout = fopen(full_file_path,"wb"); // some zipfile don't contain the directory alone before file if ( (fout==NULL) && (!(options & OM_ZIP_OPTS_NOPATH)) && (filename_withoutpath!=(char*)filename_inzip) ) { char c = *(filename_withoutpath-1); *(filename_withoutpath-1)='\0'; __om_unzip_makedir(archive,rootExportPath,write_filename); *(filename_withoutpath-1)=c; fout=fopen(full_file_path,"wb"); } om_free(full_file_path); if (fout==NULL) { __om_unzip_append_error(archive,om_string_format("error opening %s",write_filename)); om_free(buf); return UNZ_INTERNALERROR; } } if (fout!=NULL) { //printf(" extracting: %s\n",write_filename); do { err = unzReadCurrentFile(uf,buf,size_buf); if (err<0) { __om_unzip_append_error(archive,om_string_format("error %d with zipfile in unzReadCurrentFile\n",err)); break; } if (err>0) { if (fwrite(buf,err,1,fout)!=1) { __om_unzip_append_error(archive,om_string_format("error in writing extracted file\n")); err=UNZ_ERRNO; break; } } } while (err>0); if (fout) fclose(fout); // OpenMEAP doesn't care if the date of the files on the device // are the same as in the archive. // if (err==0) // change_file_date(write_filename,file_info.dosDate, file_info.tmu_date); } if (err==UNZ_OK) { err = unzCloseCurrentFile (uf); if (err!=UNZ_OK) { __om_unzip_append_error(archive,om_string_format("error %d with zipfile in unzCloseCurrentFile\n",err)); } } else { unzCloseCurrentFile(uf); /* don't lose the error */ } } om_free(buf); return err; }