static bool do_dump_buffer_to_file(char *buf, char *prefix) { char path[100]; char date[40]; char obid[40]; if (!buf) return false; if (strstr(buf, "date{ts{")) strncpy(date, strstr(buf, "date{ts{"), sizeof(date)); else strncpy(date, "date{ts{no-date{", sizeof(date)); if (!strstr(buf, "object_id{int{")) return false; strncpy(obid, strstr(buf, "object_id{int{"), sizeof(obid)); char *ptr1 = strstr(date, "date{ts{"); char *ptr2 = strstr(obid, "object_id{int{"); char *pdate = next_token(&ptr1); pdate = next_token(&ptr1); pdate = next_token(&ptr1); char *pobid = next_token(&ptr2); pobid = next_token(&ptr2); pobid = next_token(&ptr2); snprintf(path, sizeof(path), "/%s/%s/UEMIS Dump/%s_%s_Uemis_dump_%s_in_round_%d_%d.txt", home, user, prefix, pdate, pobid, debug_round, bufCnt); int dumpFile = subsurface_open(path, O_RDWR | O_CREAT, 0666); if (dumpFile == -1) return false; write(dumpFile, buf, strlen(buf)); close(dumpFile); bufCnt++; return true; }
struct zip *subsurface_zip_open_readonly(const char *path, int flags, int *errorp) { #if defined(LIBZIP_VERSION_MAJOR) /* libzip 0.10 has zip_fdopen, let's use it since zip_open doesn't have a * wchar_t version */ int fd = subsurface_open(path, O_RDONLY | O_BINARY, 0); struct zip *ret = zip_fdopen(fd, flags, errorp); if (!ret) close(fd); return ret; #else return zip_open(path, flags, errorp); #endif }
int readfile(const char *filename, struct memblock *mem) { int ret, fd; struct stat st; char *buf; mem->buffer = NULL; mem->size = 0; fd = subsurface_open(filename, O_RDONLY | O_BINARY, 0); if (fd < 0) return fd; ret = fstat(fd, &st); if (ret < 0) goto out; ret = -EINVAL; if (!S_ISREG(st.st_mode)) goto out; ret = 0; if (!st.st_size) goto out; buf = malloc(st.st_size + 1); ret = -1; errno = ENOMEM; if (!buf) goto out; mem->buffer = buf; mem->size = st.st_size; ret = read(fd, buf, mem->size); if (ret < 0) goto free; buf[ret] = 0; if (ret == mem->size) goto out; errno = EIO; ret = -1; free: free(mem->buffer); mem->buffer = NULL; mem->size = 0; out: close(fd); return ret; }
/* Check if there's a req.txt file and get the starting filenr from it. * Test for the maximum number of ANS files (I believe this is always * 4000 but in case there are differences depending on firmware, this * code is easy enough */ static bool uemis_init(const char *path) { char *ans_path; int i; if (!path) return false; /* let's check if this is indeed a Uemis DC */ reqtxt_path = build_filename(path, "req.txt"); reqtxt_file = subsurface_open(reqtxt_path, O_RDONLY, 0666); if (!reqtxt_file) { #if UEMIS_DEBUG & 1 fprintf(debugfile, ":EE req.txt can't be opened\n"); #endif return false; } if (bytes_available(reqtxt_file) > 5) { char tmp[6]; read(reqtxt_file, tmp, 5); tmp[5] = '\0'; #if UEMIS_DEBUG & 2 fprintf(debugfile, "::r req.txt \"%s\"\n", tmp); #endif if (sscanf(tmp + 1, "%d", &filenr) != 1) return false; } else { filenr = 0; #if UEMIS_DEBUG & 2 fprintf(debugfile, "::r req.txt skipped as there were fewer than 5 bytes\n"); #endif } close(reqtxt_file); /* It would be nice if we could simply go back to the first set of * ANS files. But with a FAT filesystem that isn't possible */ ans_path = build_filename(path, "ANS"); number_of_files = number_of_file(ans_path); free(ans_path); /* initialize the array in which we collect the answers */ for (i = 0; i < NUM_PARAM_BUFS; i++) param_buff[i] = ""; return true; }
/* send a request to the dive computer and collect the answer */ static bool uemis_get_answer(const char *path, char *request, int n_param_in, int n_param_out, const char **error_text) { int i = 0, file_length; char sb[BUFLEN]; char fl[13]; char tmp[101]; const char *what = translate("gettextFromC", "data"); bool searching = true; bool assembling_mbuf = false; bool ismulti = false; bool found_answer = false; bool more_files = true; bool answer_in_mbuf = false; char *ans_path; int ans_file; int timeout = UEMIS_LONG_TIMEOUT; reqtxt_file = subsurface_open(reqtxt_path, O_RDWR | O_CREAT, 0666); snprintf(sb, BUFLEN, "n%04d12345678", filenr); str_append_with_delim(sb, request); for (i = 0; i < n_param_in; i++) str_append_with_delim(sb, param_buff[i]); if (!strcmp(request, "getDivelogs") || !strcmp(request, "getDeviceData") || !strcmp(request, "getDirectory") || !strcmp(request, "getDivespot") || !strcmp(request, "getDive")) { answer_in_mbuf = true; str_append_with_delim(sb, ""); if (!strcmp(request, "getDivelogs")) what = translate("gettextFromC", "divelog entry id"); else if (!strcmp(request, "getDivespot")) what = translate("gettextFromC", "divespot data id"); else if (!strcmp(request, "getDive")) what = translate("gettextFromC", "more data dive id"); } str_append_with_delim(sb, ""); file_length = strlen(sb); snprintf(fl, 10, "%08d", file_length - 13); memcpy(sb + 5, fl, strlen(fl)); #if UEMIS_DEBUG & 1 fprintf(debugfile, "::w req.txt \"%s\"\n", sb); #endif if (write(reqtxt_file, sb, strlen(sb)) != strlen(sb)) { *error_text = translate("gettextFromC", ERR_FS_SHORT_WRITE); return false; } if (!next_file(number_of_files)) { *error_text = translate("gettextFromC", ERR_FS_FULL); more_files = false; } trigger_response(reqtxt_file, "n", filenr, file_length); usleep(timeout); mbuf = NULL; mbuf_size = 0; while (searching || assembling_mbuf) { if (import_thread_cancelled) return false; progress_bar_fraction = filenr / 4000.0; snprintf(fl, 13, "ANS%d.TXT", filenr - 1); ans_path = build_filename(build_filename(path, "ANS"), fl); ans_file = subsurface_open(ans_path, O_RDONLY, 0666); read(ans_file, tmp, 100); close(ans_file); #if UEMIS_DEBUG & 8 tmp[100] = '\0'; fprintf(debugfile, "::t %s \"%s\"\n", ans_path, tmp); #elif UEMIS_DEBUG & 4 char pbuf[4]; pbuf[0] = tmp[0]; pbuf[1] = tmp[1]; pbuf[2] = tmp[2]; pbuf[3] = 0; fprintf(debugfile, "::t %s \"%s...\"\n", ans_path, pbuf); #endif free(ans_path); if (tmp[0] == '1') { searching = false; if (tmp[1] == 'm') { assembling_mbuf = true; ismulti = true; } if (tmp[2] == 'e') assembling_mbuf = false; if (assembling_mbuf) { if (!next_file(number_of_files)) { *error_text = translate("gettextFromC", ERR_FS_FULL); more_files = false; assembling_mbuf = false; } reqtxt_file = subsurface_open(reqtxt_path, O_RDWR | O_CREAT, 0666); trigger_response(reqtxt_file, "n", filenr, file_length); } } else { if (!next_file(number_of_files - 1)) { *error_text = translate("gettextFromC", ERR_FS_FULL); more_files = false; assembling_mbuf = false; searching = false; } reqtxt_file = subsurface_open(reqtxt_path, O_RDWR | O_CREAT, 0666); trigger_response(reqtxt_file, "r", filenr, file_length); uemis_increased_timeout(&timeout); } if (ismulti && more_files && tmp[0] == '1') { int size; snprintf(fl, 13, "ANS%d.TXT", assembling_mbuf ? filenr - 2 : filenr - 1); ans_path = build_filename(build_filename(path, "ANS"), fl); ans_file = subsurface_open(ans_path, O_RDONLY, 0666); size = bytes_available(ans_file); if (size > 3) { char *buf; int r; if (lseek(ans_file, 3, SEEK_CUR) == -1) goto fs_error; buf = malloc(size - 2); if ((r = read(ans_file, buf, size - 3)) != size - 3) { free(buf); goto fs_error; } buf[r] = '\0'; buffer_add(&mbuf, &mbuf_size, buf); show_progress(buf, what); free(buf); param_buff[3]++; } close(ans_file); timeout = UEMIS_TIMEOUT; usleep(UEMIS_TIMEOUT); } } if (more_files) { int size = 0, j = 0; char *buf = NULL; if (!ismulti) { snprintf(fl, 13, "ANS%d.TXT", filenr - 1); ans_path = build_filename(build_filename(path, "ANS"), fl); ans_file = subsurface_open(ans_path, O_RDONLY, 0666); size = bytes_available(ans_file); if (size > 3) { int r; if (lseek(ans_file, 3, SEEK_CUR) == -1) goto fs_error; buf = malloc(size - 2); if ((r = read(ans_file, buf, size - 3)) != size - 3) { free(buf); goto fs_error; } buf[r] = '\0'; buffer_add(&mbuf, &mbuf_size, buf); show_progress(buf, what); #if UEMIS_DEBUG & 8 fprintf(debugfile, "::r %s \"%s\"\n", ans_path, buf); #endif } size -= 3; close(ans_file); free(ans_path); } else { ismulti = false; } #if UEMIS_DEBUG & 8 fprintf(debugfile, ":r: %s\n", buf); #endif if (!answer_in_mbuf) for (i = 0; i < n_param_out && j < size; i++) param_buff[i] = next_segment(buf, &j, size); found_answer = true; free(buf); } #if UEMIS_DEBUG & 1 for (i = 0; i < n_param_out; i++) fprintf(debugfile, "::: %d: %s\n", i, param_buff[i]); #endif return found_answer; fs_error: close (ans_file); return false; }