示例#1
0
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");
}
示例#2
0
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");
}
示例#3
0
文件: sig.c 项目: alirezamirian/SPro
/*
 * Read samples into the buffer from a wave signal stream. Return the
 * number of samples per channel transfered into the buffer.  
 */
unsigned long sig_sphere_stream_read(sigstream_t *f)
{
  void *p = f->buf->s;
  unsigned long nread, i;

  nread = sp_read_data(p, f->buf->m / f->nchannels, f->f);

  if (f->swap) 
    for (i = 0; i < nread; i++, p += f->nbps)
      sp_swap(p, f->nbps);

  f->buf->n = nread * f->nchannels;
  
  return(nread);
}
示例#4
0
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");
}
示例#5
0
int diff_waveforms(char *file1, char *file2,
		   char *conv_str1, char *conv_str2, int verbose, FILE *fp)
{
    SP_FILE *sp1, *sp2;
    char *buff1=CNULL, *buff2=CNULL;
    int n1, n2, i, fail=0, blocksize=512;
    int return_value = 0;
    SP_INTEGER samples_processed=0, file1_snb, file2_snb, file1_chcnt;
    SP_INTEGER file2_chcnt;

    if ((sp1 = sp_open(file1, "r")) == SPNULL){
	fail=1;
	if (verbose)
	    fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n",file1,file2);
	if (verbose)
	    fprintf(fp,"sp_open failed on file %s\n",file1);
	sp_print_return_status(fp);
    }
    if ((sp2 = sp_open(file2, "r")) == SPNULL){
	if (fail == 0)
	    if (verbose)
	       fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n",
		       file1,file2);
	fail=1;

	if (verbose)
	    fprintf(fp,"sp_open failed on file %s\n",file2);
	sp_print_return_status(fp);
	goto FATAL_QUIT;
    }    

    if (fail)
	goto FATAL_QUIT;

    if (conv_str1 != CNULL)
	if (sp_set_data_mode(sp1,conv_str1) != 0){
	    fail=1;
	    if (verbose)
	       fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n",
		       file1,file2);
	    if (verbose)
		fprintf(fp,"sp_set_data_mode failed on file %s\n",file1);
	    sp_print_return_status(fp);
	}	    
    if (conv_str2 != CNULL)
	if (sp_set_data_mode(sp2,conv_str2) != 0){
	    if (fail == 0)
		if (verbose)
		    fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n",
			    file1,file2);
	    fail=1;
	    if (verbose) 
		fprintf(fp,"sp_set_data_mode failed on file %s\n",file2);
	    sp_print_return_status(fp);
	}
    if (fail)
	goto FATAL_QUIT;

    if (sp_h_get_field(sp1,SAMPLE_N_BYTES_FIELD,
		       T_INTEGER,(void *)&file1_snb) != 0){
	fprintf(spfp,"Unable to retieve %s field from file '%s'\n",
		SAMPLE_N_BYTES_FIELD,file1);
	goto FATAL_QUIT;
    }
    if (sp_h_get_field(sp2,SAMPLE_N_BYTES_FIELD,
		       T_INTEGER,(void *)&file2_snb) != 0){
	fprintf(spfp,"Unable to retieve %s field from file '%s'\n",
		SAMPLE_N_BYTES_FIELD,file2);
	goto FATAL_QUIT;
    }
    if (sp_h_get_field(sp1,CHANNEL_COUNT_FIELD,
		       T_INTEGER,(void *)&file1_chcnt) != 0){
	fprintf(spfp,"Unable to retieve %s field from file '%s'\n",
		CHANNEL_COUNT_FIELD,file1);
	goto FATAL_QUIT;
    }
    if (sp_h_get_field(sp2,CHANNEL_COUNT_FIELD,
		       T_INTEGER,(void *)&file2_chcnt) != 0){
	fprintf(spfp,"Unable to retieve %s field from file '%s'\n",
		CHANNEL_COUNT_FIELD,file2);
	goto FATAL_QUIT;
    }


    if ((buff1 = (char *)sp_data_alloc(sp1,blocksize)) == CNULL){
	if (verbose) fprintf(fp,"Unable to malloc memory for buffer 1\n");
	goto FATAL_QUIT;
    }
    if ((buff2 = (char *)sp_data_alloc(sp2,blocksize)) == CNULL){
	if (verbose) fprintf(fp,"Unable to malloc memory for buffer 2\n");
	goto FATAL_QUIT;
    }

    if (file1_snb != file2_snb){
	if (verbose){
	    fprintf(fp,"Files '%s' and '%s' do not have the same",
		    file1,file2);
	    fprintf(fp," sample_n_bytes value, %d and %d respectively\n",
		    file1_snb,file2_snb);
	}
	goto FATAL_QUIT;
    }	

    if (file1_chcnt != file2_chcnt){
	if (verbose){
	    fprintf(fp,"Files '%s' and '%s' do not have the same",
		    file1,file2);
	    fprintf(fp," channel_count value, %d and %d respectively\n",
		    file1_chcnt,file2_chcnt);
	}
	goto FATAL_QUIT;
    }	

    do {
	int record_size = file1_snb * file1_chcnt;
	n1 = sp_read_data((char *)buff1,blocksize,sp1);
	if ((n1 == 0) && (sp1->read_spifr->waveform->samples_read !=
			  sp1->read_spifr->status->user_sample_count)){
	    sp_print_return_status(fp);
	    goto FATAL_QUIT;
	}
	n2 = sp_read_data((char *)buff2,blocksize,sp2);
	if ((n2 == 0) && (sp2->read_spifr->waveform->samples_read !=
			  sp2->read_spifr->status->user_sample_count)){
	    sp_print_return_status(fp);
	    goto FATAL_QUIT;
	}
	if (n1 != n2){
	    if (verbose)
		fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n",
			file1,file2);
	    if (verbose) 
		fprintf(fp,"   %d samples read from '%s'\n",n1,file1);
	    if (verbose)
		fprintf(fp,"   %d samples read from '%s'\n",n2,file2);
	    goto FATAL_QUIT;
	}
	for (i=0; i<n1; i++) {
	    if (memcmp(buff1 + i*record_size,
		     buff2 + i*record_size,record_size)){
		int bn;
		if (verbose){
		  fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s sample %d\n",
			  file1,file2,samples_processed+i);
		    fprintf(fp,"    File 1:  ");
		    for (bn=0; bn < record_size; bn++) {
			fprintf(fp,"%2x ",
			     *((unsigned char *)(buff1 + i*record_size + bn)));
			if ((bn+1) % file1_snb == 0)
			    fprintf(fp,"| ");
		    }
		    fprintf(fp,"\n    File 2:  ");
		    for (bn=0; bn < record_size; bn++) {
			fprintf(fp,"%2x ",
			     *((unsigned char *)(buff2 + i*record_size + bn)));
			if ((bn+1) % file1_snb == 0)
			    fprintf(fp,"| ");
		    }
		    fprintf(fp,"\n");
		}
		goto FATAL_QUIT;
	    }
	}
	samples_processed += n1;
    } while (!sp_eof(sp1));
    if (!sp_eof(sp2)){
	if (verbose)
	    fprintf(fp,"DIFFERENT WAVEFORM: files %s and %s\n",file1,file2);
	if (verbose)
	    fprintf(fp,"   file %s not at eof\n",file2);
	goto FATAL_QUIT;
    }
    return_value = 0;
    goto CLEAN_UP;

  FATAL_QUIT:  /* Failed routine */
    return_value = 100;

  CLEAN_UP:
    if (sp1 != SPNULL) {
	if (buff1 != (char *)NULL) sp_data_free(sp1,buff1);
	sp_close(sp1);
    }
    if (sp2 != SPNULL) {
	if (buff2 != (char *)NULL) sp_data_free(sp2,buff2);
	sp_close(sp2);
    }
    return(return_value);
}
示例#6
0
static int sign_data(spctx_t *ctx)
{
    char ebuf[256];
    int n;
    DKIMContext ctxt;
    
    strncpy(dkim_opts.szRequiredHeaders, "From;To;Cc;Subject;Date;", 25);
    dkim_opts.nHash = DKIM_HASH_SHA256;
    dkim_opts.nIncludeBodyHash = DKIM_BODYHASH_IETF_1;
    dkim_opts.nCanon = DKIM_SIGN_RELAXED;
    
    if(key_is_set == 0)
    {
	FILE* keyFP = fopen( keyfile, "r" );
	if ( keyFP == NULL ) 
	{
	    sp_messagex(ctx, LOG_ERR, "Unable to open DKIM key file: %s", keyfile);
	    return -1;
	}
	n = fread( keyBuffer, 1, sizeof(keyBuffer), keyFP );
	if (n == sizeof(keyBuffer))  /* TC9 */
	{
	    sp_messagex(ctx, LOG_ERR, "DKIM key is too large, maximum size is %i", sizeof(keyBuffer));
	}
	keyBuffer[n] = '\0';
	fclose(keyFP);
	
	sp_messagex(ctx, LOG_DEBUG, "DKIM key read from %s", keyfile);
	key_is_set = 1;
    }
    
    /* Tell client to start sending data */
    if(sp_start_data (ctx) < 0)
        return -1; /* Message already printed */
        
    n = DKIMSignInit( &ctxt, &dkim_opts );
    sp_messagex(ctx, LOG_DEBUG, "DKIM signer initialised");      

    int len = -1;
    const char *buffer = 0;
    do
    {
        len = sp_read_data(ctx, &buffer);
        if(len == -1)
	{
            DKIMSignFree(&ctxt);
	    return -1;
	}
        if(len > 0)
        {
            DKIMSignProcess( &ctxt, buffer, len );
	    sp_write_data( ctx, buffer, len );
        }

    } while(len > 0);
    sp_write_data( ctx, NULL, 0 );
    
    char *dkim_signature = NULL;
    n = DKIMSignGetSig2( &ctxt, keyBuffer, &dkim_signature );
    sp_messagex(ctx, LOG_DEBUG, "Signing message");
    
    if( sp_done_data(ctx, dkim_signature) == -1 )
    {
	DKIMSignFree(&ctxt);
	return -1;
    } else {
	DKIMSignFree(&ctxt);
	return 0;
    }
}
示例#7
0
static int verify_data(spctx_t* ctx)
{
    char ebuf[256];
    int n;
    SPF_request_t *spf_request = NULL;
    char * xforwardaddr = NULL;
    char * xforwardhelo = NULL;
    
    if(spf_server == NULL)
    {
	/* redirect errors */
	SPF_error_handler = SPF_error_syslog; 
	SPF_warning_handler = SPF_warning_syslog; 
	SPF_info_handler = SPF_info_syslog; 
	SPF_debug_handler = SPF_debug_syslog;
      
        spf_server = SPF_server_new(SPF_DNS_CACHE, 1);
	if (spf_server == NULL) 
	    return -1;	  
    }
    
    /* trim string */
    if(ctx->xforwardaddr)
	xforwardaddr = trim_space(ctx->xforwardaddr);
    if(ctx->xforwardhelo)
	xforwardhelo = trim_space(ctx->xforwardhelo);
    
    sp_messagex(ctx, LOG_DEBUG, "New connection: ADDR %s - MAIL FROM %s - XF-ADDR %s - XF-HELO %s", 
		ctx->client.peername, ctx->sender, xforwardaddr, xforwardhelo);
    
    spf_request = SPF_request_new(spf_server);
    if( xforwardaddr )
      SPF_request_set_ipv4_str( spf_request, xforwardaddr );
    else if ( ctx->client.peername )
      SPF_request_set_ipv4_str( spf_request, ctx->client.peername );
    if( xforwardhelo )
      SPF_request_set_helo_dom( spf_request, xforwardhelo );
    if( ctx->sender )
      SPF_request_set_env_from( spf_request, ctx->sender );

    SPF_response_t *spf_response = NULL;
    SPF_request_query_mailfrom(spf_request, &spf_response);
    
    char hostname[100];
    strncpy(hostname, SPF_request_get_rec_dom(spf_request), 99);
    
    char *result_spf = NULL;
    switch(SPF_response_result(spf_response))
    {     
      case SPF_RESULT_NONE: 	
	sp_messagex(ctx, LOG_DEBUG, "No SPF policy found for %s", ctx->sender); 
	result_spf = "none";
	break;
	
      case SPF_RESULT_NEUTRAL: 
        result_spf = "neutral";
	sp_messagex(ctx, LOG_DEBUG, "SPF: NEUTRAL for %s", ctx->sender); 
	break;

      case SPF_RESULT_SOFTFAIL:
	result_spf = "softfail";
	sp_messagex(ctx, LOG_DEBUG, "SPF: SOFTFAIL for %s", ctx->sender); 
	break;
	
      case SPF_RESULT_PASS:
	result_spf = "pass";
	sp_messagex(ctx, LOG_DEBUG, "SPF: PASS for %s", ctx->sender); 
        break;
	
      case SPF_RESULT_FAIL:
	buffer_reject_message("550 SPF Reject", ebuf, sizeof(ebuf));
        buffer_reject_message(SPF_response_get_smtp_comment(spf_response), ebuf, sizeof(ebuf));
        final_reject_message(ebuf, sizeof(ebuf));
	sp_messagex(ctx, LOG_DEBUG, "SPF FAIL for %s, ignore message", ctx->sender); 

	SPF_response_free(spf_response);
	SPF_request_free(spf_request);

	if(sp_fail_data(ctx, ebuf) == -1)
            return -1;	
	else
	    return 0;
	break;
      
      case SPF_RESULT_TEMPERROR:
      case SPF_RESULT_PERMERROR:
      case SPF_RESULT_INVALID:
	buffer_reject_message("450 temporary failure", ebuf, sizeof(ebuf));
        final_reject_message(ebuf, sizeof(ebuf));
	sp_messagex(ctx, LOG_DEBUG, "TEMP ERROR or INVALID RECORD in SPF for %s", ctx->sender); 
 
	SPF_response_free(spf_response);
	SPF_request_free(spf_request);

        if(sp_fail_data(ctx, ebuf) == -1)
            return -1;	
	else
	    return 0;
	break;
    };
    char auth_result_spf[1025];
    snprintf(auth_result_spf, 1024, "spf=%s smtp.mailfrom=%s", result_spf, ctx->sender);
   
    SPF_response_free(spf_response);
    SPF_request_free(spf_request);
    
    
    
    /* Tell client to start sending data */
    if(sp_start_data (ctx) < 0)
        return -1; /* Message already printed */

    /* Setup DKIM verifier */
    DKIMContext ctxt;
    DKIMVerifyOptions vopts = {0};
    vopts.nCheckPractices = 1;
    vopts.pfnSelectorCallback = NULL; //SelectorCallback;

    n = DKIMVerifyInit( &ctxt, &vopts );

    /* Read data into verifier */
    int len = -1;
    const char *buffer = 0;
    do
    {
        len = sp_read_data(ctx, &buffer);
        if(len == -1)
            return -1;
        if(len > 0)
        {
            DKIMVerifyProcess( &ctxt, buffer, len );
	    sp_write_data( ctx, buffer, len );
        }

    } while(len > 0);
    sp_write_data( ctx, NULL, 0 );

    /* Verify DKIM */
    n = DKIMVerifyResults( &ctxt );
    
    /* Get verification details */
    int nSigCount = 0;
    DKIMVerifyDetails* pDetails;
    char szPolicy[512];

    DKIMVerifyGetDetails(&ctxt, &nSigCount, &pDetails, szPolicy );

    /* Proxy based on verification results */
    char auth_result_dkim[1025];
    if(nSigCount == 0)
    {
        sp_messagex(ctx, LOG_DEBUG, "No DKIM signature, passthrough");
	snprintf(auth_result_dkim, 1024, "dkim=none");
    }
    else if (n == DKIM_SUCCESS || n == DKIM_PARTIAL_SUCCESS)
    {
        sp_messagex(ctx, LOG_DEBUG, "DKIM verification: Success, adding header information");
	
	int strpos = 0;
	int i=0;
	for(; i<nSigCount; ++i)
	{
	    snprintf(&auth_result_dkim[strpos], 1024 - strpos, 
		     "%sdkim=%s header.d=%s", (i>0 ? ";\n" : ""),
		     (pDetails[i].nResult == DKIM_SUCCESS ? "pass" : "fail"),
		     pDetails[i].szSignatureDomain);
	    strpos = strlen(auth_result_dkim);
	}
	
    } else {
        sp_messagex(ctx, LOG_DEBUG, "DKIM verification: Failed, report error and ignore message.");

        buffer_reject_message("550 DKIM Signature failed verification (http://www.dkim.org/info/dkim-faq.html)", ebuf, sizeof(ebuf));
        final_reject_message(ebuf, sizeof(ebuf));

        DKIMVerifyFree( &ctxt );

        if(sp_fail_data(ctx, ebuf) == -1)
            return -1;
	else
	    return 0;
    }
    DKIMVerifyFree( &ctxt );

    char auth_results_header[1025];
    snprintf(auth_results_header, 1024, "Authentication-Results: %s;\n %s;\n %s;", 
	     hostname, auth_result_spf, auth_result_dkim);
    
    if( sp_done_data(ctx, auth_results_header) == -1)
        return -1;

    return 0;  
}