/** * @return om_dict_ptr where the hash_func is the default om_dict_hash_string function */ om_dict_ptr om_dict_new(int size) { om_dict_ptr ret = om_malloc(sizeof(om_dict)); if( ret==OM_NULL ) { om_error_set( OM_ERR_MALLOC, "Could not allocate a new dict" ); return OM_NULL; } ret->hash_func = om_dict_hash_string; ret->bucket_count = size; ret->buckets = om_malloc(sizeof(om_list_ptr)*size); return ret; }
om_props_ptr om_props_acquire(const char *name) { om_props_ptr props = om_malloc(sizeof(om_props)); props->device_data = om_dict_new(15); //((om_dict_ptr)props->device_data))->copy_value_func props->get=om_mock_props_get; return props; }
char * om_string_decodeURI(const char *str) { // count characters to decode int i=0, charCount=0, len=strlen(str), lenMinus2=len-2; while(str[i]!=0) { if('%'==str[i]) { charCount+=1; } i++; } // allocate new string char *newStr = om_malloc( sizeof(char) * (len-(charCount*2)+1) ); // copy each character, decoding as we go i=0; for( int p=0; p<len; p++ ) { char *p2 = str+p; if( *p2=='%' && p<=lenMinus2 && om_string_is_hex_char(*(p2+1)) && om_string_is_hex_char(*(p2+2)) ) { char tmp[3]={om_char_toupper(*(p2+1)),om_char_toupper(*(p2+2)),'\0'}; sscanf(&tmp,"%X",newStr+i); p+=2; } else { newStr[i]=*p2; } i++; } // return new string return newStr; }
om_http_response_ptr om_net_do_http_post(const char *url, const char *post_data) { om_net_mock_vars_var->last_post_data = om_string_copy(post_data); om_http_response_ptr resp = om_malloc(sizeof(om_http_response)); resp->status_code = om_net_mock_vars_var->do_http_post_result->status_code; resp->result = om_string_copy(om_net_mock_vars_var->do_http_post_result->result); return resp; }
char * om_substring_copy(om_substring_ptr ptr) { char * ret = om_malloc((ptr->len+1)*sizeof(char)); if( ret==NULL ) { om_error_set(OM_ERR_MALLOC,"could not allocate to copy string in om_substring_copy()"); return OM_NULL; } memcpy(ret,ptr->str,ptr->len*sizeof(char)); return ret; }
char * om_string_copy(const char *str) { char *ret = om_malloc(sizeof(char)*strlen(str)+1); if( ret==NULL ) { om_error_set(OM_ERR_MALLOC,"Could not allocate to copy string in om_string_copy()"); return OM_NULL; } strcpy(ret,str); return ret; }
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); }
om_substring_ptr om_substring_new(const char *str, int len) { om_substring_ptr ret = om_malloc(sizeof(om_substring)); if( ret==NULL ) { om_error_set(OM_ERR_MALLOC,"Could not malloc() a new substring"); return OM_NULL; } ret->str = str; ret->len = len; return ret; }
om_dict_entry_ptr __om_dict_new_entry(void * key, void * val) { om_dict_entry_ptr ret = om_malloc(sizeof(om_dict_entry)); if( ret==NULL ) { om_error_set(OM_ERR_MALLOC,"Couldn't allocate a new dict entry"); return OM_NULL; } ret->key=key; ret->value=val; return ret; }
char * om_string_substr(const char *str, int start, int length) { char * ret = om_malloc(length+1); if( ret==OM_NULL ) return ret; int len = strlen(str); len = len >= start+length ? length : (len+1)-start; memcpy(ret,str+start,len); return ret; }
om_prefs_ptr om_prefs_acquire(const char *name) { om_prefs_ptr prefs = om_malloc(sizeof(om_prefs)); strcpy(prefs->name,name); prefs->device_data = om_dict_new(15); ((om_dict_ptr)prefs->device_data)->release_func = om_mock_prefs_dict_release_entry; prefs->get=om_mock_prefs_get; prefs->set=om_mock_prefs_set; prefs->clear=om_mock_prefs_clear; prefs->remove=om_mock_prefs_remove; return prefs; }
char * om_string_append(const char *str, const char *app) { int size = sizeof(char)*(strlen(str)+strlen(app)+1); char * ret = om_malloc(size); if( ret==OM_NULL ) { om_error_set_code(OM_ERR_MALLOC); return OM_NULL; } memcpy(ret,str,strlen(str)); strcat(ret,app); return ret; }
om_http_response_ptr om_net_do_http_get_to_file_output_stream(const char *url, om_file_output_stream_ptr ostream, void (*call_back)(void *callback_data, om_http_response_ptr response, om_uint32 bytes_total, om_uint32 bytes_downloaded), void *callback_data) { om_net_mock_vars_var->last_input_stream_passed = ostream; om_net_mock_vars_var->last_get_url_passed = om_string_copy(url); om_http_response_ptr resp = om_malloc(sizeof(om_http_response)); resp->status_code = om_net_mock_vars_var->do_http_get_result->status_code; resp->result = om_string_copy(om_net_mock_vars_var->do_http_get_result->result); return resp; }
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; }
char * om_string_encodeURI(const char *str) { const char* reserved = "!’\"();:@&=+$,/?%#[]% \0"; // count characters to encode int i=0, encodePadding=0, reservedLen=strlen(reserved); while(str[i]!=0) { for(int j=0; j<reservedLen; j++) { if(reserved[j]==str[i]) { encodePadding+=3; } } i++; } // allocate new string char *newStr = om_malloc( sizeof(char) * (strlen(str)+encodePadding+1) ); // copy each character, encoding as we go i=0; char *pos = newStr; om_bool charHandled; while(str[i]!=0) { charHandled=OM_FALSE; for(int j=0; j<reservedLen; j++) { if(str[i]==reserved[j]) { sprintf(pos,"%%%X",str[i]); pos+=3; charHandled=OM_TRUE; break; } } if( !charHandled ) { *pos=str[i]; pos++; } i++; } // return new string return newStr; }
OM_PRIVATE_FUNC char * __om_digest_md5_file(om_file_input_stream *istream) { 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); while( (r=om_storage_read(istream,buffer,OM_DIGEST_BUFFER_LEN_MD5)) && r!=(-1) ) { // try to align to 32 bits //int len = r/4; //if( r%4!=0 ) r+=4; cvs_MD5Update(pctx,buffer,r); memset(buffer,0,OM_DIGEST_BUFFER_LEN_MD5); } 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_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; }
/** * 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); } }
OM_PRIVATE_FUNC char * __om_digest_sha1_file(om_file_input_stream *istream) { 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); while( (r=om_storage_read(istream,buffer,OM_DIGEST_BUFFER_LEN_SHA1)) && r!=(-1) ) { // try to align to 32 bits //int len = r/4; //if( r%4!=0 ) r+=4; SHA1Input(pctx,buffer,r); memset(buffer,0,OM_DIGEST_BUFFER_LEN_SHA1); } 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; }
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; }
shouldUpdate = *updateFreq != 0 ? (now - *lastUpdate > *updateFreq) : OM_FALSE; } shouldUpdate = (*shouldPullUpdates) && shouldUpdate; om_free(lastUpdate); om_free(updateFreq); om_free(shouldPullUpdates); return shouldUpdate; } char * om_update_connreq_create_post(om_update_connreq_ptr request) { const char *template = "action=connection-open-request&device-type=%s&device-uuid=%s&" \ "app-name=%s&app-version=%s&hash=%s&slic-version=%s"; om_update_connreq_ptr encodedRequest = om_malloc( sizeof(om_update_connreq) ); if( encodedRequest==OM_NULL ) { return OM_NULL; } encodedRequest->device_type=om_string_encodeURI(request->device_type); encodedRequest->device_uuid=om_string_encodeURI(request->device_uuid); encodedRequest->app_name=om_string_encodeURI(request->app_name); encodedRequest->app_version=om_string_encodeURI(request->app_version); encodedRequest->app_version_hash=om_string_encodeURI(request->app_version_hash!=OM_NULL?request->app_version_hash:""); encodedRequest->slic_version=om_string_encodeURI(request->slic_version); int size = ( ( strlen(encodedRequest->device_type) + strlen(encodedRequest->device_uuid) \ + strlen(encodedRequest->app_name) + strlen(encodedRequest->app_version) + strlen(encodedRequest->app_version_hash) \ + strlen(encodedRequest->slic_version) + strlen(template) ) * sizeof(char) ) \
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; }