END_TEST /******************************************************************************* * test return_... functions */ START_TEST(test_return_functions) { ck_assert(return_null() == NULL); ck_assert(return_null("asdf", 5, NULL, 1, "qwer") == NULL); ck_assert(return_true() == TRUE); ck_assert(return_true("asdf", 5, NULL, 1, "qwer") == TRUE); ck_assert(return_false() == FALSE); ck_assert(return_false("asdf", 5, NULL, 1, "qwer") == FALSE); ck_assert(return_failed() == FAILED); ck_assert(return_failed("asdf", 5, NULL, 1, "qwer") == FAILED); ck_assert(return_success() == SUCCESS); ck_assert(return_success("asdf", 5, NULL, 1, "qwer") == SUCCESS); /* just make sure this works */ nop(); nop("asdf", 5, NULL, 1, "qwer"); }
static void finish_set_timezone(GDBusMethodInvocation *invocation, struct method_call_data *data) { gchar link[PATH_MAX], tmp[PATH_MAX]; if (snprintf(link, sizeof link, "%s%s%s", LOCALTIME_TO_ZONEINFO_PATH, ZONEINFO_PATH, data->set_timezone.timezone) >= sizeof link) goto error; if (snprintf(tmp, sizeof tmp, "%s.%06u", LOCALTIME_PATH, g_random_int()) >= sizeof tmp) goto error; if (symlink(link, tmp)) goto error; set_default_file_context(tmp, link); if (rename(tmp, LOCALTIME_PATH)) { unlink(tmp); goto error; } emit_property_change(g_dbus_method_invocation_get_connection(invocation), "Timezone", g_variant_new_string(data->set_timezone.timezone)); return_success(invocation); update_kernel_utc_offset(); /* RTC in local needs to be set for the new timezone */ if (is_rtc_local()) start_hwclock_call(FALSE, FALSE, FALSE, NULL, NULL, NULL); return; error: return_error(invocation, G_DBUS_ERROR_FAILED, "Failed to update %s", LOCALTIME_PATH); }
static void set_timezone(GVariant *parameters, GDBusMethodInvocation *invocation, const gchar *caller) { gboolean user_interaction, no_change; const gchar *timezone; struct method_call_data data; GVariant *current_timezone; g_variant_get(parameters, "(&sb)", &timezone, &user_interaction); if (!check_timezone_name(timezone)) { return_error(invocation, G_DBUS_ERROR_INVALID_ARGS, "Invalid timezone"); return; } current_timezone = get_timezone(); no_change = !g_strcmp0(g_variant_get_string(current_timezone, NULL), timezone); g_variant_unref(current_timezone); if (no_change) { return_success(invocation); return; } snprintf(data.set_timezone.timezone, sizeof data.set_timezone.timezone, "%s", timezone); start_auth_check(caller, POLKIT_ACTION_SET_TIMEZONE, user_interaction, invocation, finish_set_timezone, &data); }
int verify_file_checksum(char *filename) { char *proc="verify_file_checksum " SPHERE_VERSION_STR; SP_FILE *sp; char buf[1024]; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (filename == CNULL) return_err(proc,100,100,"Null filename"); if ((sp = sp_open(filename,"rv")) == SPNULL) return_err(proc,101,101, rsprintf("Unable to open SPHERE file '%s'",filename)); if (sp->read_spifr->status->user_sample_count > 0){ if (sp_read_data(buf,1,sp) != 1){ sp_close(sp); return_err(proc,200,200,"Verification of checksum failed"); } } else { sp_close(sp); return_err(proc,300,300,"No data in file to check"); } sp_close(sp); if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning 0\n",proc); return_success(proc,0,0,"Checksum verification passed"); }
int parse_sample_byte_format(char *str, enum SP_sample_byte_fmt *sbf) { char *proc="parse_sample_byte_format " SPHERE_VERSION_STR; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (str == CNULL) return_err(proc,100,100,"Null sample_byte_format_string"); if (sbf == (enum SP_sample_byte_fmt *)0) return_err(proc,101,101,"Null sbf pointer"); if (strsame(str,"01")) *sbf = SP_sbf_01; else if (strsame(str,"10")) *sbf = SP_sbf_10; else if (strsame(str,"1")) *sbf = SP_sbf_1; else if (strsame(str,"0123")) *sbf = SP_sbf_0123; else if (strsame(str,"1032")) *sbf = SP_sbf_1032; else if (strsame(str,"2301")) *sbf = SP_sbf_2301; else if (strsame(str,"3210")) *sbf = SP_sbf_3210; else if (strsame(str,"N")) *sbf = SP_sbf_N; if (strstr(str,"shortpack") != CNULL) { /* this return value must remain 1000, other functions depend on it*/ return_err(proc,1000,1000, rsprintf("Unknown sample_byte_format value '%s' in header",str)); } if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning 0\n",proc); return_success(proc,0,0,"ok"); }
static int pre_verify_checksum(SP_FILE *sp){ char *proc="pre_verify_checksum " SPHERE_VERSION_STR; SPIFR *spifr=sp->read_spifr; SP_CHECKSUM checksum; /* if the samples are in memory, compute the checksum from there. */ /* if not, read in the file, a block at a time and compute the */ /* checksum. */ switch (spifr->status->file_encoding){ case SP_se_pcm2: if (fob_short_checksum(spifr->waveform->sp_fob, &checksum, spifr->status->file_sbf != spifr->status->natural_sbf, sp_add_checksum) < 0) return_err(proc,501,0,"Unable to Pre-Verify Checksum"); if (checksum != spifr->status->file_checksum){ spifr->waveform->failed_checksum = TRUE; return_err(proc,1001,0, "Pre-Read Short Checksum Test Failed"); } break; default: if (fob_char_checksum(spifr->waveform->sp_fob, &checksum,sp_add_checksum) < 0) return_err(proc,502,0,"Unable to Pre-Verify Checksum"); if (checksum != spifr->status->file_checksum){ spifr->waveform->failed_checksum = TRUE; return_err(proc,1001,0, "Pre-Read Char Checksum Test Failed"); } break; } return_success(proc,0,0,"ok"); }
int sp_compute_checksum(SP_FILE *sp, SP_CHECKSUM *comp_chksum){ char *proc = "sp_compute_checksum"; void *buff; SP_INTEGER cur_pos; if (sp == SPNULL) return_err(proc,101,101,"Null SPFILE structure"); if (sp->open_mode != SP_mode_read) return_err(proc,102,102,"File must be opened for read"); if (! sp->read_spifr->status->is_disk_file) return_err(proc,103,103,"File must be a disk file"); if (sp_error(sp) != 0) return_err(proc,104,104,"Sphere file already has an error"); /* save the current position so we can go back to it */ if ((cur_pos = sp_tell(sp)) < 0) return_err(proc,110,110, rsprintf("sp_tell() failed, returning: %s", get_return_status_message())); /* rewind the file */ if (sp_seek(sp,0,0) != 0) return_err(proc,111,111, rsprintf("sp_seek() to sample 0 failed, returning: %s", get_return_status_message())); /* allocate some memory */ if ((buff = (void *)sp_data_alloc(sp,4096)) == (void *)0) return_err(proc,112,112, rsprintf("can not alloc waveform buffer, returning: %s", get_return_status_message())); /* read in the data */ while (sp_read_data(buff,4096,sp) > 0) ; /* dealloc memory */ sp_data_free(sp,buff); if (sp_error(sp) != 0) return_err(proc,120,120, rsprintf("sp_error() indicates an error, returning: %s", get_return_status_message())); *comp_chksum = sp->read_spifr->waveform->checksum; if (sp_seek(sp,cur_pos,0) != 0) return_err(proc,130,130, rsprintf("sp_seek() to return the file to it's initial" "state failed, returning: %s", get_return_status_message())); return_success(proc,0,0,"ok"); }
static void set_rtc_local(GVariant *parameters, GDBusMethodInvocation *invocation, const gchar *caller) { gboolean user_interaction; struct method_call_data data; g_variant_get(parameters, "(bbb)", &data.set_rtc_local.local, &data.set_rtc_local.adjust_system, &user_interaction); if (data.set_rtc_local.local == is_rtc_local()) { return_success(invocation); return; } start_auth_check(caller, POLKIT_ACTION_SET_RTC_LOCAL, user_interaction, invocation, finish_set_rtc_local, &data); }
static void finish_set_ntp_active(GDBusMethodInvocation *invocation, struct method_call_data *data) { GVariantBuilder builder1, builder2; gchar *unit_name; guint i, enable, disable; /* Reload the list to get new NTP units installed on the system */ update_ntp_units(); /* Start and enable the first NTP unit if active is true. Stop and disable everything else. Errors are ignored for other units than first. */ for (i = enable = disable = 0; i < ntp_units->len; i++) { unit_name = get_ntp_unit(i)->name; if (!i && data->set_ntp_active.active) { if (!call_systemd_noresult("StartUnit", g_variant_new("(ss)", unit_name, "replace"))) if (!i) goto error; if (!enable++) g_variant_builder_init(&builder1, G_VARIANT_TYPE("as")); g_variant_builder_add(&builder1, "s", unit_name); } else { if (!call_systemd_noresult("StopUnit", g_variant_new("(ss)", unit_name, "replace"))) if (!i) goto error; if (!disable++) g_variant_builder_init(&builder2, G_VARIANT_TYPE("as")); g_variant_builder_add(&builder2, "s", unit_name); } } if (enable) call_systemd_noresult("EnableUnitFiles", g_variant_new("(asbb)", &builder1, FALSE, TRUE)); if (disable) call_systemd_noresult("DisableUnitFiles", g_variant_new("(asb)", &builder2, FALSE)); /* This seems to be needed to update the unit state reported by systemd */ if (enable || disable) call_systemd_noresult("Reload", g_variant_new("()")); emit_property_change(g_dbus_method_invocation_get_connection(invocation), "NTP", g_variant_new_boolean(data->set_ntp_active.active)); return_success(invocation); return; error: return_error(invocation, G_DBUS_ERROR_FAILED, "Failed to start/stop NTP unit"); }
static void set_ntp_active(GVariant *parameters, GDBusMethodInvocation *invocation, const gchar *caller) { gboolean user_interaction; struct method_call_data data; g_variant_get(parameters, "(bb)", &data.set_ntp_active.active, &user_interaction); if (!ntp_units->len) { return_error(invocation, G_DBUS_ERROR_FAILED, "No NTP unit available"); return; } if (data.set_ntp_active.active == is_ntp_active()) { return_success(invocation); return; } start_auth_check(caller, POLKIT_ACTION_SET_NTP_ACTIVE, user_interaction, invocation, finish_set_ntp_active, &data); }
static void finish_set_time(GDBusMethodInvocation *invocation, struct method_call_data *data) { struct timeval tv; struct timex tx; if (data->set_time.relative) { tx.modes = ADJ_SETOFFSET | ADJ_NANO; tx.time.tv_sec = data->set_time.requested_time / 1000000; tx.time.tv_usec = data->set_time.requested_time - tx.time.tv_sec * 1000000; if (tx.time.tv_usec < 0) { tx.time.tv_sec--; tx.time.tv_usec += 1000000; } /* Convert to nanoseconds */ tx.time.tv_usec *= 1000; if (adjtimex(&tx) < 0) goto error; } else { /* Compensate for the time taken by the authorization check */ data->set_time.requested_time += g_get_monotonic_time() - data->set_time.request_time; tv.tv_sec = data->set_time.requested_time / 1000000; tv.tv_usec = data->set_time.requested_time - tv.tv_sec * 1000000; if (settimeofday(&tv, NULL)) goto error; } return_success(invocation); /* Set the RTC to the new system time */ start_hwclock_call(FALSE, FALSE, FALSE, NULL, NULL, NULL); return; error: return_error(invocation, G_DBUS_ERROR_FAILED, "Failed to set system clock: %s", strerror(errno)); }
// read from socket, write to file // ALWAYS returns an HTML reply // int copy_socket_to_file(FILE* in, char* path, double offset, double nbytes) { unsigned char buf[BLOCK_SIZE]; struct stat sbuf; int pid; // open file. Use raw IO not buffered IO so that we can use reliable // posix file locking. // Advisory file locking is not guaranteed reliable when // used with stream buffered IO. // int fd = open(path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH ); if (fd<0) { return return_error(ERR_TRANSIENT, "can't open file %s: %s\n", path, strerror(errno) ); } // Put an advisory lock on the file. // This will prevent OTHER instances of file_upload_handler // from being able to write to the file. // pid = mylockf(fd); if (pid>0) { close(fd); return return_error(ERR_TRANSIENT, "can't lock file %s: %s locked by PID=%d\n", path, strerror(errno), pid ); } else if (pid < 0) { close(fd); return return_error(ERR_TRANSIENT, "can't lock file %s\n", path); } // check that file length corresponds to offset // TODO: use a 64-bit variant // if (stat(path, &sbuf)) { close(fd); return return_error(ERR_TRANSIENT, "can't stat file %s: %s\n", path, strerror(errno) ); } if (sbuf.st_size < offset) { close(fd); return return_error(ERR_TRANSIENT, "length of file %s %d bytes < offset %.0f bytes", path, (int)sbuf.st_size, offset ); } if (offset) lseek(fd, offset, SEEK_SET); if (sbuf.st_size > offset) { log_messages.printf(MSG_CRITICAL, "file %s length on disk %d bytes; host upload starting at %.0f bytes.\n", this_filename, (int)sbuf.st_size, offset ); } // caller guarantees that nbytes > offset // bytes_left = nbytes - offset; while (bytes_left > 0) { int n, m, to_write; m = bytes_left<(double)BLOCK_SIZE ? (int)bytes_left : BLOCK_SIZE; // try to get m bytes from socket (n>=0 is number actually returned) // n = fread(buf, 1, m, in); // try to write n bytes to file // to_write=n; while (to_write > 0) { ssize_t ret = write(fd, buf+n-to_write, to_write); if (ret < 0) { close(fd); const char* errmsg; if (errno == ENOSPC) { errmsg = "No space left on server"; } else { errmsg = strerror(errno); } return return_error(ERR_TRANSIENT, "can't write file %s: %s\n", path, errmsg ); } to_write -= ret; } // check that we got all bytes from socket that were requested // Note: fread() reads less than requested only if there's // an error or EOF (see the man page) // if (n != m) { close(fd); if (feof(in)) { return return_error(ERR_TRANSIENT, "EOF on socket read : asked for %d, got %d\n", m, n ); } else if (ferror(in)) { return return_error(ERR_TRANSIENT, "error %d (%s) on socket read: asked for %d, got %d\n", ferror(in), strerror(ferror(in)), m, n ); } else { return return_error(ERR_TRANSIENT, "incomplete socket read: asked for %d, got %d\n", m, n ); } } bytes_left -= n; } close(fd); return return_success(0); }
// ALWAYS generates an HTML reply // int handle_file_upload(FILE* in, R_RSA_PUBLIC_KEY& key) { char buf[256], path[512], temp[256]; FILE_INFO file_info; int retval; double nbytes=-1, offset=0; bool is_valid; while (fgets(buf, 256, in)) { #if 0 log_messages.printf(MSG_NORMAL, "got:%s\n", buf); #endif if (match_tag(buf, "<file_info>")) { retval = file_info.parse(in); if (retval) { return return_error(ERR_PERMANENT, "FILE_INFO::parse"); } #if 0 log_messages.printf(MSG_NORMAL, "file info:\n%s\n", file_info.signed_xml ); #endif if (!config.ignore_upload_certificates) { if (!file_info.signed_xml || !file_info.xml_signature) { log_messages.printf(MSG_CRITICAL, "file info is missing signature\n" ); return return_error(ERR_PERMANENT, "invalid signature"); } else { retval = verify_string( file_info.signed_xml, file_info.xml_signature, key, is_valid ); if (retval || !is_valid) { log_messages.printf(MSG_CRITICAL, "verify_string() [%s] [%s] retval %d, is_valid = %d\n", file_info.signed_xml, file_info.xml_signature, retval, is_valid ); log_messages.printf(MSG_NORMAL, "signed xml: %s", file_info.signed_xml ); log_messages.printf(MSG_NORMAL, "signature: %s", file_info.xml_signature ); return return_error(ERR_PERMANENT, "invalid signature"); } } } continue; } if (parse_double(buf, "<offset>", offset)) continue; if (parse_double(buf, "<nbytes>", nbytes)) continue; if (parse_str(buf, "<md5_cksum>", temp, sizeof(temp))) continue; if (match_tag(buf, "<data>")) { if (nbytes < 0) { return return_error(ERR_PERMANENT, "nbytes missing or negative"); } // enforce limits in signed XML // if (!config.ignore_upload_certificates) { if (nbytes > file_info.max_nbytes) { sprintf(buf, "file size (%d KB) exceeds limit (%d KB)", (int)(nbytes/1024), (int)(file_info.max_nbytes/1024) ); copy_socket_to_null(in); return return_error(ERR_PERMANENT, buf); } } // make sure filename is legit // if (strstr(file_info.name, "..")) { return return_error(ERR_PERMANENT, "file_upload_handler: .. found in filename: %s", file_info.name ); } if (strlen(file_info.name) == 0) { return return_error(ERR_PERMANENT, "file_upload_handler: no filename; nbytes %f", nbytes ); } retval = dir_hier_path( file_info.name, config.upload_dir, config.uldl_dir_fanout, path, true ); if (retval) { log_messages.printf(MSG_CRITICAL, "Failed to find/create directory for file '%s' in '%s'\n", file_info.name, config.upload_dir ); return return_error(ERR_TRANSIENT, "can't open file"); } log_messages.printf(MSG_NORMAL, "Starting upload of %s from %s [offset=%.0f, nbytes=%.0f]\n", file_info.name, get_remote_addr(), offset, nbytes ); #ifndef _USING_FCGI_ fflush(stderr); #endif if (offset >= nbytes) { log_messages.printf(MSG_CRITICAL, "ERROR: offset >= nbytes!!\n" ); return return_success(0); } retval = copy_socket_to_file(in, path, offset, nbytes); log_messages.printf(MSG_NORMAL, "Ended upload of %s from %s; retval %d\n", file_info.name, get_remote_addr(), retval ); #ifndef _USING_FCGI_ fflush(stderr); #endif return retval; } log_messages.printf(MSG_CRITICAL, "unrecognized: %s", buf ); } return return_error(ERR_PERMANENT, "Missing <data> tag"); }
/* * sp_open * */ SP_FILE *sp_open(char *filename, char *mode) { SP_FILE *tsp; char *errmsg, *proc="sp_open " SPHERE_VERSION_STR, *fopen_mode; enum SP_file_open_mode current_mode; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (filename == CNULL) return_err(proc,101,SPNULL,"Null filename string"); if (mode == CNULL) return_err(proc,101,SPNULL,"Null file mode string"); if (sp_verbose > 10) fprintf(spfp,"Proc %s: file '%s' mode '%s'\n", proc,filename,mode); if ((tsp=sp_alloc_and_init_sphere_t()) == SPNULL) return_err(proc,102,SPNULL,"Unable to malloc SPFILE memory"); /* set the file open mode in the status structure */ if (strsame(mode,"r")) current_mode = tsp->open_mode = SP_mode_read; else if (strsame(mode,"w")) current_mode = tsp->open_mode = SP_mode_write; else if (strsame(mode,"rv")){ current_mode = tsp->open_mode = SP_mode_read; tsp->read_spifr->status->extra_checksum_verify = TRUE; } else if (strsame(mode,"wv")) { current_mode = tsp->open_mode = SP_mode_write; tsp->write_spifr->status->extra_checksum_verify = TRUE; } else if (strsame(mode,"u")) { tsp->open_mode = SP_mode_read; current_mode = SP_mode_update; } else { free_sphere_t(tsp); return_err(proc,103,SPNULL, rsprintf("Illegal SPFILE open mode '%s'",mode)); } /* just open the file, either for reading or writing. If the */ /* mode was SP_mode_writing, and the file exists, change the mode */ /* to SP_mode_update. */ switch (tsp->open_mode) { case (SP_mode_read): { if (! strsame(filename,"-")) { fopen_mode = (current_mode == SP_mode_read) ? READMODE : UPDATEMODE; if ((tsp->read_spifr->waveform->sp_fp = fopen(filename,fopen_mode)) == (FILE *)0){ free_sphere_t(tsp); return_err(proc,111,SPNULL, rsprintf("%s'%s' for reading fopen mode %s", "Unable to open SPHERE file ", filename,fopen_mode)); } tsp->read_spifr->status->is_disk_file = TRUE; } else { tsp->read_spifr->waveform->sp_fp = stdin; tsp->read_spifr->status->is_disk_file = FALSE; } tsp->read_spifr->status->external_filename = mtrf_strdup(filename); break; } case (SP_mode_write):{ if (! strsame(filename,"-")) { /* open the file, truncating if the file exists */ fopen_mode = (current_mode == SP_mode_write) ? WRITEMODE : UPDATEMODE; if ((tsp->write_spifr->waveform->sp_fp = fopen(filename,fopen_mode)) == (FILE *)0){ free_sphere_t(tsp); return_err(proc,105,SPNULL, rsprintf("Unable to open SPHERE file '%s' for %s %s", filename,"writing, fopen mode",fopen_mode)); } tsp->write_spifr->status->is_disk_file = TRUE; } else { tsp->write_spifr->waveform->sp_fp = stdout; tsp->write_spifr->status->is_disk_file = FALSE; } tsp->write_spifr->status->external_filename = mtrf_strdup(filename); break; } default: { return_err(proc,200,SPNULL,"Internal error"); } } /* now that the file is opened, load the header if it exist, */ /* otherwise alloc an empty header for the user */ switch (tsp->open_mode) { case (SP_mode_read): { /* read the header */ tsp->read_spifr->header = sp_open_header(tsp->read_spifr->waveform->sp_fp,TRUE,&errmsg); if ( tsp->read_spifr->header == HDRNULL ) { free_sphere_t(tsp); return_err(proc,104,SPNULL, rsprintf("Unable to open SPHERE header of file '%s', %s", filename,errmsg)); } /* get the size of the header */ if (! strsame(filename,"-")) { if ((tsp->read_spifr->waveform->header_data_size = sp_file_header_size(filename)) < 0){ free_sphere_t(tsp); return_err(proc,110,SPNULL, rsprintf("Unable to get SPHERE header size of file '%s'", filename)); } } else { if ((tsp->read_spifr->waveform->header_data_size = sp_header_size(tsp->read_spifr->header)) < 0){ free_sphere_t(tsp); return_err(proc,111,SPNULL, rsprintf("Unable to get SPHERE header size of file '%s'", filename)); } } /****** Remove the sample_count field if it's ******/ /****** value is 999999999 and the file is a stream ******/ /****** Added by JGF June 22, 1994 ******/ if (! tsp->read_spifr->status->is_disk_file){ int type, size; SP_INTEGER l_int; if (sp_get_field(tsp->read_spifr->header, SAMPLE_COUNT_FIELD,&type,&size) == 0){ if (sp_get_data(tsp->read_spifr->header,SAMPLE_COUNT_FIELD, (char *)&l_int,&size) == 0){ if (l_int == 999999999){ if (sp_verbose > 10) fprintf(spfp, "Proc %s: file '%s' deleting %s field\n", proc,filename,SAMPLE_COUNT_FIELD); if (sp_delete_field(tsp->read_spifr->header, SAMPLE_COUNT_FIELD) < 0) return_err(proc,112,SPNULL, rsprintf("Unable to delete fake '%s' field", SAMPLE_COUNT_FIELD)); } } } } /****** Correct any out-of-date headers right NOW ******/ if (correct_out_of_date_headers(tsp) != 0){ fprintf(spfp,"Warning: correction of "); fprintf(spfp,"out-of-date headers failed\n"); sp_print_return_status(spfp); } /* duplicate the header for the file interface */ if ((tsp->read_spifr->status->file_header = sp_dup_header(tsp->read_spifr->header)) == HDRNULL){ fprintf(spfp,"Error: sp_open_header unable "); fprintf(spfp,"to dup header for file '%s'\n",filename); free_sphere_t(tsp); return_err(proc,106,SPNULL, rsprintf("Unable to duplicate the SPHERE header of file", filename)); } /* set the default operation settings */ if (sp_set_default_operations(tsp) != 0){ print_return_status(spfp); return_err(proc,107,SPNULL, rsprintf("Unable to interpret the SPHERE header of file '%s'", filename)); } break; } case (SP_mode_write):{ tsp->write_spifr->header = sp_create_header(); if ( tsp->write_spifr->header == HDRNULL ) { free_sphere_t(tsp); return_err(proc,108,SPNULL, rsprintf("Unable to allocate SPHERE header for file '%s'", filename)); } tsp->write_spifr->status->file_header = sp_create_header(); if ( tsp->write_spifr->status->file_header == HDRNULL ) { free_sphere_t(tsp); return_err(proc,109,SPNULL, rsprintf("Unable to allocate hidden SPHE. header for file '%s'", filename)); } } default: ; } /* the file was actually opened for update, so make a temp file, and */ /* duplicate the read in file. */ if (current_mode == SP_mode_update){ SP_FILE *tsp2; SPIFR *tspifr; char *temp_file; char data_mode[100]; temp_file = sptemp(tsp->read_spifr->status->external_filename); if (temp_file == CNULL) return_err(proc,300,SPNULL,"Unable to create temporary filename"); if ((tsp2 = sp_open(temp_file,WRITEMODE)) == SPNULL) { free_sphere_t(tsp); mtrf_free(temp_file); return_err(proc,301,SPNULL, rsprintf("Unable to open temporary file",temp_file)); } sp_set_data_mode(tsp,"SE-ORIG:SBF-ORIG"); /* now copy the header into the update file */ if (sp_copy_header(tsp,tsp2) != 0){ free_sphere_t(tsp); free_sphere_t(tsp2); unlink(temp_file); mtrf_free(temp_file); return_err(proc,302,SPNULL,"Unable to duplicate output header"); } *data_mode = '\0'; /*now set the data mode to match the output format of the read file*/ switch (tsp->read_spifr->status->file_compress){ case SP_wc_shorten: strcat(data_mode,"SE-SHORTEN:"); break; case SP_wc_wavpack: strcat(data_mode,"SE-WAVPACK:"); break; case SP_wc_shortpack: strcat(data_mode,"SE-SHORTPACK:"); break; default: ; } switch (tsp->read_spifr->status->file_sbf){ case SP_sbf_01: strcat(data_mode,"SBF-01"); break; case SP_sbf_10: strcat(data_mode,"SBF-10"); break; case SP_sbf_1: strcat(data_mode,"SBF-1"); break; case SP_sbf_N: strcat(data_mode,"SBF-N"); break; default: ; } if (sp_set_data_mode(tsp2,data_mode) >= 100){ free_sphere_t(tsp); free_sphere_t(tsp2); unlink(temp_file); mtrf_free(temp_file); return_err(proc,303,SPNULL, rsprintf("Unable to set_data_mode '%s' for update file", data_mode)); } /* now merge the two SPFILE pointers into a single structure */ /* and free the residual */ tspifr = tsp->write_spifr; tsp->write_spifr = tsp2->write_spifr; tsp2->write_spifr = tspifr; free_sphere_t(tsp2); mtrf_free(temp_file); tsp->open_mode = current_mode; } /* sp_file_dump(tsp,spfp);*/ if (sp_verbose > 17) sp_file_dump(tsp,spfp); if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning Sphere-file pointer\n",proc); return_success(proc,0,tsp,"ok"); }
int sp_set_default_operations(SP_FILE *sp) { SP_INTEGER l_int; char *str, *proc="sp_set_default_operations " SPHERE_VERSION_STR; SPIFR *spifr; int ret; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (sp == SPNULL) return_err(proc,100,100,"Null SPFILE pointer"); if ((sp->open_mode == SP_mode_read) || (sp->open_mode == SP_mode_update)) spifr = sp->read_spifr; else if (sp->open_mode == SP_mode_write) spifr = sp->write_spifr; else return_err(proc,100,100,"Unknown File Mode"); /**********************************************************************/ /* The following fields are REQUIRED for Read operations, */ /* NO Exceptions */ if (sp_h_get_field(sp,SAMPLE_COUNT_FIELD,T_INTEGER,(void *)&l_int) != 0){ /* ---------- OLD CODE --------------------- return_err(proc,101,101,rsprintf("Missing '%s' header field", SAMPLE_COUNT_FIELD)); spifr->status->user_sample_count = spifr->status->file_sample_count = (int)l_int;*/ /* added a condition to permit a pipe to NOT have a sample_count */ /* field. ADDED June 22, 1993 */ if (spifr->status->is_disk_file){ return_err(proc,101,101,rsprintf("Missing '%s' header field", SAMPLE_COUNT_FIELD)); } else { /* Sample counts may be missing from piped files */ spifr->status->user_sample_count = spifr->status->file_sample_count = 999999999; } } else spifr->status->user_sample_count = spifr->status->file_sample_count = (int)l_int; if (l_int <= 0) return_err(proc,108,108, rsprintf("Field '%s' value out of range, %d <= 0", SAMPLE_COUNT_FIELD,l_int)); if (sp_h_get_field(sp,SAMPLE_N_BYTES_FIELD, T_INTEGER,(void *)&l_int) != 0) return_err(proc,104,104, rsprintf("Missing '%s' header field", SAMPLE_N_BYTES_FIELD)); spifr->status->user_sample_n_bytes = spifr->status->file_sample_n_bytes = (int)l_int; if (l_int <= 0) return_err(proc,108,108, rsprintf("Field '%s' value out of range, %d <= 0", SAMPLE_N_BYTES_FIELD,l_int)); if (sp_h_get_field(sp,CHANNEL_COUNT_FIELD,T_INTEGER,(void *)&l_int) != 0) return_err(proc,105,105, rsprintf("Missing '%s' header field", CHANNEL_COUNT_FIELD)); spifr->status->user_channel_count = spifr->status->file_channel_count = (int)l_int; if (l_int <= 0) return_err(proc,108,108, rsprintf("Field '%s' value out of range, > 0", CHANNEL_COUNT_FIELD,l_int)); /**********************************************************************/ /* The following fields may exist, if they do not, there is a default */ /***** NOTE: only set the file_sbf, Sp_set_data_mode is called to */ /***** set the user_sbf */ if ((ret=sp_h_get_field(sp,SAMPLE_BF_FIELD,T_STRING,(void *)&str)) != 0){ if ((spifr->status->file_sbf = get_natural_sbf(spifr->status->user_sample_n_bytes)) == SP_sbf_null) return_err(proc,107,107, rsprintf("Unable to read sample sizes of %d bytes", spifr->status->user_sample_n_bytes)); } else { /* str holds the sample_byte_format_value */ ret = parse_sample_byte_format(str,&(spifr->status->file_sbf)); if (ret == 1000) { /* then the file was compressed using change_wav_format */ spifr->status->file_sbf = get_natural_sbf(spifr->status->user_sample_n_bytes); spifr->status->file_compress = SP_wc_shortpack; if ((h_set_field(spifr->header,SAMPLE_BF_FIELD, T_STRING,get_natural_byte_order(2)) != 0) || (h_set_field(spifr->status->file_header,SAMPLE_BF_FIELD, T_STRING,get_natural_byte_order(2)) != 0)){ sp_print_return_status(spfp); mtrf_free(str); return_err(proc,110,110, rsprintf("Unable to re-set sample byte format%s", "field for a shortpacked file")); } if ((h_set_field(spifr->header,SAMPLE_CODING_FIELD,T_STRING, rsprintf("pcm,embedded-%s",str)) != 0) || (h_set_field(spifr->status->file_header,SAMPLE_CODING_FIELD, T_STRING,rsprintf("pcm,embedded-%s",str)) !=0)){ sp_print_return_status(spfp); mtrf_free(str); return_err(proc,111,111, rsprintf("Unable to re-set sample coding field%s", "for a shortpacked file")); } } else if (ret != 0) { /* there really was an error */ mtrf_free(str); return_err(proc,106,106, "Unable to parse the 'sample_byte_format' field"); } mtrf_free(str); } /***** field break *****/ if (sp_h_get_field(sp,SAMPLE_CODING_FIELD,T_STRING,(void *)&str) != 0) if (spifr->status->user_sample_n_bytes == 1) str = mtrf_strdup("ulaw"); else /* the default, since old Corpora are missing this field */ str = mtrf_strdup("pcm"); if (parse_sample_coding(str,spifr->status->file_sample_n_bytes, &(spifr->status->file_encoding), &(spifr->status->file_compress)) != 0){ mtrf_free(str); print_return_status(spfp); return_err(proc,107,107, rsprintf("Unable to parse sample_coding value '%s' header field", str)); } mtrf_free(str); /*********************************************************************/ /* The following fields are conditionally required. */ ret = sp_h_get_field(sp,SAMPLE_RATE_FIELD,T_INTEGER,(void *)&l_int); switch (spifr->status->file_encoding) { case SP_se_pcm1: case SP_se_pcm2: case SP_se_ulaw: if (ret != 0) return_err(proc,102,102, rsprintf("Header field '%s' missing, but required%s", SAMPLE_RATE_FIELD," for waveform data")); spifr->status->user_sample_rate = spifr->status->file_sample_rate = (int)l_int; break; case SP_se_raw: default: spifr->status->user_sample_rate = spifr->status->file_sample_rate =0; } /***********************************************************************/ /* The following fields are OPTIONAL, but if they exist, there is a */ /* special purpose for them */ if (sp_h_get_field(sp,SAMPLE_CHECKSUM_FIELD,T_INTEGER,(void *)&l_int)==0) spifr->status->file_checksum = l_int; else { spifr->status->ignore_checksum = TRUE; } /*********************/ /* Consitency checks */ /*********************/ if (spifr->status->file_encoding == SP_se_ulaw && spifr->status->file_sample_n_bytes != 1) return_err(proc,120,120, rsprintf("Ulaw encoding requires a 1 byte sample,%s %d", " however the header value is", spifr->status->file_sample_n_bytes)); if (spifr->status->file_encoding == SP_se_pcm1 && spifr->status->file_sample_n_bytes != 1) return_err(proc,120,120, rsprintf("PCM1 encoding requires a 1 byte sample, %s %d", "however the header value is", spifr->status->file_sample_n_bytes)); if (spifr->status->file_encoding == SP_se_pcm1 && spifr->status->file_sample_n_bytes != 2) return_err(proc,120,120, rsprintf("PCM2 encoding requires a 2 byte sample, %s %d", "however the header value is", spifr->status->file_sample_n_bytes)); /********************************/ /* set up the default decodings */ if (sp->open_mode == SP_mode_read) if (sp_set_data_mode(sp,"") != 0){ print_return_status(spfp); return_err(proc,110,110, rsprintf("Unable to set up default encodings %s", "on file opened for read")); } else if (sp->open_mode == SP_mode_update) if (sp_set_data_mode(sp,"SE_ORIG:SBF_ORIG") != 0){ print_return_status(spfp); return_err(proc,111,111, "Unable to set up default encodings on file opened for update"); } if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning 0\n",proc); return_success(proc,0,0,"ok"); }
static void finish_set_rtc_local_hwclock(GDBusMethodInvocation *invocation, struct method_call_data *data) { emit_property_change(g_dbus_method_invocation_get_connection(invocation), "LocalRTC", g_variant_new_boolean(data->set_rtc_local.local)); return_success(invocation); }
int sp_copy_header(SP_FILE *spin, SP_FILE *spout) { char *proc_name="sp_copy_header " SPHERE_VERSION_STR; struct header_t *h; int i; SP_INTEGER l_int; SP_REAL real; if (spin->open_mode == SP_mode_read) h = spin->read_spifr->header; else if (spin->open_mode == SP_mode_write) h = spin->write_spifr->header; else return_err(proc_name,100,100,"Unable to dup header opened for update"); /* just loop through all the names, adding each field */ for (i=0; i < h->fc ; i++){ switch (h->fv[i]->type){ case T_STRING: if (sp_h_set_field(spout,h->fv[i]->name, h->fv[i]->type,h->fv[i]->data) != 0){ sp_print_return_status(spfp); return_err(proc_name,200,200, rsprintf("Unable to copy STRING field '%s'", h->fv[i]->name)); } break; case T_INTEGER: l_int=atol(h->fv[i]->data); if (sp_h_set_field(spout,h->fv[i]->name, h->fv[i]->type,&l_int) != 0){ sp_print_return_status(spfp); return_err(proc_name,200,200, rsprintf("Unable to copy INTEGER field '%s'", h->fv[i]->name)); } break; case T_REAL: real=atof(h->fv[i]->data); if (sp_h_set_field(spout,h->fv[i]->name,h->fv[i]->type,&real) != 0){ sp_print_return_status(spfp); return_err(proc_name,200,200, rsprintf("Unable to copy REAL field '%s'", h->fv[i]->name)); } break; } } /* Special Check, if the input file is a pipe and the sample_count */ /* field is missing, (this is legal), AND the output is a disk file */ /* add a dummy sample_count field to the output header */ /* Added June 22, 1994 */ { int type, size, is_disk_file, out_is_disk_file; is_disk_file = (spin->open_mode == SP_mode_read) ? spin->read_spifr->status->is_disk_file : spin->write_spifr->status->is_disk_file; out_is_disk_file = (spout->open_mode == SP_mode_read) ? spout->read_spifr->status->is_disk_file : spout->write_spifr->status->is_disk_file; if (! is_disk_file) if (sp_get_field(h,SAMPLE_COUNT_FIELD,&type,&size) < 0){ /* add the field to the header */ l_int = 999999999; if (sp_h_set_field(spout,SAMPLE_COUNT_FIELD, T_INTEGER,&l_int) != 0){ sp_print_return_status(spfp); return_err(proc_name,400,400, rsprintf("Unable to copy INTEGER field '%s'", h->fv[i]->name)); } } } if (sp_set_default_operations(spout) != 0) return_err(proc_name,300,300, "Unable to set default operations duplicated file"); return_success(proc_name,0,0,"ok"); }
int sp_close(SP_FILE *sp) { char *proc="sp_close " SPHERE_VERSION_STR; char *write_name; char *read_name; SP_INTEGER lint=0, header_size=0, data_size=0; int header_changed=FALSE; SPIFR *spifr; SPSTATUS *w_spstat, *r_spstat; int ret, verify_checksum=FALSE; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (sp == SPNULL) return_err(proc,100,100,"Null SPFILE pointer"); w_spstat = sp->write_spifr->status; r_spstat = sp->read_spifr->status; write_name = (w_spstat->external_filename == CNULL) ? CNULL : mtrf_strdup(sp->write_spifr->status->external_filename); read_name = (r_spstat->external_filename == CNULL) ? CNULL : mtrf_strdup(r_spstat->external_filename); if (sp->open_mode == SP_mode_update) { if (sp_verbose > 10) fprintf(spfp,"Proc %s: Mode SP_update\n",proc); if (w_spstat->write_occured_flag) { /* if there has been a spwrite, then the waveform is written */ /* as if it were a file opened for write */ /* Step 1: recursively call sp_close, changing the mode to write */ /* Step 2: delete the previous file */ /* Step 3: rename the temporary file */ if (sp_verbose > 15) fprintf(spfp,"Proc %s: Overwriting the original waveform\n", proc); sp->open_mode = SP_mode_write; if ((ret=sp_close(sp)) != 0){ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_child(proc,int,ret); } unlink(read_name); rename(write_name,read_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } else { /* the header has been changed and the data mode of the waveform */ /* COULD BE CHANGED the waveform has not been modified in any */ /* way, only the header has changed */ /* Step 1: write the header into the temporary file */ /* Step 2: If the header changed in size OR the waveform */ /* format has changed */ /* A: copy the waveform into the temp file */ /* B: close the files */ /* C: delete the old file in favor of the new file */ /* Else the header has not changed in size. */ /* A: write the header into the original file */ /* B: Close both files */ /* C: delete the temporary file */ FILE *fp; int samples_read, samples_written; /* Step 1: */ spifr = sp->write_spifr; fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (sp_verbose > 15) fprintf(spfp, "Proc %s: Writing header to temp file. position %d\n", proc,ftell(fp)); if (fp == FPNULL){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3000,3000,"Internal Error"); } /* Write the header into the temporary file to compute the size */ /* of the header and then rewind back over the just written header*/ rewind(fp); if (sp_write_header(fp,spifr->status->file_header, &header_size,&data_size) < 0){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3001,3001, "Unable to update header in file"); } rewind(fp); /* Step 2 - - if the header size or waveform has changed */ if ((sp->read_spifr->waveform->header_data_size != header_size) || (w_spstat->file_encoding != r_spstat->file_encoding) || (w_spstat->file_compress != r_spstat->file_compress) || (w_spstat->file_sbf != r_spstat->file_sbf) || (w_spstat->channels != CHANNELSNULL)){ char *buff; int ns, nc, in_nspb, out_nspb; if (sp_verbose > 15) { fprintf(spfp,"Proc %s: output header and/or",proc); fprintf(spfp,"data has changed, copying file.\n"); fprintf(spfp,"Proc %s: from %d to %d\n",proc, sp->read_spifr->waveform->header_data_size, header_size); } ns = r_spstat->user_sample_count; nc = r_spstat->user_channel_count; in_nspb = r_spstat->user_sample_n_bytes * r_spstat->user_channel_count; out_nspb = w_spstat->user_sample_n_bytes * w_spstat->user_channel_count; if ((buff=mtrf_malloc(nc * in_nspb * 4096)) == CNULL) { free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3010,3010, "Unable to malloc transfer buffer space"); } /* A: */ do { sp->open_mode = SP_mode_read; samples_read = sp_read_data(buff,4096,sp); if (samples_read > 0) { sp->open_mode = SP_mode_write; samples_written = sp_write_data(buff,samples_read,sp); if (samples_written != samples_read){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3012,3012, "Copy of waveform data failed"); } } else { if (sp_eof(sp) == 0) { free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3013,3013, "Error: Zero samples read while not at EOF"); } if (sp_error(sp) >= 100) { /* a checksum error occured, close the sp and */ /* delete the temp file */ sp->open_mode = SP_mode_update; sp_print_return_status(spfp); free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); mtrf_free(buff); return_err(proc,3011,3011, "Error copying waveform data"); } } sp->open_mode = SP_mode_update; } while (samples_read > 0); mtrf_free(buff); /* make sure the file is at eof (as if it were opened for */ /* read) */ sp->open_mode = SP_mode_read; if (! sp_eof(sp)){ sp->open_mode = SP_mode_update; free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3012,3012,"Error copying waveform data"); } sp->open_mode = SP_mode_write; if ((ret=sp_close(sp)) != 0){ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_child(proc,int,ret); } /* C: */ unlink(read_name); rename(write_name,read_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } else { /* A: */ spifr = sp->read_spifr; fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (fp == FPNULL) return_err(proc,3002,3002,"Internal Error"); rewind(fp); if (sp_verbose > 15) fprintf(spfp, "Proc %s: header size not changed. position %d\n", proc,ftell(fp)); if (sp_write_header(fp,w_spstat->file_header, &header_size,&data_size) < 0){ free_sphere_t(sp); unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,3003,3003, "Unable to update header in file"); } /* B: */ free_sphere_t(sp); /* C: */ unlink(write_name); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); } } } /* END of update mode file */ if (sp->open_mode == SP_mode_write) { if (sp_verbose > 10) fprintf(spfp, "Proc %s: Mode SP_mode_write\n",proc); spifr = sp->write_spifr; /* flush the data to the file */ if (spifr->status->is_disk_file) fob_fflush(spifr->waveform->sp_fob); /* if the mode is write, update the sample_count and checksum */ /* field if needed. If the checksum field exists, verify it, */ /* and warn if it's not the same */ /************ ONLY UPDATE FIELDS IF THE FILE IS NOT A STREAM *********/ if (spifr->status->is_disk_file){ h_get_field(w_spstat->file_header, SAMPLE_COUNT_FIELD, T_INTEGER, (void *)&lint); if (spifr->waveform->samples_written != lint) { /* then update the field */ lint = (SP_INTEGER) spifr->waveform->samples_written; spifr->status->file_sample_count = lint; /* temporarily reset the write occured flag to allow header */ /* modifications */ w_spstat->write_occured_flag = FALSE; if (sp_h_set_field(sp,SAMPLE_COUNT_FIELD,T_INTEGER,&lint) !=0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,200,200,"Unable to update sample_count"); } /* Reset the write occured flag */ w_spstat->write_occured_flag = TRUE; header_changed = TRUE; } if (h_get_field(spifr->status->file_header,SAMPLE_CHECKSUM_FIELD, T_INTEGER,(void *)&lint) != 0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,201,201, "Unable to get sample_checksum for file on disk"); } if (lint != spifr->status->file_checksum) { /* then the checksum was just computed, so install it */ lint = (SP_INTEGER)spifr->waveform->checksum; /* temporarily reset the write occured flag to allow header */ /* modifications */ w_spstat->write_occured_flag = FALSE; if (sp_h_set_field(sp,SAMPLE_CHECKSUM_FIELD, T_INTEGER,&lint) >= 100){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,202,202,"Unable to update checksum"); } /* Reset the write occured flag */ w_spstat->write_occured_flag = TRUE; header_changed = TRUE; } else if (lint != spifr->waveform->checksum) { spifr->waveform->failed_checksum = TRUE; if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,203,203, rsprintf("Write verification of checksum failed on file %s", spifr->status->external_filename)); } } /* flush the updated header to the file */ if (header_changed) { FILE *fp; if (! spifr->status->is_disk_file) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,301,301, "Internal Error, header changed size on write to stdout"); } fp = ((spifr->waveform->sp_fp != FPNULL) ? (spifr->waveform->sp_fp) : ((spifr->waveform->sp_fob->fp != FPNULL) ? (spifr->waveform->sp_fob->fp) : FPNULL)); if (fp == FPNULL) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,300,300,"Internal Error"); } rewind(fp); if (sp_write_header(fp,spifr->status->file_header, &header_size,&data_size) < 0) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,204,204,"Unable to update header in file"); } } if ((spifr->status->is_temp_file == FALSE) && fob_is_fp(spifr->waveform->sp_fob)) { /* check to make sure the blocking has not changed */ if (header_changed) if (((data_size + PAD_MULT) / PAD_MULT) != ((spifr->waveform->header_data_size + PAD_MULT) /PAD_MULT)){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,205,205, "Header size has changed on update"); } } else { if (spifr->status->user_compress == spifr->status->file_compress){ if (fob_flush_to_fp(spifr->waveform->sp_fob, spifr->waveform->sp_fp) != 0){ if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,206,206,"Unable to flush data to disk"); } } else { /* do some compression */ FOB *comp_fob; /* 1. rewind the data */ /* 2. alloc FOB to compress into */ /* 3. compress the file */ /* 4. free the allocated FOB */ fob_rewind(spifr->waveform->sp_fob); if ((comp_fob = fob_create(spifr->waveform->sp_fp)) == FOBPNULL) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,207,207,"Unable to setup for compression"); } spifr->waveform->sp_fp = FPNULL; switch (spifr->status->file_compress){ char message[70]; case SP_wc_shorten: /* optimize the compression */ shorten_set_channel_count(spifr->status->file_channel_count); if (spifr->status->file_encoding == SP_se_ulaw) shorten_set_ftype("au"); else if (spifr->status->file_encoding == SP_se_pcm1) shorten_set_ftype("s8"); else if (spifr->status->file_encoding == SP_se_pcm2) if (spifr->status->file_sbf == SP_sbf_01) shorten_set_ftype("s16lh"); else shorten_set_ftype("s16hl"); if (sp_verbose > 15) shorten_dump_flags(spfp); if(setjmp(exitenv) == 0){ if (shorten_compress(spifr->waveform->sp_fob, comp_fob, message) < 0){ fob_destroy(comp_fob); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,208,208, rsprintf("Shorten Compression Failed - %s", message)); } } else return_err(proc,213,0,"Shorten Compression Aborted"); fob_fflush(comp_fob); break; case SP_wc_wavpack: if(setjmp(exitenv) == 0){ /* optimize the compression */ wavpack_set_progname( "wavpack" ); if (spifr->status->file_channel_count == 1) wavpack_set_monoflg(TRUE); else wavpack_set_monoflg(FALSE); wavpack_set_byteflg(spifr->status->file_sbf ==SP_sbf_1); if (sp_verbose > 15) wavpack_dump_interface(spfp); if (wavpack_pack(spifr->waveform->sp_fob, comp_fob)<0){ fob_destroy(comp_fob); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,209,209, "Wavpack Compression Failed"); } wavpack_free_progname(); fob_fflush(comp_fob); } else { return_err(proc,212,0,"Wavpack Compression Aborted"); } break; case SP_wc_shortpack: return_err(proc,211,211, "Unable to Compress using shortpack\n"); default: if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); free_sphere_t(sp); return_err(proc,210,210, "Unable to Compress the requested format\n"); } spifr->waveform->sp_fp = comp_fob->fp; fob_destroy(comp_fob); } } if ((sp->open_mode == SP_mode_write) || (sp->open_mode == SP_mode_update)) if (w_spstat->extra_checksum_verify) verify_checksum = TRUE; } free_sphere_t(sp); /*************************************************/ /* The file is now completely written and closed */ /*************************************************/ /**************************************************/ /* If the write verification is requested, do it */ if (verify_checksum) { if (strsame(write_name,"-")) { if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_warn(proc,1,1, "Unable to verify checksum, file went to STDOUT"); } if (verify_file_checksum(write_name) != 0){ sp_print_return_status(spfp); if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_err(proc,1000,1000, "Read Verification of written file failed"); } } if (write_name != CNULL) mtrf_free(write_name); if (read_name != CNULL) mtrf_free(read_name); return_success(proc,0,0,"ok"); }
static int decompress_waveform(SP_FILE *sp) { int decomp_into_memory=TRUE; int wav_bytes=0; SPIFR *spifr = sp->read_spifr; FOB *fob_in, *fob_out; char *buff; int blen; char *proc="decompress_waveform " SPHERE_VERSION_STR; wav_bytes = spifr->status->user_sample_count * spifr->status->user_channel_count * spifr->status->user_sample_n_bytes; /* the file must be decompressed, Question: Should it be done in memory? */ if (wav_bytes > MAX_INTERNAL_WAVFORM) decomp_into_memory = FALSE; /* The file needs to be de_compressed into memory !!!! */ /* 1. make an FOB struct for the uncompressed waveform to be read into d */ /* and the original file */ /* 2. allocate memory for the entire waveform */ /* 3. decompress the file */ /* 4. Clean up the FOB struct for the file, moving the fp from the FOB */ /* 5. reset the uncompressed FOB struct to the beginning of the memory */ if (decomp_into_memory) { if (sp_verbose > 15) fprintf(spfp,"Proc %s: Pre-buffering compressed data into memory\n", proc); if (fob_create2(spifr->waveform->sp_fp, FPNULL, &fob_in, &fob_out) < 0) return_err(proc,200,0,"Unable to setup for decompression"); blen = spifr->status->file_channel_count * spifr->status->file_sample_count * spifr->status->file_sample_n_bytes; if ((buff=mtrf_malloc(blen)) == CNULL){ fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,201,0,"Unable to malloc memory to decompress into"); } fob_bufinit(fob_out, buff, blen); } else { /* decompress into a disk file */ FILE *temp_fp; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Pre-buffering compressed data %s\n", proc,"into a temporary file"); spifr->status->temp_filename = sptemp_dirfile(); if (spifr->status->temp_filename == CNULL) return_err(proc,400,0,"Unable to create usable temporary file"); if (sp_verbose > 15) fprintf(spfp,"Proc %s: %s%d bytes long, using temp file %s\n", proc, "Attempting to read a big file ",wav_bytes, spifr->status->temp_filename); if ((temp_fp=fopen(spifr->status->temp_filename,TRUNCATE_UPDATEMODE)) == FPNULL) return_err(proc,401,0, rsprintf("Unable to open temporary file %s", spifr->status->temp_filename)); if (fob_create2(spifr->waveform->sp_fp, temp_fp, &fob_in, &fob_out) <0) return_err(proc,402,0,"Unable to setup for decompression"); /* the FILE pointer will be closed after completion of the */ /* decompression directly from the fob_in FOB pointer. this is the */ /* bug which Francis caught. */ /* Note: Do NOT set the waveform file to FPNULL here (see bugfix */ /* below.) ***PSI*** 24-Sep-1993 */ /* spifr->waveform->sp_fp = FPNULL; */ spifr->status->is_temp_file = TRUE; } if (sp_verbose > 15) fprintf(spfp, "Proc %s: before decompression, input file at position %d\n", proc,fob_ftell(fob_in)); switch (spifr->status->file_compress){ char message[80]; case SP_wc_shorten: if (sp_verbose > 15) fprintf(spfp,"Proc %s: Executing Shorten Decompression\n",proc); if (setjmp(exitenv) == 0){ if (shorten_uncompress(fob_in, fob_out, message) < 0){ fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,202,0, rsprintf("Shorten Decompression Failed",message)); } } else { fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,207,0,"Shorten Decompression aborted"); } break; case SP_wc_wavpack: if(setjmp(exitenv) == 0){ if (sp_verbose > 15) fprintf(spfp,"before set progname\n"); wavpack_set_progname( "wavpack" ); if (sp_verbose > 15) fprintf(spfp, "Proc %s: Executing Wavpack Decompression\n",proc); if (sp_verbose > 15) wavpack_dump_interface(spfp); if (wavpack_unpack(fob_in, fob_out) < 0){ fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,203,0,"Wavpack Decompression Failed"); } wavpack_free_progname(); } else { fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,206,0,"Wavpack Decompression aborted"); } break; case SP_wc_shortpack: if(setjmp(exitenv) == 0){ if (sp_verbose > 15) fprintf(spfp, "Proc %s: Executing Shortpack Decompression\n",proc); if (shortpack_uncompress(fob_in, fob_out, spifr->status->file_header) < 0){ fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,203,0,"Shortpack Decompression Failed"); } } else { fob_destroy(fob_in); fob_destroy(fob_out); return_err(proc,208,0,"Shortpack Decompression aborted"); } break; default: return_err(proc,209,0,"Unable to decompress the requested format\n"); } fob_rewind(fob_out); /**** Begin SRI bugfix. ****/ /* If a temporary file is being used, close the waveform file BEFORE */ /* setting it to FPNULL. ***PSI*** 24-Sep-1993 */ if (spifr->status->is_temp_file) { if (sp_verbose > 15) fprintf(spfp,"Proc %s: Closing waveform file \"%s\" (%d)\n", proc, spifr->status->external_filename, fileno(spifr->waveform->sp_fp)); if (fclose(spifr->waveform->sp_fp)) return_err(proc, 403, 0, rsprintf("Unable to close waveform file \"%s\" (%d)", spifr->status->external_filename, fileno(spifr->waveform->sp_fp))); spifr->waveform->sp_fp = FPNULL; } /**** End SRI bugfix. ****/ if (! decomp_into_memory) { /* Close the original file pointer to the SPHERE file */ fclose(fob_in->fp); } fob_destroy(fob_in); spifr->waveform->sp_fob = fob_out; return_success(proc,0,0,"ok"); }
/* * * sp_read_data() * */ int sp_mc_read_data(void *buffer, size_t num_sample, SP_FILE *sp) { char *proc="sp_read_data " SPHERE_VERSION_STR; SPIFR *spifr; int ret; int do_conversions, do_channel_selections; if (buffer == (void *)0) return_err(proc,100,0,"Null memory buffer"); if (sp == SPNULL) return_err(proc,101,0,"Null SPFILE structure"); if (sp->open_mode != SP_mode_read) return_err(proc,104,104,"Read on a file not opened for read"); #ifdef isnotansi if (num_sample < 0) return_err(proc,103,0, rsprintf("Negative sample count %d",num_sample)); #endif spifr = sp->read_spifr; if (sp_verbose > 10) fprintf(spfp, "Proc %s: file %s, %d bytes/sample, %d channels, %d samples\n", proc,spifr->status->external_filename, spifr->status->user_sample_n_bytes, spifr->status->user_channel_count, num_sample); if (spifr->waveform->failed_checksum) return_err(proc,1001,0,"Pre-Read Checksum Test Failed"); /***********************************************************************/ /* Perform all initializations to the sphere file to begin reading */ if (spifr->status->read_occured_flag == FALSE) { spifr->status->read_occured_flag = TRUE; if (sp_verbose > 15) fprintf(spfp, "Proc %s: Initializing read of data\n", proc); if ((spifr->status->user_compress == SP_wc_none) && (spifr->status->file_compress != SP_wc_none)){ decompress_waveform(sp) ; if ((ret = sp_get_return_status()) != 0) return_err(proc,ret,0, rsprintf("decompress_waveform failed, %s", get_return_status_message())); } else { /* The following code assumes that no pre-reading of the */ /* waveform is needed */ if ((spifr->waveform->sp_fob = fob_create(spifr->waveform->sp_fp)) == FOBPNULL) return_err(proc,300,0, "Unable to allocate a FOB 'File or Buffer' struct."); spifr->waveform->sp_fp = FPNULL; } /****************************************************/ /** INVARIANT ASSERTION: **/ /** The data is now in it's natural (decomp) form **/ /****************************************************/ /************ Set up the file conversions ***********/ /****************************************************/ /* Set up byte format the conversions */ if (spifr->status->user_sbf != spifr->status->file_sbf) if (((spifr->status->user_sbf == SP_sbf_01) && (spifr->status->file_sbf == SP_sbf_10)) || ((spifr->status->user_sbf == SP_sbf_10) && (spifr->status->file_sbf == SP_sbf_01))) fob_read_byte_swap(spifr->waveform->sp_fob); /********************************************************/ /* set up a translation buffer, for sample conversions */ /* and channel selections */ /* are sample encodings necessary ????? */ do_conversions = FALSE; if (spifr->status->user_encoding != spifr->status->file_encoding) { if (((spifr->status->file_encoding == SP_se_ulaw) && (spifr->status->user_encoding == SP_se_pcm2)) || ((spifr->status->file_encoding == SP_se_pcm2) && (spifr->status->user_encoding == SP_se_ulaw))) do_conversions = TRUE; else return_err(proc,400,0, "Unable to convert sample types ... for now\n"); } /* are channel selection requested ????? */ do_channel_selections = FALSE; if (spifr->status->channels != CHANNELSNULL) do_channel_selections = TRUE; if (do_conversions || do_channel_selections || (spifr->status->user_data_fmt == SP_df_array)){ /* allocate the memory for the file data buffer */ /* IF it's a legal transformation */ spifr->waveform->file_data_buffer_len = TRANSLATION_LEN * spifr->status->file_sample_n_bytes * spifr->status->file_channel_count; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes%s\n", proc, spifr->waveform->file_data_buffer_len,TRANSLATION_LEN, spifr->status->file_sample_n_bytes, spifr->status->file_channel_count, " for file data buffer"); if ((spifr->waveform->file_data_buffer = (void *) mtrf_malloc(spifr->waveform->file_data_buffer_len)) == (void *)0) return_err(proc,500,0, "Unable to alloc memory for the translation buffer"); } if (do_conversions && (do_channel_selections || (spifr->status->user_data_fmt == SP_df_array))){ spifr->waveform->converted_buffer_len = TRANSLATION_LEN * spifr->status->user_sample_n_bytes * spifr->status->file_channel_count; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes %s\n", proc, spifr->waveform->converted_buffer_len,TRANSLATION_LEN, spifr->status->user_sample_n_bytes, spifr->status->file_channel_count, "for converted data buffer"); if ((spifr->waveform->converted_buffer = (void *) mtrf_malloc(spifr->waveform->converted_buffer_len)) == (void *)0) return_err(proc,550,0, "Unable to alloc memory for the translation buffer"); } if (spifr->status->user_data_fmt == SP_df_array){ spifr->waveform->interleave_buffer_len = TRANSLATION_LEN * spifr->status->user_sample_n_bytes * spifr->status->user_channel_count; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Alloc %d (%d*%d*%d) bytes %s\n", proc, spifr->waveform->interleave_buffer_len,TRANSLATION_LEN, spifr->status->user_sample_n_bytes, spifr->status->user_channel_count, "for interleave data buffer"); if ((spifr->waveform->interleave_buffer = (void *) mtrf_malloc(spifr->waveform->interleave_buffer_len)) == (void *)0) return_err(proc,600,0, "Unable to alloc memory for the interleave buffer"); } /* pre-verify the waveform data */ if (spifr->status->extra_checksum_verify){ pre_verify_checksum(sp); if ((ret = sp_get_return_status()) != 0) return_err(proc,ret,0, rsprintf("pre_verify_checksum failed, %s", get_return_status_message())); } } if (sp_verbose > 15) fprintf(spfp, "Proc %s: current file position %d\n",proc, fob_ftell(spifr->waveform->sp_fob)); ret = read_data_in(buffer, num_sample, sp); if (sp_get_return_type() == RETURN_TYPE_ERROR) return_err(proc,sp_get_return_status(),0, rsprintf("read_data_in failed, %s", get_return_status_message())); return_success(proc,0,ret,"ok"); }
static int read_data_in(void *buffer, size_t num_sample, SP_FILE *sp){ SPIFR *spifr; char *proc=" read_data_in " SPHERE_VERSION_STR; int samples_read = 0; int in_samples=0, o, oc, s, c, ret; int block=0; char *in_block=(char *)0, *out_block=(char *)0; char *current_data_location = (char *)0; char *out_conversion_block=(char *)0,*in_conversion_block=(char *)0; char *next_out_block=(char *)0; short *sh_data=(short *)0; unsigned char *ulaw_data = (unsigned char *)0; SP_CHECKSUM checksum=0, block_checksum=0; int file_record_size; char **arr_buff = (char **)0, *arr; spifr = sp->read_spifr; file_record_size = spifr->status->file_sample_n_bytes * spifr->status->file_channel_count; while ((samples_read < num_sample) && (! fob_feof(spifr->waveform->sp_fob))){ if (sp_verbose > 16) fprintf(spfp,"Proc %s: Beginning block %d\n",proc,block); /* read in either a block or the whole chunk if data */ if (spifr->waveform->file_data_buffer != CNULL) { if (sp_verbose > 15) fprintf(spfp, "Proc %s: reading a block into temporary storage\n", proc); in_block = (void *)spifr->waveform->file_data_buffer; current_data_location = in_block; if ((in_samples = (num_sample - samples_read))> TRANSLATION_LEN) in_samples = TRANSLATION_LEN; ret = fob_fread(in_block, file_record_size, in_samples, spifr->waveform->sp_fob); if (ret < 0) return_err(proc,105,0,"Unable to read data"); } else { /* there was no change in the sample coding so just read */ /* in the data */ if (sp_verbose > 15) fprintf(spfp, "Proc %s: read a block WITHOUT coding conversions\n", proc); ret = fob_fread(buffer, file_record_size, num_sample, spifr->waveform->sp_fob); if (ret < 0) return_err(proc,107,0,"Unable to read data"); in_block = (void *)buffer; current_data_location = in_block; } if (sp_verbose > 16) fprintf(spfp, "Proc %s: block read of %d Samples, expected %d\n", proc,ret,num_sample); in_samples = ret; /**** ret is the number of samples per time period read in from */ /**** the file */ /**** Do the checksum computation before format changes occur ***/ switch (spifr->status->file_encoding){ case SP_se_pcm2: /* DON'T SWAP if the coding type hasn't changed, and the */ /* output SBF == natural_sbf */ /* OR if the coding changed and the file SBF */ /* is == natural SBF */ if (((spifr->status->user_encoding == SP_se_pcm2) && (spifr->status->natural_sbf == spifr->status->user_sbf)) || ((spifr->status->user_encoding != SP_se_pcm2) && (spifr->status->natural_sbf == spifr->status->file_sbf))){ if (sp_verbose > 16) fprintf(spfp, "Proc %s: Not Swapping for checksum\n",proc); checksum = sp_compute_short_checksum((void *)in_block,in_samples* spifr->status->file_channel_count, FALSE); } else { if (sp_verbose > 16) fprintf(spfp,"Proc %s: Swapping for checksum\n",proc); checksum = sp_compute_short_checksum((void *)in_block, in_samples*spifr->status->file_channel_count, TRUE); } break; default: { int n; n = in_samples * spifr->status->file_channel_count * spifr->status->file_sample_n_bytes; if (sp_verbose > 16) fprintf(spfp,"Proc %s: Computing char checksum %d bytes\n", proc,n); checksum = sp_compute_char_checksum(in_block, n); break; } } spifr->waveform->checksum = sp_add_checksum(spifr->waveform->checksum,checksum); block_checksum = checksum; /*** FINISHED WITH THE CHECKSUMS ***/ samples_read += in_samples; spifr->waveform->samples_read += in_samples; if (sp_eof(sp)) /* only check this if the user_sample count is real */ /* Added June 22, 1994 by JGF */ if (spifr->status->user_sample_count != 999999999){ if (spifr->waveform->samples_read != spifr->status->user_sample_count){ spifr->waveform->read_premature_eof = TRUE; return_err(proc,500,0, rsprintf("Premature End-of-File %d read != %d", spifr->waveform->samples_read, spifr->status->user_sample_count)); } } if (spifr->waveform->samples_read == spifr->status->user_sample_count){ if ((! spifr->status->ignore_checksum) && (spifr->waveform->checksum != spifr->status->file_checksum)){ spifr->waveform->failed_checksum = TRUE; return_err(proc,1000,0, rsprintf("%sComputed %d != Expected %d", "Checksum Test Failed ", spifr->waveform->checksum, spifr->status->file_checksum)); } } /**** Do the sample coding conversions ****/ if (((spifr->status->file_encoding == SP_se_ulaw) && (spifr->status->user_encoding == SP_se_pcm2)) || ((spifr->status->file_encoding == SP_se_pcm2) && (spifr->status->user_encoding == SP_se_ulaw))) { int samples_to_change = in_samples*spifr->status->file_channel_count; if ((spifr->status->channels != CHANNELSNULL) || (spifr->status->user_data_fmt == SP_df_array)){ out_conversion_block = next_out_block = (char *)spifr->waveform->converted_buffer; if (sp_verbose > 16) fprintf(spfp,"Proc %s: using converted buffer output\n", proc); } else { out_conversion_block = (char *)buffer; if (sp_verbose > 16) fprintf(spfp,"Proc %s: using buffer output argument\n", proc); if (next_out_block == (char *)0) next_out_block = out_conversion_block; } if (sp_verbose > 16) fprintf(spfp, "Proc %s: converting %d (%d*%d) samples\n",proc, samples_to_change,in_samples, spifr->status->file_channel_count); if ((spifr->status->file_encoding == SP_se_ulaw) && (spifr->status->user_encoding == SP_se_pcm2)) { /* now convert the block into the buffer */ if (sp_verbose > 16) fprintf(spfp,"Proc %s: Converting ULAW to PCM", proc); /* set up some pointers */ ulaw_data = (unsigned char *)spifr->waveform->file_data_buffer; sh_data = (short *)next_out_block ; /*** This was a bug, it used to compare to sp_sbf_10 ***/ if (spifr->status->user_sbf != get_natural_sbf(2)){ if (sp_verbose > 16) fprintf(spfp," outputting 01 format bytes\n"); for (o=0; o < samples_to_change; o++) { *sh_data = ulaw2linear_01_sbf_lut[*ulaw_data]; sh_data ++; ulaw_data ++; } } else { if (sp_verbose > 16) fprintf(spfp," outputting 10 format bytes\n"); for (o=0; o < samples_to_change; o++) { *sh_data = ulaw2linear_10_sbf_lut[*ulaw_data]; sh_data ++; ulaw_data ++; } } next_out_block = (char *)sh_data; } else if ((spifr->status->file_encoding == SP_se_pcm2) && (spifr->status->user_encoding == SP_se_ulaw)) { if (sp_verbose > 16) fprintf(spfp,"Proc %s: Performing read translation%s\n", proc," from PCM2 to ULAW"); /* set up some pointers */ sh_data = (short *)spifr->waveform->file_data_buffer; ulaw_data = (unsigned char *)next_out_block; if (spifr->status->file_sbf != spifr->status->natural_sbf){ char *p , temp; short odata; if (sp_verbose > 16) fprintf(spfp, "Proc %s: Swapping input shorts\n", proc); for (o=0; o < samples_to_change; o++) { /* Pre swap the bytes */ odata = *sh_data; p = (char *) &odata; temp = *p; *p = *(p + 1); *(p + 1) = temp; /* fprintf(spfp, " %d -> %x -> %x\n",o,*sh_data,odata); */ *ulaw_data = linear2ulaw(odata); sh_data ++; ulaw_data ++; } }else for (o=0; o < samples_to_change; o++) { *ulaw_data =linear2ulaw(*sh_data); sh_data ++; ulaw_data ++; } next_out_block = (char *)ulaw_data; } else return_err(proc,109,0,"Internal Error"); current_data_location = out_conversion_block; } /* Do the channel conversions */ if (spifr->status->channels != CHANNELSNULL){ int in_recsize, out_recsize, in_chancnt, out_chancnt; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Converting channels\n",proc); if (spifr->status->user_data_fmt == SP_df_array) out_block = spifr->waveform->interleave_buffer; else if (out_block == (void *)0) out_block = (void *)buffer; current_data_location = out_block; if (spifr->status->file_encoding != spifr->status->user_encoding) in_conversion_block = (void *)spifr->waveform->converted_buffer; else if (in_conversion_block == (void *)0) in_conversion_block = (void *)spifr->waveform->file_data_buffer; in_chancnt = spifr->status->file_channel_count; in_recsize = spifr->status->user_sample_n_bytes * in_chancnt; out_chancnt = spifr->status->user_channel_count; out_recsize = spifr->status->user_sample_n_bytes * out_chancnt; for (oc=0; oc<spifr->status->channels->num_chan; oc++) if (spifr->status->channels->ochan[oc].num_origin == 1){ char *in_ptr, *out_ptr; in_ptr = in_conversion_block + ((spifr->status->channels->ochan[oc].orig_channel[0]-1) * spifr->status->user_sample_n_bytes); out_ptr = out_block + (oc * spifr->status->user_sample_n_bytes); for (s=0; s<in_samples; s++){ memcpy(out_ptr,in_ptr, spifr->status->user_sample_n_bytes); in_ptr += in_recsize; out_ptr += out_recsize; } } else { if (spifr->status->user_encoding == SP_se_pcm2) { /* do a straight add */ ORIGINATION_CHAN *ochn; short *in_ptr, *out_ptr; int sum, ch; if (sp_verbose > 15) fprintf(spfp, "Proc %s: Adding PCM data %s %d\n", proc, "channel",oc); in_ptr = (short *)in_conversion_block; out_ptr = (short *)out_block; ochn = &(spifr->status->channels->ochan[oc]); if (spifr->status->user_sbf== get_natural_sbf(2)){ for (s=0; s<in_samples; s++){ for (ch=0, sum=0; ch < ochn->num_origin; ch++){ sum +=*(in_ptr+ochn->orig_channel[ch]-1); } if (sum > 32767) sum = 32767; else if (sum < -32768) sum = -32768; *(out_ptr + oc) = (short)sum; in_ptr += in_chancnt; out_ptr += out_chancnt; } } else { short x; if (sp_verbose > 15) fprintf(spfp,"Proc %s: %s %d\n", proc, "Adding Swapped PCM data channel",oc); for (s=0; s<in_samples; s++){ /* fprintf(spfp,"sample %d\n",s); */ for (ch=0, sum=0; ch < ochn->num_origin; ch++){ x = *(in_ptr+ochn->orig_channel[ch]-1); swap_bytes(x); sum += x; /* fprintf(spfp," %d = %d\n",x,sum); */ } if (sum > 32767) x = 32767; else if (sum < -32768) x = -32768; else x = sum; swap_bytes(x); *(out_ptr + oc) = (short)x; in_ptr += in_chancnt; out_ptr += out_chancnt; } } } else if (spifr->status->user_encoding == SP_se_ulaw){ /* do an add on ulaw data */ ORIGINATION_CHAN *ochn; unsigned char *in_ptr, *out_ptr; int sum, ch; if (sp_verbose > 15) fprintf(spfp, "Proc %s: Adding ULAW data %s %d\n", proc, "channel",oc); in_ptr = (unsigned char *)in_conversion_block; out_ptr = (unsigned char *)out_block; ochn = &(spifr->status->channels->ochan[oc]); for (s=0; s<in_samples; s++){ for (ch=0, sum=0; ch < ochn->num_origin; ch++){ sum += ulaw2linear_10_sbf_lut[ *(in_ptr+ochn->orig_channel[ch]-1)]; } if (sum > 32767) sum = 32767; else if (sum < -32768) sum = -32768; *(out_ptr + oc) = linear2ulaw(sum); in_ptr += in_chancnt; out_ptr += out_chancnt; } } } out_block += out_recsize * in_samples; } if (spifr->status->user_data_fmt == SP_df_array){ /* convert the data from it's interleaved form */ /* to an array format */ int snb = spifr->status->user_sample_n_bytes; int chcnt = spifr->status->user_channel_count; int recsize = snb * chcnt; char *in_dat; if (sp_verbose > 15) fprintf(spfp,"Proc %s: Converting data to an array\n", proc); if (arr_buff == (char **)0) arr_buff = (char **)buffer; for (c=0; c<chcnt; c++){ in_dat = current_data_location + (snb * c) ; arr = arr_buff[c] + ((samples_read-in_samples) * snb); for (s=0; s<in_samples; s++,arr+=snb,in_dat+=recsize) memcpy(arr,in_dat,snb); } } if (sp_verbose > 11){ fprintf(spfp,"Proc %s: Block %d: Requested %d samples", proc,block++,num_sample); fprintf(spfp," read %d total %d, Checksum %d (BC %d)\n", ret,spifr->waveform->samples_read, block_checksum, spifr->waveform->checksum); } } return_success(proc,0,samples_read,"ok"); }
// ALWAYS generates an HTML reply // int handle_file_upload(FILE* in, R_RSA_PUBLIC_KEY& key) { char buf[256], path[MAXPATHLEN], signed_xml[1024]; char name[256], stemp[256]; double max_nbytes=-1; char xml_signature[1024]; int retval; double offset=0, nbytes = -1; bool is_valid, btemp; strcpy(name, ""); strcpy(xml_signature, ""); bool found_data = false; while (fgets(buf, 256, in)) { #if 1 log_messages.printf(MSG_NORMAL, "got:%s\n", buf); #endif if (match_tag(buf, "<file_info>")) continue; if (match_tag(buf, "</file_info>")) continue; if (match_tag(buf, "<signed_xml>")) continue; if (match_tag(buf, "</signed_xml>")) continue; if (parse_bool(buf, "generated_locally", btemp)) continue; if (parse_bool(buf, "upload_when_present", btemp)) continue; if (parse_str(buf, "<url>", stemp, sizeof(stemp))) continue; if (parse_str(buf, "<md5_cksum>", stemp, sizeof(stemp))) continue; if (match_tag(buf, "<xml_signature>")) { copy_element_contents( in, "</xml_signature>", xml_signature, sizeof(xml_signature) ); continue; } if (parse_str(buf, "<name>", name, sizeof(name))) { strcpy(this_filename, name); continue; } if (parse_double(buf, "<max_nbytes>", max_nbytes)) continue; if (parse_double(buf, "<offset>", offset)) continue; if (parse_double(buf, "<nbytes>", nbytes)) continue; if (match_tag(buf, "<data>")) { found_data = true; break; } log_messages.printf(MSG_CRITICAL, "unrecognized: %s", buf); } if (strlen(name) == 0) { return return_error(ERR_PERMANENT, "Missing name"); } if (!found_data) { return return_error(ERR_PERMANENT, "Missing <data> tag"); } if (!config.ignore_upload_certificates) { if (strlen(xml_signature) == 0) { return return_error(ERR_PERMANENT, "missing signature"); } if (max_nbytes < 0) { return return_error(ERR_PERMANENT, "missing max_nbytes"); } sprintf(signed_xml, "<name>%s</name><max_nbytes>%.0f</max_nbytes>", name, max_nbytes ); retval = check_string_signature( signed_xml, xml_signature, key, is_valid ); if (retval || !is_valid) { log_messages.printf(MSG_CRITICAL, "check_string_signature() [%s] [%s] retval %d, is_valid = %d\n", signed_xml, xml_signature, retval, is_valid ); log_messages.printf(MSG_NORMAL, "signed xml: %s\n", signed_xml ); log_messages.printf(MSG_NORMAL, "signature: %s\n", xml_signature ); return return_error(ERR_PERMANENT, "invalid signature"); } } if (nbytes < 0) { return return_error(ERR_PERMANENT, "nbytes missing or negative"); } // enforce limits in signed XML // if (!config.ignore_upload_certificates) { if (nbytes > max_nbytes) { sprintf(buf, "file size (%d KB) exceeds limit (%d KB)", (int)(nbytes/1024), (int)(max_nbytes/1024) ); copy_socket_to_null(in); return return_error(ERR_PERMANENT, buf); } } // make sure filename is legit // if (strstr(name, "..")) { return return_error(ERR_PERMANENT, "file_upload_handler: .. found in filename: %s", name ); } if (strlen(name) == 0) { return return_error(ERR_PERMANENT, "file_upload_handler: no filename; nbytes %f", nbytes ); } retval = dir_hier_path( name, config.upload_dir, config.uldl_dir_fanout, path, true ); if (retval) { log_messages.printf(MSG_CRITICAL, "Failed to find/create directory for file '%s' in '%s'\n", name, config.upload_dir ); return return_error(ERR_TRANSIENT, "can't open file"); } log_messages.printf(MSG_NORMAL, "Starting upload of %s from %s [offset=%.0f, nbytes=%.0f]\n", name, get_remote_addr(), offset, nbytes ); #ifndef _USING_FCGI_ fflush(stderr); #endif if (offset >= nbytes) { log_messages.printf(MSG_CRITICAL, "ERROR: offset >= nbytes!!\n" ); return return_success(0); } retval = copy_socket_to_file(in, path, offset, nbytes); log_messages.printf(MSG_NORMAL, "Ended upload of %s from %s; retval %d\n", name, get_remote_addr(), retval ); #ifndef _USING_FCGI_ fflush(stderr); #endif return retval; }
// always returns HTML reply // int handle_get_file_size(char* file_name) { struct stat sbuf; char path[MAXPATHLEN], buf[256]; int retval, pid, fd; // TODO: check to ensure path doesn't point somewhere bad // Use 64-bit variant // retval = dir_hier_path( file_name, config.upload_dir, config.uldl_dir_fanout, path ); if (retval) { log_messages.printf(MSG_CRITICAL, "Failed to find/create directory for file '%s' in '%s'.\n", file_name, config.upload_dir ); return return_error(ERR_TRANSIENT, "can't open file"); } // if the volume is full, report a transient error // to prevent the client from starting a transfer // if (volume_full(config.upload_dir)) { return return_error(ERR_TRANSIENT, "Server is out of disk space"); } fd = open(path, O_WRONLY|O_APPEND); if (fd<0 && ENOENT==errno) { // file does not exist: return zero length // log_messages.printf(MSG_NORMAL, "handle_get_file_size(): [%s] returning zero\n", file_name ); return return_success("<file_size>0</file_size>"); } if (fd<0) { // can't get file descriptor: try again later // log_messages.printf(MSG_CRITICAL, "handle_get_file_size(): cannot open [%s] %s\n", file_name, strerror(errno) ); return return_error(ERR_TRANSIENT, "can't open file"); } if ((pid=mylockf(fd))) { // file locked by another file_upload_handler: try again later // close(fd); log_messages.printf(MSG_CRITICAL, "handle_get_file_size(): [%s] returning error\n", file_name ); return return_error(ERR_TRANSIENT, "[%s] locked by file_upload_handler PID=%d", file_name, pid ); } // file exists, writable, not locked by anyone else, so return length. // retval = stat(path, &sbuf); close(fd); if (retval) { // file DOES perhaps exist, but can't stat it: try again later // log_messages.printf(MSG_CRITICAL, "handle_get_file_size(): [%s] returning error %s\n", file_name, strerror(errno) ); return return_error(ERR_TRANSIENT, "cannot stat file" ); } log_messages.printf(MSG_NORMAL, "handle_get_file_size(): [%s] returning %d\n", file_name, (int)sbuf.st_size ); sprintf(buf, "<file_size>%d</file_size>", (int)sbuf.st_size); return return_success(buf); }
int parse_sample_coding(char *str, int sample_n_bytes, enum SP_sample_encoding *sample_encoding, enum SP_waveform_comp *wav_compress) { int enc_set=FALSE, comp_set=FALSE; char *pstr, *str_mem; char *proc="parse_sample_coding " SPHERE_VERSION_STR; if (sp_verbose > 10) fprintf(spfp,"Proc %s:\n",proc); if (str == CNULL) return_err(proc,101,101,"Null coding string"); if (sample_n_bytes < 1 || sample_n_bytes > 2) { /*then we are assuming the field wasn't set yet, so use the default*/ sample_n_bytes = 0; } if (sample_encoding == (enum SP_sample_encoding *)0) return_err(proc,103,103,"Null sample encoding pointer"); if (wav_compress == (enum SP_waveform_comp *)0) return_err(proc,104,104,"Null waveform compress pointer"); *wav_compress = SP_wc_null; *sample_encoding = SP_se_null; if (sp_verbose > 16) fprintf(spfp,"%s: string IS %s\n",proc,str); /* the algorithm to parse the sample encoding field is : */ /* 1: get a token before a ',' or NULL */ /* 2: set a flag to what it matches */ /* 3: move past the token */ /* 4: loop to (1) */ /* make a duplicate copy because strtok is destructive */ str_mem = mtrf_strdup(str); pstr = strtok(str_mem,","); while (pstr != CNULL){ if (sp_verbose > 16) fprintf(spfp,"%s: token found = %s\n",proc,pstr); if (strsame(pstr,"pcm")){ if (enc_set){ mtrf_free(str_mem); return_err(proc,105,105, "Multiple sample encodings in header field"); } if (sample_n_bytes == 1) *sample_encoding = SP_se_pcm1; else *sample_encoding = SP_se_pcm2; enc_set = TRUE; } else if (strsame(pstr,"ulaw") || strsame(pstr,"mu-law")) { if (enc_set){ mtrf_free(str_mem); return_err(proc,105,105, "Multiple sample encodings in header field"); } *sample_encoding = SP_se_ulaw; enc_set = TRUE; } else if (strsame(pstr,"raw")){ if (enc_set){ mtrf_free(str_mem); return_err(proc,105,105, "Multiple sample encodings in header field"); } *sample_encoding = SP_se_raw; enc_set = TRUE; } else if (strstr(pstr,"embedded-shorten-v") != CNULL) { if (comp_set) { mtrf_free(str_mem); return_err(proc,106,106, "Multiple waveform compressions in header field"); } *wav_compress = SP_wc_shorten; comp_set = TRUE; } else if (strstr(pstr,"embedded-wavpack") != CNULL) { if (comp_set){ mtrf_free(str_mem); return_err(proc,106,106, "Multiple waveform compressions in header field"); } *wav_compress = SP_wc_wavpack; comp_set = TRUE; } else if (strstr(pstr,"embedded-shortpack-v") != CNULL) { if (comp_set){ mtrf_free(str_mem); return_err(proc,106,106, "Multiple waveform compressions in header field"); } *wav_compress = SP_wc_shortpack; comp_set = TRUE; } else { mtrf_free(str_mem); return_err(proc,107,107,"Unknown token in sample coding field"); } pstr = strtok(CNULL,","); } if (*wav_compress == SP_wc_null) *wav_compress = SP_wc_none; if (*sample_encoding == SP_se_null) *sample_encoding = SP_se_pcm2; mtrf_free(str_mem); if (sp_verbose > 11) fprintf(spfp,"Proc %s: Returning 0\n",proc); return_success(proc,0,0,"ok"); }