示例#1
0
int himd_blockstream_open(struct himd * himd, unsigned int firstfrag, unsigned int frags_per_block, struct himd_blockstream * stream, struct himderrinfo * status)
{
    struct fraginfo frag;
    unsigned int fragcount, fragnum, blockcount;

    g_return_val_if_fail(himd != NULL, -1);
    g_return_val_if_fail(firstfrag >= HIMD_FIRST_FRAGMENT, -1);
    g_return_val_if_fail(firstfrag <= HIMD_LAST_FRAGMENT, -1);
    g_return_val_if_fail(stream != NULL, -1);

    stream->himd = himd;

    for(fragcount = 0, blockcount = 0, fragnum = firstfrag;
        fragnum != 0; fragcount++)
    {
        if(himd_get_fragment_info(himd, fragnum, &frag, status) < 0)
            return -1;
        fragnum = frag.nextfrag;
        if(fragcount > HIMD_LAST_FRAGMENT)
        {
            set_status_printf(status, HIMD_ERROR_FRAGMENT_CHAIN_BROKEN,
                               _("Fragment chain starting at %d loops"), firstfrag);
            return -1;
        }
        blockcount += frag.lastblock - frag.firstblock + 1;
    }

    stream->frags = malloc(fragcount * sizeof stream->frags[0]);
    if(!stream->frags)
    {
        set_status_printf(status, HIMD_ERROR_OUT_OF_MEMORY,
                          _("Can't allocate %d fragments for chain starting at %d"), fragcount, firstfrag);
        return -1;
    }
    stream->fragcount = fragcount;
    stream->blockcount = blockcount;
    stream->curfragno = 0;

    for(fragcount = 0, fragnum = firstfrag; fragnum != 0; fragcount++)
    {
        if(himd_get_fragment_info(himd, fragnum, &stream->frags[fragcount], status) < 0)
            return -1;
        fragnum = stream->frags[fragcount].nextfrag;
    }

    stream->atdata = himd_open_file(himd, "ATDATA", HIMD_READ_ONLY);
    if(!stream->atdata)
    {
        set_status_printf(status, HIMD_ERROR_CANT_OPEN_AUDIO,
                          _("Can't open audio data: %s"), g_strerror(errno));
        free(stream->frags);
        return -1;
    }

    stream->curblockno = stream->frags[0].firstblock;
    stream->frames_per_block = frags_per_block;
    
    return 0;
}
示例#2
0
int himd_nonmp3stream_open(struct himd * himd, unsigned int trackno, struct himd_nonmp3stream * stream, struct himderrinfo * status)
{
    struct trackinfo trkinfo;

    g_return_val_if_fail(himd != NULL, -1);
    g_return_val_if_fail(trackno >= HIMD_FIRST_TRACK, -1);
    g_return_val_if_fail(trackno <= HIMD_LAST_TRACK, -1);
    g_return_val_if_fail(stream != NULL, -1);

    if(himd_get_track_info(himd, trackno, &trkinfo, status) < 0)
        return -1;
    if((trkinfo.codec_id != CODEC_LPCM) &&
       (trkinfo.codec_id != CODEC_ATRAC3) &&
       (trkinfo.codec_id != CODEC_ATRAC3PLUS_OR_MPEG ||
                           (trkinfo.codecinfo[0] & 3) != 0))
    {
        set_status_printf(status, HIMD_ERROR_BAD_AUDIO_CODEC,
                          _("Track %d does not contain PCM, ATRAC3 or ATRAC3+ data"), trackno);
        return -1;
    }
    if(himd_blockstream_open(himd, trkinfo.firstfrag, himd_trackinfo_framesperblock(&trkinfo), &stream->stream, status) < 0)
        return -1;

    if(descrypt_open(&stream->cryptinfo, trkinfo.key, trkinfo.ekbnum, status) < 0)
    {
        himd_blockstream_close(&stream->stream);
        return -1;
    }
    stream->framesize = himd_trackinfo_framesize(&trkinfo);
    stream->framesleft = 0;
    return 0;
}
示例#3
0
int himd_mp3stream_open(struct himd * himd, unsigned int trackno, struct himd_mp3stream * stream, struct himderrinfo * status)
{
    struct trackinfo trkinfo;

    g_return_val_if_fail(himd != NULL, -1);
    g_return_val_if_fail(trackno >= HIMD_FIRST_TRACK, -1);
    g_return_val_if_fail(trackno <= HIMD_LAST_TRACK, -1);
    g_return_val_if_fail(stream != NULL, -1);

    if(himd_get_track_info(himd, trackno, &trkinfo, status) < 0)
        return -1;
    if(trkinfo.codec_id != CODEC_ATRAC3PLUS_OR_MPEG ||
       (trkinfo.codecinfo[0] & 3) != 3)
    {
        set_status_printf(status, HIMD_ERROR_BAD_AUDIO_CODEC,
                          _("Track %d does not contain MPEG data"), trackno);
        return -1;
    }

    if(himd_obtain_mp3key(himd, trackno, &stream->key, status) < 0)
        return -1;

    if(himd_blockstream_open(himd, trkinfo.firstfrag, TRACK_IS_MPEG, &stream->stream, status) < 0)
        return -1;

    stream->frames = 0;
    stream->curframe = 0;
    stream->frameptrs = NULL;

    return 0;
}
示例#4
0
unsigned int himd_get_trackslot(struct himd * himd, unsigned int idx, struct himderrinfo * status)
{
    if(idx >= himd_track_count(himd))
    {
        set_status_printf(status, HIMD_ERROR_NO_SUCH_TRACK, _("Track %d of %d requested"));
        return 0;
    }
    return beword16(himd->tifdata + 0x102 + 2*idx);
}
示例#5
0
char* himd_get_string_utf8(struct himd * himd, unsigned int idx, int*type, struct himderrinfo * status)
{
    int length;
    char * out;
    char * srcencoding;
    char * rawstr;
    GError * err = NULL;
    g_return_val_if_fail(himd != NULL, NULL);
    g_return_val_if_fail(idx >= 1, NULL);
    g_return_val_if_fail(idx < 4096, NULL);
    
    rawstr = himd_get_string_raw(himd, idx, type, &length, status);
    if(!rawstr)
        return NULL;

    switch((unsigned char)rawstr[0])
    {
        case HIMD_ENCODING_LATIN1:
            srcencoding = "ISO-8859-1";
            break;
        case HIMD_ENCODING_UTF16BE:
            srcencoding = "UTF-16BE";
            break;
        case HIMD_ENCODING_SHIFT_JIS:
            srcencoding = "SHIFT_JIS";
            break;
        default:
            set_status_printf(status, HIMD_ERROR_UNKNOWN_ENCODING,
                       "string %d has unknown encoding with ID %d",
                       idx, rawstr[0]);
            himd_free(rawstr);
            return NULL;
    }
    out = g_convert(rawstr+1,length-1,"UTF-8",srcencoding,NULL,NULL,&err);
    himd_free(rawstr);
    if(err)
    {
        set_status_printf(status, HIMD_ERROR_STRING_ENCODING_ERROR,
                   "convert string %d from %s to UTF-8: %s",
                   idx, srcencoding, err->message);
        return NULL;
    }
    return out;
}
示例#6
0
文件: hotssh-tab.c 项目: GNOME/hotssh
static void
on_socket_client_event (GSocketClient      *client,
                        GSocketClientEvent  event,
                        GSocketConnectable *connectable,
                        GIOStream          *connection,
                        gpointer            user_data)
{
  HotSshTab *self = HOTSSH_TAB (user_data);
  HotSshTabPrivate *priv = hotssh_tab_get_instance_private (self);
  switch (event)
    {
    case G_SOCKET_CLIENT_RESOLVING:
      set_status_printf (self, _("Resolving '%s'…"),
                         priv->hostname);
      break;
    case G_SOCKET_CLIENT_CONNECTING:
      {
        GSocketConnection *socketconn = G_SOCKET_CONNECTION (connection);
        gs_unref_object GSocketAddress *remote_address =
          g_socket_connection_get_remote_address (socketconn, NULL);

        g_debug ("socket connecting remote=%p", remote_address);
        if (remote_address && G_IS_INET_SOCKET_ADDRESS (remote_address))
          {
            GInetAddress *inetaddr =
              g_inet_socket_address_get_address ((GInetSocketAddress*)remote_address);
            gs_free char *inet_str = g_inet_address_to_string (inetaddr);
            set_status_printf (self, _("Connecting to '%s'…"),
                               inet_str);
          }
        break;
      }
    default:
      break;
    }
}
示例#7
0
int descrypt_decrypt(void * dataptr, unsigned char * block, size_t cryptlen,
                     const unsigned char * fragkey, struct himderrinfo * status)
{
    unsigned char finalfragkey[8];
    unsigned char mainkey[8];
    struct descrypt_data * data = dataptr;
    int err;

    xor_keys(finalfragkey, data->masterkey, fragkey);
    if((err = cached_cipher_prepare(&data->master, finalfragkey, NULL)) < 0)
    {
        set_status_printf(status, HIMD_ERROR_ENCRYPTION_FAILURE, _("Can't setup track key: %s"), mcrypt_strerror(err));
        return -1;
    }

    memcpy(mainkey, block+16, 8);
    if((err = mcrypt_generic(data->master.cipher, mainkey, 8)) < 0)
    {
        set_status_printf(status, HIMD_ERROR_ENCRYPTION_FAILURE, _("Can't calc block key: %s"), mcrypt_strerror(err));
        return -1;
    }

    if((err = cached_cipher_prepare(&data->block, mainkey, block + 24)) < 0)
    {
        set_status_printf(status, HIMD_ERROR_ENCRYPTION_FAILURE, _("Can't setup block key: %s"), mcrypt_strerror(err));
        return -1;
    }

    if((err = mdecrypt_generic(data->block.cipher, block+32, cryptlen)) < 0)
    {
        set_status_printf(status, HIMD_ERROR_ENCRYPTION_FAILURE, _("Can't decrypt: %s"), mcrypt_strerror(err));
        return -1;
    }

    return 0;
}
示例#8
0
int himd_get_track_info(struct himd * himd, unsigned int idx, struct trackinfo * t, struct himderrinfo * status)
{
    unsigned char * trackbuffer;
    unsigned int firstpart;

    g_return_val_if_fail(himd != NULL, -1);
    g_return_val_if_fail(idx >= HIMD_FIRST_TRACK, -1);
    g_return_val_if_fail(idx <= HIMD_LAST_TRACK, -1);
    g_return_val_if_fail(t != NULL, -1);

    trackbuffer = get_track(himd, idx);
    firstpart = beword16(trackbuffer+36);

    if(firstpart == 0)
    {
        set_status_printf(status, HIMD_ERROR_NO_SUCH_TRACK,
                          _("Track %d is not present on disc"), idx);
        return -1;
    }
    get_dostime(&t->recordingtime,trackbuffer+0);
    t->ekbnum = beword32(trackbuffer+4);
    t->title = beword16(trackbuffer+8);
    t->artist = beword16(trackbuffer+10);
    t->album = beword16(trackbuffer+12);
    t->trackinalbum = trackbuffer[14];
    memcpy(t->key, trackbuffer+16,8);
    memcpy(t->mac, trackbuffer+24,8);
    t->codec_id = trackbuffer[32];
    memcpy(t->codecinfo,trackbuffer+33,3);
    memcpy(t->codecinfo+3,trackbuffer+44,2);
    t->firstfrag = firstpart;
    t->tracknum = beword16(trackbuffer+38);
    t->seconds = beword16(trackbuffer+40);
    memcpy(t->contentid,trackbuffer+48,20);
    get_dostime(&t->starttime,trackbuffer+68);
    get_dostime(&t->endtime,trackbuffer+72);
    return 0;
}
示例#9
0
int himd_add_string(struct himd * himd, char *string, int type, struct himderrinfo * status)
{
    int curidx, curtype, i, nextidx;
    int nslots;
    int idx_firstslot;
    gsize length;
    gchar * convertedstring;
    unsigned char * curchunk;
    unsigned char strencoding;

    g_return_val_if_fail(himd != NULL, -1);
    g_return_val_if_fail(string != NULL, -1);


    /* try to use Latin-1 or Shift-JIS. If that fails, use Unicode. */
    if((convertedstring = g_convert(string,-1,"ISO-8859-1","UTF8",
                                    NULL,&length,NULL)) != NULL)
        strencoding = HIMD_ENCODING_LATIN1;
    else if((convertedstring = g_convert(string,-1,"SHIFT_JIS","UTF8",
                                    NULL,&length,NULL)) != NULL)
        strencoding = HIMD_ENCODING_SHIFT_JIS;
    else if((convertedstring = g_convert(string,-1,"UTF-16BE","UTF8",
                                    NULL,&length,NULL)) != NULL)
        strencoding = HIMD_ENCODING_UTF16BE;
    else {
        /* should never happen, as utf-16 can encode anything */
	set_status_printf(status, HIMD_ERROR_UNKNOWN_ENCODING,
			  "can't encode the string '%s' into anything usable",
                          string);
        return -1;
    }

    /* how many number of slots to store string in? */
    nslots = (length+14)/14;	/* +13 for rounding up, +1 for the encoding byte */

    /* check that there are enough free slots. Start at slot 0 which
       is the head of the free list. */
    curidx = 0;
    for(i = 0; i < nslots; i--)
    {
        curtype = strtype(get_strchunk(himd, curidx));
        curidx = strlink(get_strchunk(himd, curidx));
        if(!curidx)
        {
            g_free(convertedstring);
            set_status_printf(status, HIMD_ERROR_OUT_OF_STRINGS,
                "Not enough string space to allocate %d string slots\n", nslots);
            return -1;
        }
        if(curtype != STRING_TYPE_UNUSED)
        {
            g_free(convertedstring);
            set_status_printf(status, HIMD_ERROR_STRING_CHAIN_BROKEN,
                "String slot %d in free list has type %d\n", curidx, curtype);
            return -1;
        }
    }

    idx_firstslot = strlink(get_strchunk(himd, 0));
    curidx = idx_firstslot;
    for(i = 0; i < nslots; i++)
    {
        /* reserve space for the encoding byte in the first slot */
        gsize slotlen = (i != 0) ? 14 : 13;
        gsize stroffset = i*14 - 1;

        /* limit length to what is remaining of the string */
        if(slotlen > length - stroffset)
            slotlen = length - stroffset;

        curchunk = get_strchunk(himd, curidx);
        nextidx  = strlink(curchunk);
        if(i == 0)
        {
            curchunk[0] = strencoding;
            memcpy(curchunk + 1, convertedstring, slotlen);
            set_strtype(curchunk, type);
        }
        else
        {
            memcpy(curchunk, convertedstring + stroffset, slotlen);
            set_strtype(curchunk, STRING_TYPE_CONTINUATION);
        }
        if(i == nslots-1)
            set_strlink(curchunk, 0);
        curidx = nextidx;
    }

    /* adjust free list head pointer */
    set_strlink(get_strchunk(himd, 0), curidx);
    g_free(convertedstring);

    return idx_firstslot;
}
示例#10
0
char* himd_get_string_raw(struct himd * himd, unsigned int idx, int*type, int* length, struct himderrinfo * status)
{
    int curidx;
    int len;
    char * rawstr;
    int actualtype;

    g_return_val_if_fail(himd != NULL, NULL);
    g_return_val_if_fail(idx >= 1, NULL);
    g_return_val_if_fail(idx < 4096, NULL);
    
    actualtype = strtype(get_strchunk(himd,idx));
    /* Not the head of a string */
    if(actualtype < 8)
    {
        set_status_printf(status, HIMD_ERROR_NOT_STRING_HEAD,
                   _("String table entry %d is not a head: Type %d"),
                   idx,actualtype);
        return NULL;
    }
    if(type != NULL)
        *type = actualtype;

    /* Get length of string */
    len = 1;
    for(curidx = strlink(get_strchunk(himd,idx)); curidx != 0; 
          curidx = strlink(get_strchunk(himd,curidx)))
    {
        if(strtype(get_strchunk(himd,curidx)) != STRING_TYPE_CONTINUATION)
        {
            set_status_printf(status, HIMD_ERROR_STRING_CHAIN_BROKEN,
                       _("%dth entry in string chain starting at %d has type %d"),
                       len+1,idx,strtype(get_strchunk(himd,curidx)));
            return NULL;
        }
        len++;
        if(len >= 4096)
        {
            set_status_printf(status, HIMD_ERROR_STRING_CHAIN_BROKEN,
                       _("string chain starting at %d loops"),idx);
            return NULL;
        }
    }

    /* collect fragments */
    rawstr = g_malloc(len*14);
    if(!rawstr)
    {
        set_status_printf(status, HIMD_ERROR_OUT_OF_MEMORY,
                   _("Can't allocate %d bytes for raw string (string idx %d)"),
                   len, idx);
        return NULL;
    }

    len = 0;
    for(curidx = idx; curidx != 0; 
          curidx = strlink(get_strchunk(himd,curidx)))
    {
        memcpy(rawstr+len*14,get_strchunk(himd,curidx),14);
        len++;
    }

    *length = 14*len;
    return rawstr;
}
示例#11
0
int himd_blockstream_read(struct himd_blockstream * stream, unsigned char * block,
                            unsigned int * firstframe, unsigned int * lastframe,
                            unsigned char * fragkey, struct himderrinfo * status)
{
    struct fraginfo * curfrag;

    g_return_val_if_fail(stream != NULL, -1);
    g_return_val_if_fail(block != NULL, -1);

    if(stream->curfragno == stream->fragcount)
    {
        set_status_const(status, HIMD_STATUS_AUDIO_EOF, _("EOF of audio stream reached"));
        return -1;
    }

    curfrag = &stream->frags[stream->curfragno];

    if(stream->curblockno == curfrag->firstblock)
    {
        if(firstframe)
            *firstframe = curfrag->firstframe;
        if(fseek(stream->atdata, stream->curblockno*16384L, SEEK_SET) < 0)
        {
            set_status_printf(status, HIMD_ERROR_CANT_SEEK_AUDIO,
                              _("Can't seek in audio data: %s"), g_strerror(errno));
            return -1;
        }
    }
    else if(firstframe)
        *firstframe = 0;

    if(fread(block, 16384, 1, stream->atdata) != 1)
    {
        if(feof(stream->atdata))
            set_status_printf(status, HIMD_ERROR_CANT_READ_AUDIO, _("Unexpected EOF while reading audio block %d"),stream->curblockno);
        else
            set_status_printf(status, HIMD_ERROR_CANT_READ_AUDIO, _("Read error on block audio %d: %s"), stream->curblockno, g_strerror(errno));
        return -1;
    }

    if(fragkey)
        memcpy(fragkey, curfrag->key, sizeof curfrag->key);

    if(stream->curblockno == curfrag->lastblock)
    {
        if(lastframe)
        {
            if(is_mpeg(stream))
                *lastframe = curfrag->lastframe - 1;
            else
                *lastframe = curfrag->lastframe;
        }
        stream->curfragno++;
        curfrag++;
        if(stream->curfragno < stream->fragcount)
            stream->curblockno = curfrag->firstblock;
    }
    else
    {
        if(lastframe)
        {
            if(is_mpeg(stream))
                *lastframe = beword16(block+4) - 1;
            else
                *lastframe = stream->frames_per_block - 1;
        }
        stream->curblockno++;
    }

    return 0;
}
示例#12
0
int himd_mp3stream_read_block(struct himd_mp3stream * stream, const unsigned char ** frameout, unsigned int * lenout, unsigned int * framecount, struct himderrinfo * status)
{
    unsigned int i;
    unsigned int firstframe, lastframe;
    unsigned int dataframes, databytes;

    /* partial block remaining, return all remaining frames */
    if(stream->curframe < stream->frames)
    {
        if(frameout)
            *frameout = stream->frameptrs[stream->curframe];
        if(lenout)
            *lenout = stream->frameptrs[stream->frames] - 
                      stream->frameptrs[stream->curframe];
        if(framecount)
            *framecount = stream->frames - stream->curframe;

        stream->curframe = stream->frames;
        return 0;
    }
    
    /* need to read next block */
    if(himd_blockstream_read(&stream->stream, stream->blockbuf,
                             &firstframe, &lastframe, NULL, status) < 0)
        return -1;

    free(stream->frameptrs);
    stream->frameptrs = NULL;

    if(firstframe > lastframe)
    {
        set_status_printf(status, HIMD_ERROR_BAD_FRAME_NUMBERS,
                   _("Last frame %u before first frame %u"),
                   lastframe, firstframe);
        return -1;
    }

    dataframes = beword16(stream->blockbuf+4);
    databytes = beword16(stream->blockbuf+8);

    if(databytes > 0x3FC0)
    {
        set_status_printf(status, HIMD_ERROR_BAD_DATA_FORMAT,
                   _("Block contains %u MPEG data bytes, which is too much"),
                   databytes);
        return -1;
    }

    if(lastframe >= dataframes)
    {
        set_status_printf(status, HIMD_ERROR_BAD_FRAME_NUMBERS,
                   _("Last requested frame %u past number of frames %u"),
                   lastframe, dataframes);
        return -1;
    }

    /* Decrypt block */
    for(i = 0;i < (databytes & ~7U);i++)
        stream->blockbuf[i+0x20] ^= stream->key[i & 3];

    /* Indicate completely consumed block 
       be sure to set this *before* writing to *framecont,
       it might alias stream->frames! */
    stream->frames = 0;
    stream->curframe = 0;

    /* The common case - all frames belong to the stream to read.
       If compiled without MAD, always put all frames into the block */
#ifndef CONFIG_WITH_MAD
    if(firstframe == 0 && lastframe == dataframes - 1)
#endif
    {
        if(frameout)
            *frameout = stream->blockbuf + 0x20;

        if(lenout)
            *lenout = databytes;

        if(framecount)
            *framecount = dataframes;

        return 0;
    }

#ifdef CONFIG_WITH_MAD
    if(himd_mp3stream_split_frames(stream, databytes, firstframe, lastframe, status) < 0)
        return -1;

    if(*framecount)
        *framecount = lastframe - firstframe + 1;
#endif
    return 0;
}
示例#13
0
static int himd_mp3stream_split_frames(struct himd_mp3stream * stream, unsigned int databytes, unsigned int firstframe, unsigned int lastframe, struct himderrinfo * status)
{
    int gotdata = 1;
    unsigned int i;
    struct mad_stream madstream;
    struct mad_header madheader;

    /* stream->frameptrs is NULL if the current frame has not been splitted yet */
    g_warn_if_fail(stream->frameptrs == NULL);

    stream->frameptrs = malloc((lastframe - firstframe + 2) * sizeof stream->frameptrs[0]);
    if(!stream->frameptrs)
    {
        set_status_printf(status, HIMD_ERROR_OUT_OF_MEMORY,
                   _("Can't allocate memory for %u frame pointers"),
                   lastframe-firstframe+2);
        return -1;
    }
    /* parse block */
    mad_stream_init(&madstream);
    mad_header_init(&madheader);

    mad_stream_buffer(&madstream, &stream->blockbuf[0x20],
                                  databytes+MAD_BUFFER_GUARD);

    /* drop unneeded frames in front */
    while(firstframe > 0)
    {
        if(mad_header_decode(&madheader, &madstream) < 0)
        {
            set_status_printf(status, HIMD_ERROR_BAD_DATA_FORMAT,
                _("Still %u frames to skip: %s"), firstframe, mad_stream_errorstr(&madstream));
            gotdata = 0;
            goto cleanup_decoder;
        }
        firstframe--;
        lastframe--;
    }
    

    /* store needed frames */
    for(i = 0;i <= lastframe;i++)
    {
        if(mad_header_decode(&madheader, &madstream) < 0 &&
            (madstream.error != MAD_ERROR_LOSTSYNC || i != lastframe))
        {
            set_status_printf(status, HIMD_ERROR_BAD_DATA_FORMAT,
                _("Frame %u of %u to store: %s"), i+1, lastframe, mad_stream_errorstr(&madstream));
            gotdata = 0;
            goto cleanup_decoder;
        }
        stream->frameptrs[i] = madstream.this_frame;
    }
    stream->frameptrs[i] = madstream.next_frame;
    stream->frames = lastframe+1;
    stream->curframe = 0;

cleanup_decoder:
    mad_header_finish(&madheader);
    mad_stream_finish(&madstream);

    if(!gotdata)
        return -1;

    return 0;
}