static int set_exif_resolution( ExifData *ed, IMAGE *im ) { double xres, yres; ExifRational xres_rational, yres_rational; ExifShort unit; /* Always save as inches - more progs support it for read. */ xres = im->Xres * 25.4; yres = im->Yres * 25.4; unit = 2; /* Wow, how dumb, fix this. */ xres_rational.numerator = xres * 100000; xres_rational.denominator = 100000; yres_rational.numerator = yres * 100000; yres_rational.denominator = 100000; if( write_tag( ed, EXIF_TAG_X_RESOLUTION, EXIF_FORMAT_RATIONAL, write_rational, &xres_rational ) || write_tag( ed, EXIF_TAG_Y_RESOLUTION, EXIF_FORMAT_RATIONAL, write_rational, &yres_rational ) || write_tag( ed, EXIF_TAG_RESOLUTION_UNIT, EXIF_FORMAT_SHORT, write_short, &unit ) ) { im_error( "im_jpeg2vips", "%s", _( "error setting JPEG resolution" ) ); return( -1 ); } return( 0 ); }
/* This is different, we set the xres/yres from the vips header rather than * from the exif tags on the image metadata. * * This is also called from the jpg reader to fix up bad exif resoltion. */ int vips__set_exif_resolution( ExifData *ed, VipsImage *im ) { double xres, yres; const char *p; int unit; VIPS_DEBUG_MSG( "vips__set_exif_resolution: vips res of %g, %g\n", im->Xres, im->Yres ); /* Default to inches, more progs support it. */ unit = 2; if( vips_image_get_typeof( im, VIPS_META_RESOLUTION_UNIT ) && !vips_image_get_string( im, VIPS_META_RESOLUTION_UNIT, &p ) ) { if( vips_isprefix( "cm", p ) ) unit = 3; else if( vips_isprefix( "none", p ) ) unit = 1; } switch( unit ) { case 1: xres = im->Xres; yres = im->Yres; break; case 2: xres = im->Xres * 25.4; yres = im->Yres * 25.4; break; case 3: xres = im->Xres * 10.0; yres = im->Yres * 10.0; break; default: vips_warn( "VipsJpeg", "%s", _( "unknown EXIF resolution unit" ) ); return( 0 ); } /* Main image xres/yres/unit are in ifd0. ifd1 has the thumbnail * xres/yres/unit. */ write_tag( ed, 0, EXIF_TAG_X_RESOLUTION, vips_exif_set_double, (void *) &xres ); write_tag( ed, 0, EXIF_TAG_Y_RESOLUTION, vips_exif_set_double, (void *) &yres ); write_tag( ed, 0, EXIF_TAG_RESOLUTION_UNIT, vips_exif_set_int, (void *) &unit ); return( 0 ); }
/* Exif also tracks image dimensions. */ static int set_exif_dimensions( ExifData *ed, VipsImage *im ) { VIPS_DEBUG_MSG( "set_exif_dimensions: vips size of %d, %d\n", im->Xsize, im->Ysize ); write_tag( ed, 2, EXIF_TAG_PIXEL_X_DIMENSION, vips_exif_set_int, (void *) &im->Xsize ); write_tag( ed, 2, EXIF_TAG_PIXEL_Y_DIMENSION, vips_exif_set_int, (void *) &im->Ysize ); return( 0 ); }
int vlogmsg(FILE* fp, const char* tag, const char* fmt, va_list ap){ pthread_mutex_lock(&mutex); write_time(fp); write_tag(fp, tag); /* centered */ int ret = vfprintf(fp, fmt, ap); pthread_mutex_unlock(&mutex); return ret; }
struct item *create_hash(struct item *payload) /*@ requires [?f0]world(?pub, ?key_clsfy) &*& [?f1]item(payload, ?pay, pub); @*/ /*@ ensures [f0]world(pub, key_clsfy) &*& [f1]item(payload, pay, pub) &*& item(result, ?hash, pub) &*& col || hash == hash_item(some(pay)); @*/ { //@ open [f1]item(payload, pay, pub); //@ open [_]item_constraints(pay, ?pay_cs, pub); //@ assert [f1]payload->content |-> ?p_cont &*& [f1]payload->size |-> ?p_size; struct item* hash = malloc(sizeof(struct item)); if (hash == 0){abort_crypto_lib("malloc of item failed");} hash->size = TAG_LENGTH + HASH_SIZE; hash->content = malloc_wrapper(hash->size); write_tag(hash->content, TAG_HASH); if (payload->size < MINIMAL_STRING_SIZE) {abort_crypto_lib("Payload of hash was to small");} sha512(payload->content, (unsigned int) payload->size, hash->content + TAG_LENGTH, 0); //@ open [f0]world(pub, key_clsfy); //@ assert hash->content |-> ?cont &*& hash->size |-> ?size; //@ public_chars(cont, TAG_LENGTH); //@ assert chars(cont, TAG_LENGTH, ?cs_tag); //@ assert cs_tag == full_tag(TAG_HASH); //@ open cryptogram(cont + TAG_LENGTH, HASH_SIZE, ?cs_cont, ?h_cg); //@ assert h_cg == cg_hash(pay_cs); //@ item h = hash_item(some(pay)); //@ close ic_cg(h)(cs_cont, h_cg); //@ list<char> cs = append(cs_tag, cs_cont); //@ if (col) public_chars(cont + TAG_LENGTH, HASH_SIZE); //@ if (col) public_generated_join(polarssl_pub(pub), cs_tag, cs_cont); //@ if (col) chars_to_secret_crypto_chars(cont + TAG_LENGTH, HASH_SIZE); //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH); //@ crypto_chars_join(cont); //@ close [f0]world(pub, key_clsfy); //@ close ic_parts(h)(cs_tag, cs_cont); //@ WELL_FORMED(cs_tag, cs_cont, TAG_HASH) //@ close well_formed_item_chars(h)(pay_cs); //@ leak well_formed_item_chars(h)(pay_cs); //@ close item_constraints(h, cs, pub); //@ leak item_constraints(h, cs, pub); //@ close item(hash, h, pub); return hash; //@ close [f1]item(payload, pay, pub); }
// reset tag to default by writing config block BOOL tag_write_default_config(BYTE tagtype, BYTE *password) { unsigned int tmp; if(!config_block_number(&tmp, tagtype)) return FALSE; // hitag2 always needs login/auth if(strlen(password) || tagtype == TAG_TYPE_HITAG2) if(!(tag_login(tmp, TmpBuff, password) || tag_auth(tmp, TmpBuff, password))) return FALSE; // emulation block for own tag type is default config block if(!config_block(TmpBuff, tagtype, tagtype)) return FALSE; return write_tag(tmp, TmpBuff, VERIFY); }
void blank_tag_rec(GapIO *io, tag_id t) /* * Blank out fields in tag record t */ { tagRecord r; (void) read_tag(io, t, &r); r.position = 0; r.length = 0; r.type.i = 0x20202020; r.comment = 0; r.next = 0; r.sense = 0; (void) write_tag(io, t,r); }
// reset tag to default and wipe all data blocks BOOL tag_write_default_blocks(BYTE tagtype, BYTE *password) { unsigned int i; switch(tagtype) { case TAG_TYPE_EM4X05: if(!tag_write_default_config(tagtype, password)) return FALSE; for(i= EM4X05_USER_DATA_BLOCK_NUM ; i < EM4X05_DATABLOCKS ; ++i) if(i != EM4X05_PW_BLOCK_NUM && !write_tag(i, EM4X05_BLANK_BLOCK, VERIFY)) return FALSE; // write default password (write only, so no verify) if(!write_tag(EM4X05_PW_BLOCK_NUM, EM4X05_PWD_DEFAULT, NO_VERIFY)) return FALSE; return TRUE; case TAG_TYPE_HITAG2: if(!tag_write_default_config(tagtype, password)) return FALSE; for(i= HITAG2_USER_DATA_BLOCK_NUM ; i < HITAG2_DATABLOCKS ; ++i) if(!write_tag(i, HITAG2_BLANK_BLOCK, VERIFY)) return FALSE; // write default password if(!write_tag(HITAG2_PW_BLOCK_NUM, HITAG2_PWD_DEFAULT, VERIFY)) return FALSE; return TRUE; case TAG_TYPE_Q5: // write config first so we can verify data block writes if(!tag_write_default_config(tagtype, "")) return FALSE; for(i= Q5_USER_DATA_BLOCK_NUM ; i < Q5_DATABLOCKS ; ++i) if(!write_tag(i, Q5_BLANK_BLOCK, VERIFY)) return FALSE; return TRUE; case TAG_TYPE_T55X7: // write config first so we can verify data block writes if(!tag_write_default_config(tagtype, "")) return FALSE; for(i= T55X7_USER_DATA_BLOCK_NUM ; i < T55X7_DATABLOCKS ; ++i) if(!write_tag(i, T55X7_BLANK_BLOCK, VERIFY)) return FALSE; return TRUE; default: return FALSE; } }
/* And orientation. */ static int set_exif_orientation( ExifData *ed, VipsImage *im ) { int orientation; /* We set the tag, even if it's been deleted, since it's a required * field. */ if( !vips_image_get_typeof( im, VIPS_META_ORIENTATION ) || vips_image_get_int( im, VIPS_META_ORIENTATION, &orientation ) ) orientation = 1; VIPS_DEBUG_MSG( "set_exif_orientation: %d\n", orientation ); write_tag( ed, 0, EXIF_TAG_ORIENTATION, vips_exif_set_int, (void *) &orientation ); return( 0 ); }
static void * vips_exif_image_field( VipsImage *image, const char *field, GValue *value, void *data ) { ExifData *ed = (ExifData *) data; const char *string; int ifd; const char *p; ExifTag tag; if( !vips_isprefix( "exif-ifd", field ) ) return( NULL ); /* value must be a string. */ if( vips_image_get_string( image, field, &string ) ) { vips_warn( "VipsJpeg", _( "bad exif meta \"%s\"" ), field ); return( NULL ); } p = field + strlen( "exif-ifd" ); ifd = atoi( p ); for( ; isdigit( *p ); p++ ) ; if( *p != '-' ) { vips_warn( "VipsJpeg", _( "bad exif meta \"%s\"" ), field ); return( NULL ); } if( !(tag = exif_tag_from_name( p + 1 )) ) { vips_warn( "VipsJpeg", _( "bad exif meta \"%s\"" ), field ); return( NULL ); } write_tag( ed, ifd, tag, vips_exif_set_entry, (void *) string ); return( NULL ); }
void exit_save( GtkWidget *widget, GtkWidget *data) { char tmp[31]; if (mp3.file) { if(!read_only) { strcpy(mp3.id3.title,gtk_entry_get_text(GTK_ENTRY(id3win_text_title))); strcpy(mp3.id3.artist,gtk_entry_get_text(GTK_ENTRY(id3win_text_artist))); strcpy(mp3.id3.album,gtk_entry_get_text(GTK_ENTRY(id3win_text_album))); strcpy(mp3.id3.year,gtk_entry_get_text(GTK_ENTRY(id3win_text_year))); strcpy(mp3.id3.comment,gtk_entry_get_text(GTK_ENTRY(id3win_text_comment))); strcpy(tmp,gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(id3win_combo_genre)->entry))); mp3.id3.genre[0]=gget_genre(tmp); strcpy(tmp,gtk_entry_get_text(GTK_ENTRY(id3win_text_track))); mp3.id3.track[0]=atoi(tmp); /* if (mp3.id3.track[0] > 255) mp3.id3.track[0]=255; */ write_tag(&mp3); } fclose(mp3.file); } gtk_main_quit(); }
void delete_tag_rec(GapIO *io, tag_id t) /* * remove t from file, discarding comment if necessary */ { tag_id head; tagRecord freerec; /* * reclaim comment */ freerec.comment = 0; /* just in case read_tag fails */ (void) read_tag(io, t,&freerec); if (freerec.comment) { deallocate(io, freerec.comment); freerec.comment = 0; } (void) io_read_free_annotation(io,&head); freerec.next = head; (void) write_tag(io, t,freerec); head = t; (void) io_write_free_annotation(io,&head); }
ErrorCode WriteVtk::write_tags(std::ostream& stream, bool nodes, const Range& entities, const Tag* tag_list, int num_tags) { ErrorCode rval; // The #$%@#$% MOAB interface does not have a function to retrieve // all entities with a tag, only all entities with a specified type // and tag. Define types to loop over depending on the if vertex // or element tag data is being written. It seems horribly inefficient // to have the implementation subdivide the results by type and have // to call that function once for each type just to recombine the results. // Unfortunately, there doesn't seem to be any other way. EntityType low_type, high_type; if (nodes) { low_type = MBVERTEX; high_type = MBEDGE; } else { low_type = MBEDGE; high_type = MBENTITYSET; } // Get all defined tags std::vector<Tag> tags; std::vector<Tag>::iterator i; rval = writeTool->get_tag_list(tags, tag_list, num_tags, false); if (MB_SUCCESS != rval) return rval; // For each tag... bool entities_have_tags = false; for (i = tags.begin(); i != tags.end(); ++i) { // Skip tags holding entity handles -- no way to save them DataType dtype; rval = mbImpl->tag_get_data_type(*i, dtype); if (MB_SUCCESS != rval) return rval; if (dtype == MB_TYPE_HANDLE) continue; // If in strict mode, don't write tags that do not fit in any // attribute type (SCALAR : 1 to 4 values, VECTOR : 3 values, TENSOR : 9 values) if (mStrict) { int count; rval = mbImpl->tag_get_length(*i, count); if (MB_SUCCESS != rval) return rval; if (count < 1 || (count > 4 && count != 9)) continue; } // Get subset of input entities that have the tag set Range tagged; for (EntityType type = low_type; type < high_type; ++type) { Range tmp_tagged; rval = mbImpl->get_entities_by_type_and_tag(0, type, &(*i), 0, 1, tmp_tagged); if (MB_SUCCESS != rval) return rval; tmp_tagged = intersect(tmp_tagged, entities); tagged.merge(tmp_tagged); } // If any entities were tagged if (!tagged.empty()) { // If this is the first tag being written for the // entity type, write the label marking the beginning // of the tag data. if (!entities_have_tags) { entities_have_tags = true; stream << (nodes ? "POINT_DATA " : "CELL_DATA ") << entities.size() << std::endl; } // Write the tag rval = write_tag(stream, *i, entities, tagged); if (MB_SUCCESS != rval) return rval; } } return MB_SUCCESS; }
BOOL vtag_write_to_tag(BYTE *pass) { unsigned int block, config_block_no; BYTE tmp[MAXBLOCKSIZE + 1]; BOOL auth= FALSE; StoredConfig tmptag; // preserve tag type memcpy(&tmptag, &RFIDlerConfig, sizeof(RFIDlerConfig)); // set real tag to vtag type if not already the same if(RFIDlerConfig.TagType != RFIDlerVTag.TagType) if(!tag_set(RFIDlerVTag.TagType)) { memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return FALSE; } // reset target tag, but don't care if we get UID as it may not be in a valid mode get_tag_uid(tmp); // re-auth if(!tag_login(block, tmp, pass)) tag_auth(block, tmp, pass); // initialise target in default mode // get config block number if(!config_block_number(&config_block_no, RFIDlerConfig.TagType)) return FALSE; // get default config block data tmp[HEXDIGITS(RFIDlerVTag.BlockSize)]= '\0'; if (!config_block(tmp, RFIDlerConfig.TagType, RFIDlerConfig.TagType)) { memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return FALSE; } // write default config if(!write_tag(config_block_no, tmp, VERIFY)) { memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return FALSE; } // reset tag again get_tag_uid(tmp); // write all VTAG blocks with valid data in them // but avoid writing config block until last as tag may stop responding tmp[HEXDIGITS(RFIDlerVTag.BlockSize)]= '\0'; for(block= 0 ; block < RFIDlerVTag.DataBlocks ; ++block) if(block != config_block_no && RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * block)]) { // try to login/auth in case target tag requires it // don't care if we fail if(!(auth= tag_login(block, tmp, pass))) auth= tag_auth(block, tmp, pass); memcpy(tmp, &RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * block)], HEXDIGITS(RFIDlerVTag.BlockSize)); UserMessageNum("\r\n%d: ", block); UserMessage("%s", tmp); // failure allowed as we may be trying to write locked blocks if(!write_tag(block, tmp, VERIFY)) { UserMessage("%s", " Failed!"); if(!auth) UserMessage("%s", " (Auth/Login)"); } } // write config block (no verify as some tags stop talking after config change) if(!tag_login(block, tmp, pass)) tag_auth(block, tmp, pass); tmp[HEXDIGITS(RFIDlerVTag.BlockSize)]= '\0'; memcpy(tmp, &RFIDlerVTag.Data[HEXDIGITS(RFIDlerVTag.BlockSize * config_block_no)], HEXDIGITS(RFIDlerVTag.BlockSize)); UserMessageNum("\r\n\r\n%d: ", config_block_no); UserMessage("%s", tmp); if(!write_tag(config_block_no, tmp, NO_VERIFY)) { memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return FALSE; } memcpy(&RFIDlerConfig, &tmptag, sizeof(RFIDlerConfig)); return TRUE; }
bool LevellerDataset::write_header() { char szHeader[5]; strcpy(szHeader, "trrn"); szHeader[4] = 7; // TER v7 introduced w/ Lev 2.6. if(1 != VSIFWriteL(szHeader, 5, 1, m_fp) || !this->write_tag("hf_w", (size_t)nRasterXSize) || !this->write_tag("hf_b", (size_t)nRasterYSize)) { CPLError( CE_Failure, CPLE_FileIO, "Could not write header" ); return false; } m_dElevBase = 0.0; m_dElevScale = 1.0; if(m_pszProjection == NULL || m_pszProjection[0] == 0) { write_tag("csclass", LEV_COORDSYS_RASTER); } else { write_tag("coordsys_wkt", m_pszProjection); const UNITLABEL units_elev = this->id_to_code(m_szElevUnits); const int bHasECS = (units_elev != UNITLABEL_PIXEL && units_elev != UNITLABEL_UNKNOWN); write_tag("coordsys_haselevm", bHasECS); OGRSpatialReference sr(m_pszProjection); if(bHasECS) { if(!this->compute_elev_scaling(sr)) return false; // Raw-to-real units scaling. write_tag("coordsys_em_scale", m_dElevScale); // Elev offset, in real units. write_tag("coordsys_em_base", m_dElevBase); write_tag("coordsys_em_units", units_elev); } if(sr.IsLocal()) { write_tag("csclass", LEV_COORDSYS_LOCAL); const double dfLinear = sr.GetLinearUnits(); const int n = this->meter_measure_to_code(dfLinear); write_tag("coordsys_units", n); } else { write_tag("csclass", LEV_COORDSYS_GEO); } if( m_adfTransform[2] != 0.0 || m_adfTransform[4] != 0.0) { CPLError( CE_Failure, CPLE_IllegalArg, "Cannot handle rotated geotransform" ); return false; } // todo: GDAL gridpost spacing is based on extent / rastersize // instead of extent / (rastersize-1) like Leveller. // We need to look into this and adjust accordingly. // Write north-south digital axis. write_tag("coordsys_da0_style", LEV_DA_PIXEL_SIZED); write_tag("coordsys_da0_fixedend", 0); write_tag("coordsys_da0_v0", m_adfTransform[3]); write_tag("coordsys_da0_v1", m_adfTransform[5]); // Write east-west digital axis. write_tag("coordsys_da1_style", LEV_DA_PIXEL_SIZED); write_tag("coordsys_da1_fixedend", 0); write_tag("coordsys_da1_v0", m_adfTransform[0]); write_tag("coordsys_da1_v1", m_adfTransform[1]); } this->write_tag_start("hf_data", sizeof(float) * nRasterXSize * nRasterYSize); return true; }
struct item *asymmetric_encryption(struct item *key, struct item *payload) /*@ requires [?f]world(?pub, ?key_clsfy) &*& principal(?principal1, ?count1) &*& item(payload, ?pay, pub) &*& item(key, ?k, pub) &*& k == public_key_item(?principal2, ?count2); @*/ /*@ ensures [f]world(pub, key_clsfy) &*& principal(principal1, count1 + 1) &*& item(payload, pay, pub) &*& item(key, k, pub) &*& item(result, ?enc, pub) &*& col ? true : enc == asymmetric_encrypted_item(principal2, count2, some(pay), ?ent); @*/ { debug_print("ASYM ENCRYPTING:\n"); print_item(payload); struct item* result; result = malloc(sizeof(struct item)); if (result == 0) abort_crypto_lib("Malloc failed"); { pk_context context; unsigned int olen; char output[MAX_PACKAGE_SIZE]; // Key //@ close pk_context(&context); //@ open [f]world(pub, key_clsfy); pk_init(&context); //@ close [f]world(pub, key_clsfy); set_public_key(&context, key); //@ open [f]world(pub, key_clsfy); /*@ assert pk_context_with_key(&context, pk_public, ?principal, ?count, RSA_BIT_KEY_SIZE); @*/ //@ assert col || principal == principal2; //@ assert col || count == count2; // Encryption //@ open item(payload, pay, pub); //@ assert [_]item_constraints(pay, ?pay_cs, pub); if (payload->size > RSA_KEY_SIZE) abort_crypto_lib("Asymmetric encryption failed: incorrect sizes"); void *random_state = nonces_expose_state(); //@ close random_state_predicate(havege_state_initialized); /*@ produce_function_pointer_chunk random_function( asym_enc_havege_random_stub) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ open principal(principal1, count1); if(pk_encrypt(&context, payload->content, (unsigned int) payload->size, output, &olen, MAX_PACKAGE_SIZE, asym_enc_havege_random_stub, random_state) != 0) abort_crypto_lib("Encryption failed"); //@ close principal(principal1, count1 + 1); //@ open cryptogram(output, ?enc_length, ?enc_cs, ?enc_cg); //@ assert enc_cg == cg_asym_encrypted(principal, count, pay_cs, ?ent); //@ assert u_integer(&olen, enc_length); //@ assert enc_length > 0 &*& enc_length < MAX_PACKAGE_SIZE; //@ assert enc_length > 0 &*& enc_length <= RSA_SERIALIZED_KEY_SIZE; nonces_hide_state(random_state); //@ pk_release_context_with_key(&context); pk_free(&context); //@ open pk_context(&context); //@ close [f]world(pub, key_clsfy); // Create item result->size = TAG_LENGTH + (int) olen; result->content = malloc(result->size); if (result->content == 0) {abort_crypto_lib("Malloc failed");} write_tag(result->content, TAG_ASYMMETRIC_ENC); //@ assert result->content |-> ?cont &*& result->size |-> ?size; if (olen < MINIMAL_STRING_SIZE) {abort_crypto_lib("Asymmetric encryption failed: to small");} memcpy(result->content + TAG_LENGTH, output, olen); //@ assert chars(cont, TAG_LENGTH, ?cs_tag); //@ public_chars(cont, TAG_LENGTH); //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH); //@ assert cs_tag == full_tag(TAG_ASYMMETRIC_ENC); //@ crypto_chars_join(cont); //@ item enc = asymmetric_encrypted_item(principal, count, some(pay), ent); //@ list<char> cs = append(cs_tag, enc_cs); //@ WELL_FORMED(cs_tag, enc_cs, TAG_ASYMMETRIC_ENC) //@ close ic_parts(enc)(cs_tag, enc_cs); //@ close ic_cg(enc)(enc_cs, enc_cg); /*@ if (col) { crypto_chars_to_chars(cont, size); public_chars(cont, size); chars_to_secret_crypto_chars(cont, size); public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH); } @*/ //@ well_formed_item_constraints(pay, enc); //@ close item_constraints(enc, cs, pub); //@ leak item_constraints(enc, cs, pub); //@ close item(result, enc, pub); zeroize(output, (int) olen); //@ chars_join(output); //@ close item(payload, pay, pub); } debug_print("ENCRYPTING RESULT:\n"); print_item(result); return result; }
struct item *asymmetric_signature(struct item *key, struct item *payload) /*@ requires [?f]world(?pub, ?key_clsfy) &*& principal(?principal1, ?count1) &*& item(payload, ?pay, pub) &*& item(key, ?k, pub) &*& k == private_key_item(?principal2, ?count2); @*/ /*@ ensures [f]world(pub, key_clsfy) &*& principal(principal1, count1 + 1) &*& item(payload, pay, pub) &*& item(key, k, pub) &*& item(result, ?sig, pub) &*& col ? true : sig == asymmetric_signature_item(principal2, count2, some(pay), ?ent); @*/ { debug_print("ASYM SIGNING:\n"); print_item(payload); struct item* result; result = malloc(sizeof(struct item)); if (result == 0) abort_crypto_lib("Malloc failed"); debug_print("signing item\n"); print_item(payload); print_item(key); { pk_context context; unsigned int olen; char* output; // Key //@ close pk_context(&context); //@ open [f]world(pub, key_clsfy); pk_init(&context); //@ close [f]world(pub, key_clsfy); set_private_key(&context, key); //@ open [f]world(pub, key_clsfy); /*@ assert pk_context_with_key(&context, pk_private, ?principal, ?count, RSA_BIT_KEY_SIZE); @*/ //@ assert col || principal == principal2; //@ assert col || count == count2; // Payload //@ open item(payload, pay, pub); //@ open [_]item_constraints(pay, ?pay_cs, pub); //@ assert payload->content |-> ?p_cont &*& payload->size |-> ?p_size; if (payload->size > RSA_KEY_SIZE) abort_crypto_lib("Assymetric signing failed: incorrect size"); output = malloc(RSA_KEY_SIZE); if (output == 0) abort_crypto_lib("Malloc failed"); void *random_state = nonces_expose_state(); //@ close random_state_predicate(havege_state_initialized); /*@ produce_function_pointer_chunk random_function( asym_sig_havege_random_stub) (havege_state_initialized)(state, out, len) { call(); } @*/ //@ open principal(principal1, count1); if(pk_sign(&context, POLARSSL_MD_NONE, payload->content, (unsigned int) payload->size, output, &olen, asym_sig_havege_random_stub, random_state) != 0) abort_crypto_lib("Signing failed"); //@ open principal(principal1, count1 + 1); //@ open cryptogram(output, ?sig_length, ?sig_cs, ?sig_cg); //@ assert sig_cg == cg_asym_signature(principal, count, pay_cs, ?ent); //@ assert u_integer(&olen, sig_length); //@ assert sig_length > 0 &*& sig_length <= RSA_KEY_SIZE; nonces_hide_state(random_state); //@ pk_release_context_with_key(&context); pk_free(&context); //@ open pk_context(&context); //@ close [f]world(pub, key_clsfy); debug_print("signed item\n"); print_buffer(output, (int) olen); // Create item if (olen < MINIMAL_STRING_SIZE) abort_crypto_lib("Assymetric signing failed: output to small"); result->size = TAG_LENGTH + (int) olen; result->content = malloc(result->size); if (result->content == 0) {abort_crypto_lib("Malloc failed");} write_tag(result->content, TAG_ASYMMETRIC_SIG); //@ assert result->content |-> ?cont &*& result->size |-> ?size; //@ assert chars(cont, TAG_LENGTH, ?tag_cs); //@ assert tag_cs == full_tag(TAG_ASYMMETRIC_SIG); //@ public_chars(cont, TAG_LENGTH); //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH); memcpy(result->content + TAG_LENGTH, output, olen); //@ crypto_chars_join(cont); //@ list<char> cs = append(tag_cs, sig_cs); //@ assert crypto_chars(secret, cont, size, cs); //@ item e = asymmetric_signature_item(principal, count, some(pay), ent); //@ close ic_cg(e)(sig_cs, sig_cg); /*@ if (col) { public_chars(cont, size); public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH); } @*/ //@ close item(payload, pay, pub); zeroize(output, (int) olen); //@ chars_join(output); free(output); //@ WELL_FORMED(tag_cs, sig_cs, TAG_ASYMMETRIC_SIG) //@ close ic_parts(e)(tag_cs, sig_cs); //@ close well_formed_item_chars(e)(pay_cs); //@ leak well_formed_item_chars(e)(pay_cs); //@ close item_constraints(e, cs, pub); //@ leak item_constraints(e, cs, pub); //@ close item(result, e, pub); } debug_print("SINGING RESULT:\n"); print_item(result); return result; }
struct item *symmetric_encryption(struct item *key, struct item *payload) /*@ requires [?f]world(?pub, ?key_clsfy) &*& principal(?principal1, ?count1) &*& [_]pub(nonce_item(principal1, count1 + 1, 0)) &*& item(payload, ?pay, pub) &*& item(key, ?k, pub) &*& k == symmetric_key_item(?principal2, ?count2); @*/ /*@ ensures [f]world(pub, key_clsfy) &*& principal(principal1, count1 + 2) &*& item(payload, pay, pub) &*& item(key, k, pub) &*& item(result, ?enc, pub) &*& col ? true : enc == symmetric_encrypted_item(principal2, count2, some(pay), ?ent); @*/ { //@ open [f]world(pub, key_clsfy); debug_print("ENCRYPTING:\n"); print_item(payload); struct item* result; result = malloc(sizeof(struct item)); if (result == 0) abort_crypto_lib("Malloc failed"); { gcm_context gcm_context; char iv_buffer[GCM_IV_SIZE]; char *iv; char *result_cs; char *encrypted; //@ open item(key, k, pub); //@ assert key->content |-> ?k_cont &*& key->size |-> ?k_size; check_valid_symmetric_key_item_size(key->size); //@ open [_]item_constraints(k, ?k_cs0, pub); //@ assert [_]ic_parts(k)(?k_tag, ?k_cs); //@ crypto_chars_limits(k_cont); //@ crypto_chars_split(k_cont, TAG_LENGTH); //@ WELL_FORMED(k_tag, k_cs, TAG_SYMMETRIC_KEY) //@ assert crypto_chars(secret, k_cont, TAG_LENGTH, k_tag); //@ assert crypto_chars(secret, k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs); //@ cryptogram k_cg = cg_symmetric_key(principal2, count2); //@ if (col) k_cg = chars_for_cg_sur(k_cs, tag_symmetric_key); //@ if (col) crypto_chars_to_chars(k_cont + TAG_LENGTH, GCM_KEY_SIZE); //@ if (col) public_chars_extract(k_cont + TAG_LENGTH, k_cg); //@ if (col) chars_to_secret_crypto_chars(k_cont + TAG_LENGTH, GCM_KEY_SIZE); //@ close cryptogram(k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs, k_cg); //@ close gcm_context(&gcm_context); if (gcm_init(&gcm_context, POLARSSL_CIPHER_ID_AES, (key->content + TAG_LENGTH), (unsigned int) GCM_KEY_SIZE * 8) != 0) abort_crypto_lib("Init gcm failed"); //@ assert gcm_context_initialized(&gcm_context, ?p, ?c); //@ assert col || (p == principal2 && c == count2); //@ open cryptogram(k_cont + TAG_LENGTH, GCM_KEY_SIZE, k_cs, k_cg); //@ crypto_chars_join(k_cont); //@ close item(key, k, pub); //@ open item(payload, pay, pub); //@ open [_]item_constraints(pay, ?pay_cs, pub); //@ assert payload->content |-> ?p_cont &*& payload->size |-> ?p_size; //@ crypto_chars_limits(p_cont); if (payload->size >= INT_MAX - TAG_LENGTH - GCM_IV_SIZE - GCM_MAC_SIZE || payload->size < MINIMAL_STRING_SIZE) abort_crypto_lib("Gcm encryption failed: incorrect sizes"); result->size = TAG_LENGTH + GCM_IV_SIZE + GCM_MAC_SIZE + payload->size; result->content = malloc(result->size); //@ assert result->content |-> ?r_cont &*& result->size |-> ?r_size; if (result->content == 0) abort_crypto_lib("Malloc failed"); //@ chars_split(r_cont, TAG_LENGTH); write_tag(result->content, TAG_SYMMETRIC_ENC); //@ assert chars(r_cont, TAG_LENGTH, ?tag_cs); //@ public_chars(r_cont, TAG_LENGTH); //@ assert tag_cs == full_tag(TAG_SYMMETRIC_ENC); //@ assert chars(r_cont + TAG_LENGTH, GCM_IV_SIZE + p_size, _); //@ chars_split(r_cont + TAG_LENGTH, GCM_IV_SIZE); iv = result->content + TAG_LENGTH; //@ close nonce_request(principal1, 0); //@ close [f]world(pub, key_clsfy); create_havege_random(iv, GCM_IV_SIZE); //@ open cryptogram(iv, GCM_IV_SIZE, ?iv_cs, ?iv_cg); memcpy(iv_buffer, iv, GCM_IV_SIZE); //@ close cryptogram(iv, GCM_IV_SIZE, iv_cs, iv_cg); //@ close polarssl_pub(pub)(iv_cg); //@ leak polarssl_pub(pub)(iv_cg); //@ public_cryptogram(iv, iv_cg); //@ public_chars(iv, GCM_IV_SIZE); encrypted = iv + GCM_IV_SIZE; //@ chars_split(encrypted, GCM_MAC_SIZE); //@ open principal(principal1, count1 + 1); if (gcm_crypt_and_tag(&gcm_context, GCM_ENCRYPT, (unsigned int) payload->size, iv_buffer, GCM_IV_SIZE, NULL, 0, payload->content, encrypted + GCM_MAC_SIZE, GCM_MAC_SIZE, encrypted) != 0) abort_crypto_lib("Gcm encryption failed"); //@ close principal(principal1, count1 + 2); zeroize(iv_buffer, GCM_IV_SIZE); //@ assert crypto_chars(secret, encrypted, GCM_MAC_SIZE, ?mac_cs); //@ assert crypto_chars(secret, encrypted + GCM_MAC_SIZE, p_size, ?enc_cs); //@ crypto_chars_join(encrypted); //@ assert exists(?enc_cg); //@ list<char> cg_cs = append(mac_cs, enc_cs); //@ assert cg_cs == chars_for_cg(enc_cg); //@ list<char> cont_cs = append(iv_cs, cg_cs); //@ take_append(GCM_IV_SIZE, iv_cs, cg_cs); //@ drop_append(GCM_IV_SIZE, iv_cs, cg_cs); //@ list<char> cs = append(tag_cs, cont_cs); //@ take_append(TAG_LENGTH, tag_cs, cont_cs); //@ drop_append(TAG_LENGTH, tag_cs, cont_cs); //@ item enc; //@ list<char> ent = append(iv_cs, iv_cs); //@ take_append(GCM_IV_SIZE, iv_cs, iv_cs); //@ drop_append(GCM_IV_SIZE, iv_cs, iv_cs); /*@ if (col) { enc_cg = chars_for_cg_sur(cg_cs, tag_auth_encrypted); assert enc_cg == cg_auth_encrypted(?p0, ?c0, ?pay0, ?iv0); ent = append(iv_cs, iv0); take_append(GCM_IV_SIZE, iv_cs, iv0); drop_append(GCM_IV_SIZE, iv_cs, iv0); enc = symmetric_encrypted_item(p0, c0, some(pay), ent); public_chars(encrypted, GCM_MAC_SIZE + p_size); assert chars(encrypted, GCM_MAC_SIZE + p_size, cg_cs); chars_join(iv); chars_join(r_cont); assert chars(r_cont, r_size, cs); public_chars(r_cont, r_size); public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH); close ic_sym_enc(enc)(iv0, cg_cs); } else { assert enc_cg == cg_auth_encrypted(principal2, count2, pay_cs, iv_cs); enc = symmetric_encrypted_item(principal2, count2, some(pay), ent); close polarssl_pub(pub)(cg_nonce(principal1, count1 + 1)); leak polarssl_pub(pub)(cg_nonce(principal1, count1 + 1)); public_generated(polarssl_pub(pub), cg_nonce(principal1, count1 + 1)); chars_to_secret_crypto_chars(iv, GCM_IV_SIZE); crypto_chars_join(iv); chars_to_secret_crypto_chars(r_cont, TAG_LENGTH); crypto_chars_join(r_cont); assert crypto_chars(secret, r_cont, r_size, cs); close ic_sym_enc(enc)(iv_cs, cg_cs); } @*/ //@ well_formed_item_constraints(pay, enc); //@ close ic_cg(enc)(cg_cs, enc_cg); //@ close ic_parts(enc)(tag_cs, cont_cs); //@ WELL_FORMED(tag_cs, cont_cs, TAG_SYMMETRIC_ENC) //@ close item_constraints(enc, cs, pub); //@ leak item_constraints(enc, cs, pub); //@ close item(result, enc, pub); //@ close item(payload, pay, pub); gcm_free(&gcm_context); //@ open gcm_context(&gcm_context); } debug_print("ENCRYPTING RESULT:\n"); print_item(result); return result; }
void insert_new_tag2(GapIO *io, int into, int *cache, int cache_len, int *cache_pos, int pos, int length, char *type, char *comment, int sense) { tag_id prev, next, newt; tagRecord prev_tag, next_tag, new_tag; int i; /* Initialise cache if required */ if (pos >= *cache_pos) { next = cache[*cache_pos]; if (!next) next = first_tag(io, into); while (next) { read_tag(io, next, &next_tag); if (next_tag.position < *cache_pos) { next = next_tag.next; continue; } if (next_tag.position > pos) break; for (i = *cache_pos; i < next_tag.position; i++) cache[i] = cache[*cache_pos]; for (; i <= next_tag.position; i++) { cache[i] = next; } *cache_pos = i-1; next = next_tag.next; } for (i = *cache_pos+1; i <= pos; i++) cache[i] = cache[*cache_pos]; *cache_pos = pos; } /* Find previous and next tags - quick lookup in cache */ prev = cache[pos]; if (!prev) { next = first_tag(io, into); } else { read_tag(io, prev, &prev_tag); next = prev_tag.next; } /* Create and initialise new tag */ newt = get_free_tag(io); new_tag.position = pos; new_tag.length = length; strncpy(new_tag.type.c,type,4); if (comment!=NULL) new_tag.comment = put_comment(io, comment); else new_tag.comment = 0; new_tag.next = next; new_tag.sense = sense; write_tag(io, newt, new_tag); /* Update cache */ i = pos; while (i <= *cache_pos && cache[i] == prev) cache[i++] = newt; if (pos > *cache_pos) { int j, k = cache[*cache_pos]; for (j = *cache_pos; j < pos; j++) cache[j] = k; cache[pos] = newt; *cache_pos = pos; } /* Link previous tag */ if (prev) { prev_tag.next = newt; write_tag(io, prev, prev_tag); } else { update_tag(io, into, newt); } }
struct item *create_pair(struct item *first, struct item *second) /*@ requires [?f0]world(?pub, ?key_clsfy) &*& [?f1]item(first, ?f, pub) &*& [?f2]item(second, ?s, pub); @*/ /*@ ensures [f0]world(pub, key_clsfy) &*& [f1]item(first, f, pub) &*& [f2]item(second, s, pub) &*& item(result, pair_item(f, s), pub); @*/ { //@ open [f0]world(pub, key_clsfy); struct item* pair = malloc(sizeof(struct item)); if (pair == 0){abort_crypto_lib("malloc of item failed");} //@ open [f1]item(first, f, pub); //@ assert [f1]first->content |-> ?cont_f &*& [f1]first->size |-> ?size_f; //@ assert [f1]crypto_chars(secret, cont_f, size_f, ?cs_f); //@ assert [_]item_constraints(f, cs_f, pub); //@ well_formed_item_constraints(f, f); //@ open [_]well_formed_item_chars(f)(cs_f); //@ open [f2]item(second, s, pub); //@ assert [f2]second->content |-> ?cont_s &*& [f2]second->size |-> ?size_s; //@ assert [f2]crypto_chars(secret, cont_s, size_s, ?cs_s); //@ well_formed_item_constraints(s, s); //@ open [_]well_formed_item_chars(s)(cs_s); //@ assert [_]item_constraints(s, cs_s, pub); if (INT_MAX - TAG_LENGTH - (int) sizeof(int) - first->size < second->size) abort_crypto_lib("Requested pair item was to big"); pair->size = TAG_LENGTH + (int) sizeof(int) + first->size + second->size; pair->content = malloc_wrapper(pair->size); //@ assert pair->content |-> ?cont &*& pair->size |-> ?size; write_tag(pair->content, TAG_PAIR); { //@ assert chars(cont, TAG_LENGTH, full_tag(TAG_PAIR)); //@ public_chars(cont, TAG_LENGTH); //@ chars_to_secret_crypto_chars(cont, TAG_LENGTH); char* temp = pair->content + TAG_LENGTH; //@ chars_split(cont + TAG_LENGTH, sizeof(int)); //@ assert [f1]integer(&first->size, ?flen); //@ integer_to_chars(&first->size); //@ open chars((void*) &first->size, sizeof(int), chars_of_int(flen)); //@ character_limits((void*) &first->size); //@ close [f1]chars((void*) &first->size, sizeof(int), chars_of_int(flen)); //@ public_chars((void*) &first->size, sizeof(int)); //@ public_chars((void*) &first->size, sizeof(int)); //@ chars_to_crypto_chars((void*) &first->size, sizeof(int)); write_buffer(&temp, (void*) &(first->size), (int) sizeof(int)); //@ crypto_chars_to_chars((void*) &first->size, sizeof(int)); //@ chars_to_secret_crypto_chars(temp - sizeof(int), sizeof(int)); //@ chars_to_integer(&first->size); //@ chars_split(cont + TAG_LENGTH + sizeof(int), first->size); write_buffer(&temp, first->content, first->size); write_buffer(&temp, second->content, second->size); //@ crypto_chars_join(cont + TAG_LENGTH + sizeof(int)); //@ crypto_chars_join(cont + TAG_LENGTH); //@ crypto_chars_join(cont); } //@ list<char> size_f_cs = chars_of_int(size_f); //@ list<char> cs0 = append(size_f_cs, append(cs_f, cs_s)); //@ list<char> cs = append(full_tag(TAG_PAIR), cs0); //@ take_append(TAG_LENGTH, full_tag(TAG_PAIR), cs0); //@ drop_append(TAG_LENGTH, full_tag(TAG_PAIR), cs0); //@ assert length(size_f_cs) == sizeof(int); //@ take_append(sizeof(int), size_f_cs, append(cs_f, cs_s)); //@ drop_append(sizeof(int), size_f_cs, append(cs_f, cs_s)); //@ take_append(size_f, cs_f, cs_s); //@ drop_append(size_f, cs_f, cs_s); //@ assert drop(sizeof(int), cs0) == append(cs_f, cs_s); //@ assert size_f_cs == chars_of_unbounded_int(length(cs_f)); //@ append_assoc(size_f_cs, cs_f, cs_s); //@ assert crypto_chars(secret, cont, size, cs); //@ item p = pair_item(f, s); //@ close ic_pair(p)(cs_f, cs_s); //@ length_equals_nat_length(cs); //@ length_equals_nat_length(cs0); //@ drop_drop(sizeof(int), TAG_LENGTH, cs); //@ head_append(full_tag(TAG_PAIR), cs0); /*@ switch(nat_length(cs)) { case succ(n): well_formed_upper_bound(cs_f, nat_length(cs_f), n); well_formed_upper_bound(cs_s, nat_length(cs_s), n); case zero: assert false; } @*/ /*@ if(col) { public_chars(cont, size); public_generated_split(polarssl_pub(pub), cs, TAG_LENGTH); } @*/ //@ close ic_parts(p)(full_tag(TAG_PAIR), cs0); //@ close item_constraints(p, cs, pub); //@ leak item_constraints(p, cs, pub); //@ close item(pair, p, pub); //@ close [f1]item(first, f, pub); //@ close [f2]item(second, s, pub); return pair; //@ close [f0]world(pub, key_clsfy); }
int main(int argc, char *argv[]) { FILE *fp; int c, i, interactive = 0, view_only=1,delete_tag=0,file_open,retcode=0; int want_id3=1,scantype=SCAN_NONE,fullscan_vbr=0; int show_techinfo=0,force_mode=0,quickscan=1; int new_track=0,new_genre=0,firstfilearg; id3tag new_tag; char *print_format=NULL; char error_msg[256]; unsigned int g,n; int vbr_report=VBR_VARIABLE; mp3info mp3; new_tag.title[0]=new_tag.artist[0]=new_tag.album[0]=new_tag.year[0]= new_tag.comment[0]=new_tag.track[0]=new_tag.genre[0]=1; /* use something REALLY unlikely... -- so we could clear the tag... */ if (argc < 2 ) /* Only command is given. Short help */ { printf("%s %s\n"\ "\n MP3Info comes with ABSOLUTELY NO WARRANTY. This is free software, and\n"\ " you are welcome to redistribute it under certain conditions.\n"\ " See the file 'LICENSE' for more information.\n"\ "\nUse 'mp3info -h' for a usage summary or see the mp3info man page for a\n"\ "complete description.\n",VERSION,COPYRIGHT); return 0; } while ((c=getopt(argc,argv,"vhGidfxFt:a:l:y:c:n:g:p:r:"))!=-1) { switch(c) { case 'v': /* View mode is now automatic when no changes are made to the ID3 tag. This switch is accepted only for backward compatibility */ break; case 'h': display_help(); return 0; break; case 'G': display_genres(alphagenreindex,typegenre); return 0; break; case 'i': view_only=0; interactive = 1; break; case 'd': view_only=0; delete_tag=1; break; case 'p': print_format=optarg; translate_escapes(print_format); want_id3=0; break; case 'f': force_mode=1; break; case 'x': show_techinfo=1; break; case 't': strncpy(new_tag.title,optarg,TEXT_FIELD_LEN); view_only=0; break; case 'a': strncpy(new_tag.artist,optarg,TEXT_FIELD_LEN); view_only=0; break; case 'l': strncpy(new_tag.album,optarg,TEXT_FIELD_LEN); view_only=0; break; case 'y': strncpy(new_tag.year,optarg,INT_FIELD_LEN); view_only=0; break; case 'c': strncpy(new_tag.comment,optarg,TEXT_FIELD_LEN); view_only=0; break; case 'n': n=atoi(optarg); if(n <= 255) { new_tag.track[0] = (unsigned char) n; new_track=1; view_only=0; } else { fprintf(stderr,"Error: '%s' is not a valid track number.\n",optarg); fprintf(stderr,"Valid track numbers are integers from 0 to 255.\n"); fprintf(stderr,"Use a value of '0' to remove the track number field\n"); retcode |= 6; return retcode; } break; case 'g': g=get_genre(optarg); if(g <= 255) { new_tag.genre[0] = (unsigned char) g; new_genre=1; view_only=0; } else { fprintf(stderr,"Error: '%s' is not a recognized genre name or number.\n",optarg); fprintf(stderr,"Use the '-G' option to see a list of valid genre names and numbers\n"); retcode |= 6; return retcode; } sscanf(optarg,"%u",&g); break; case 'r': switch(optarg[0]) { case 'a': vbr_report=VBR_AVERAGE; break; case 'm': vbr_report=VBR_MEDIAN; break; case 'v': vbr_report=VBR_VARIABLE; break; default: fprintf(stderr,"Error: %s is not a valid option to the VBR reporting switch (-r)\n",optarg); fprintf(stderr,"Valid options are 'a', 'm' and 'v'. Run '%s -h' for more info.\n",argv[0]); retcode |= 6; return retcode; } break; case 'F': quickscan=0; break; } } if(!view_only) scantype=SCAN_QUICK; if(print_format) { determine_tasks(print_format,&want_id3,&scantype,&fullscan_vbr,vbr_report); } else if(view_only) { determine_tasks(ID3_FORMAT_STRING,&want_id3,&scantype,&fullscan_vbr,vbr_report); if(show_techinfo) determine_tasks(TECH_FORMAT_STRING,&want_id3,&scantype,&fullscan_vbr,vbr_report); } if(!quickscan && (scantype == SCAN_QUICK)) scantype=SCAN_FULL; firstfilearg=optind; for(i=optind;i < argc; i++) { /* Iterate over all filenames */ file_open=0; if (view_only == 1) { if ( !( fp=fopen(argv[i],"rb") ) ) { sprintf(error_msg,"Error opening MP3: %s",argv[i]); perror(error_msg); retcode |= 1; } else { file_open=1; } } else { if ( !( fp=fopen(argv[i],"rb+") ) ) { sprintf(error_msg,"Error opening MP3: %s",argv[i]); perror(error_msg); retcode |= 1; } else { file_open=1; } } if(file_open == 1) { memset(&mp3,0,sizeof(mp3info)); mp3.filename=argv[i]; mp3.file=fp; get_mp3_info(&mp3,scantype,fullscan_vbr); if((scantype != SCAN_NONE) && !mp3.header_isvalid && !force_mode) { fprintf(stderr,"%s is corrupt or is not a standard MP3 file.\n",mp3.filename); retcode |= 2; } if(view_only) { if(want_id3 && !mp3.id3_isvalid) fprintf(stderr,"%s does not have an ID3 1.x tag.\n",mp3.filename); if(print_format) { format_output(print_format,&mp3,vbr_report); } else { if(mp3.id3_isvalid || (show_techinfo && mp3.header_isvalid)) format_output(FILENAME_FORMAT_STRING,&mp3,vbr_report); if(mp3.id3_isvalid) format_output(ID3_FORMAT_STRING,&mp3,vbr_report); if(show_techinfo && mp3.header_isvalid) format_output(TECH_FORMAT_STRING,&mp3,vbr_report); printf("\n"); } } else if(mp3.header_isvalid || force_mode) { if(new_tag.title[0]!=1) { strncpy(mp3.id3.title,new_tag.title,TEXT_FIELD_LEN); } if(new_tag.artist[0]!=1) { strncpy(mp3.id3.artist,new_tag.artist,TEXT_FIELD_LEN); } if(new_tag.album[0]!=1) { strncpy(mp3.id3.album,new_tag.album,TEXT_FIELD_LEN); } if(new_tag.comment[0]!=1) { strncpy(mp3.id3.comment,new_tag.comment,TEXT_FIELD_LEN); } if(new_track) { mp3.id3.track[0]=new_tag.track[0]; if(new_tag.track[0] == '\0') { pad(mp3.id3.comment,TEXT_FIELD_LEN); } } if(new_tag.year[0]!=1) { strncpy(mp3.id3.year,new_tag.year,INT_FIELD_LEN); } if(new_genre) { mp3.id3.genre[0]=new_tag.genre[0]; } if( interactive ) { tagedit_curs(mp3.filename,i-firstfilearg+1,argc-firstfilearg,&(mp3.id3)); } /* Finally! Get it done! */ if(!delete_tag) { write_tag(&mp3); } } else { fprintf(stderr,"Use the -f switch to add ID3 info to this file anyway.\n"); } fclose(mp3.file); if(delete_tag && mp3.id3_isvalid) { truncate(mp3.filename,mp3.datasize); } } } if(optind == argc) { fprintf(stderr,"No MP3 files specified!\n"); retcode |= 8; } return retcode; }