Audio-RaveMP

 view release on metacpan or  search on metacpan

ravemp.c  view on Meta::CPAN

	XP("\n");
	if (i%32==31) {
	    XP("--more--\n");
	    if (getchar()=='q')
		break;
	}
    }
#endif

    free(blkbuff);

    return 1;
}

/************************ upload_file *********************/

/* Upload a file to the device */

int ravemp_upload_file(char *fname, char *dest_name)
{
    int i,j,mp3file,uploadok;
    int block,blk1no,blk2no,prvblk,nxtblk,page;
    unsigned fsize,fblocks,avail,namelen;
    unsigned char *p,*t,*firstblk,*datablk,*filebuff;
    unsigned char fat[TOTAL_BLOCKS];
    FILE *fp;
    struct stat fileinfo;

    uploadok = 0;

    /* Read device FAT */

    if (!load_fat(fat)) {
	RMP_TRACE(fprintf(stderr, "Unable to load allocation table\n"));
	return 0;
    }

    /* Count free blocks and determine header block numbers */

    avail = 0;

    blk1no = blk2no = -1;

    for (i=0;i<TOTAL_BLOCKS;i++) {

	if (fat[i]==0xff) {

	    if (blk1no == -1)
		blk1no = i;
	    else if (blk2no == -1)
		blk2no = i;

	    avail++;

	}
    }

    /* Get file information (note we simplistically determine if it's an MP3
       file or not by checking for a .mp3 extension) */

    if (stat(fname,&fileinfo) != 0) {
	RMP_TRACE(fprintf(stderr, "Unable to access file %s\n",fname));
	return 0;
    }

    fsize = fileinfo.st_size;

    fblocks = (fsize+DATA_SIZE-1)/DATA_SIZE;

    RMP_TRACE(fprintf(stderr, "File size: %u bytes [%u blocks needed, %u available]\n",fsize,fblocks,avail));

    if (fblocks+2 > avail) {	/* +2 for 2 header blocks */
	RMP_TRACE(fprintf(stderr, "Not enough space available for file\n"));
	return 0;
    }

    mp3file = ((p=strrchr(fname,'.')) != NULL && strcasecmp(p,".mp3")==0);

    /* Open file for upload */

    if ((fp=fopen(fname,"r"))==NULL) {
	RMP_TRACE(fprintf(stderr, "Unable to open file %s\n",fname));
	return 0;
    }

    /* Allocate memory for block buffers */

    if ((firstblk=malloc(MAX_BLOCK_SIZE))==NULL || 
	(datablk=malloc(MAX_BLOCK_SIZE)) == NULL ||
	(filebuff=malloc(DATA_SIZE)) == NULL) {
	RMP_TRACE(fprintf(stderr, "Unable to allocate memory for data buffers\n"));
	fclose(fp);
	return 0;
    }

    /* Build block list for file and put tag characters into FAT buffer */

    memset(firstblk,0xff,MAX_BLOCK_SIZE);	/* Set every value to "unused" */

    p = firstblk;

    *p++ = (blk1no>>8) & 0xff;
    *p++ = blk1no & 0xff;
    fat[blk1no] = mp3file?'M':'E';

    *p++ = (blk2no>>8) &0xff;
    *p++ = blk2no &0xff;
    fat[blk2no] = mp3file?'m':'e';

    for (i=TOTAL_BLOCKS-1,j=fblocks;i>=0&&j>0;i--) {

	if (fat[i]==0xff) {
	    fat[i]=mp3file?'m':'e';
	    *p++ = ((unsigned)i>>8) & 0xff;
	    *p++ = i & 0xff;
	    j--;
	}
    }

    /* Debug */
#if 0

ravemp.c  view on Meta::CPAN

    struct stat fileinfo;
    struct page xpage;
    FILE *fp;

    /* Determine buffer size and allocate it */

    chunksize = PAGE_SIZE+TAG_SIZE;

    buffsize = PAGES_PER_BLOCK * chunksize;

    if ((baseblk=malloc(buffsize)) == NULL || (datablk=malloc(buffsize)) == NULL) {
	RMP_TRACE(fprintf(stderr, "Memory Allocation failure\n"));
	return 0;
    }

    /* Read first block of file, which contains the list of blocks used */

    if (!read_block(firstblock,baseblk)) {
	RMP_TRACE(fprintf(stderr, "Read of First Block failed\n"));
	free(baseblk);
	free(datablk);
	return 0;
    }

    /* Read second block of file, which holds the file information */

    j = (*(baseblk+2)<<8) | *(baseblk+3);

    if (!read_block(j,datablk)) {
	RMP_TRACE(fprintf(stderr, "Read of Second Block failed\n"));
	free(baseblk);
	free(datablk);
	return 0;
    }

    /* Extract file size */

    p = datablk+PAGE_SIZE+TAG_SIZE+PAGE_SIZE; /* Point to second page tag area */

    fsize = 0;
    for (i=0;i<4;i++)
	fsize = (fsize<<8) | *p++;

    if (fsize==0 || fsize > TOTAL_BLOCKS*PAGE_SIZE*PAGES_PER_BLOCK) {
	RMP_TRACE(fprintf(stderr, "Bad file size: %u bytes reported\n",fsize));
	free(baseblk);
	free(datablk);
	return 0;
    }

    /* Extract filename, which is spread across the tags, starting at offset 20 (we
       assume the name length to less than 256-20 or 226 characters) */

    for (i=0;i<256/TAG_SIZE;i++)	/* Collect all tags into buffer */
	memcpy(&tagbuff[i*TAG_SIZE],datablk+i*(PAGE_SIZE+TAG_SIZE)+PAGE_SIZE,TAG_SIZE);

    RMP_TRACE(fprintf(stderr, "File Name: %s File Size: %u\n",&tagbuff[20],fsize)); /**/

    /* Check if file already exists */

    if (stat(&tagbuff[20],&fileinfo) == 0) {
	RMP_TRACE(fprintf(stderr, "\n*** File with same name already exists - download cancelled ***\n"));
	free(baseblk);
	free(datablk);
	return 0;
    }

    /* Create file to save data in */

    if (dest == NULL) {
	dest = &tagbuff[20];
    }

    if ((fp=fopen(dest, "w"))==NULL) {
	RMP_TRACE(fprintf(stderr, "Unable to create file to download into!\n"));
	free(baseblk);
	free(datablk);
	return 0;
    }

    /* Read all file blocks in turn */

    dlok = 1;
    for (page=0;page<PAGES_PER_BLOCK&&dlok&&fsize>0;page++) {

	memcpy(&xpage,baseblk+page*chunksize,chunksize);

	p = &xpage.data[4];	/* Pointer to block list (skipping first 2 blocks) */

	for (i=0;i<PAGE_SIZE/2&&fsize;i++) {

	    j = *p++<<8;

	    j |= *p++;

	    if (j<MIN_DATA_BLOCK || j>=TOTAL_BLOCKS) {
		RMP_TRACE(fprintf(stderr, "Download Failure: Bad Block number %u [Outside Range %u-%u]\n",j,MIN_DATA_BLOCK,TOTAL_BLOCKS-1));
		dlok = 0;
		break;
	    }

	    if (!read_block(j,datablk)) {
		RMP_TRACE(fprintf(stderr, "Error reading Block %u\n",j));
		dlok = 0;
		break;
	    }

	    for (k=0;k<PAGES_PER_BLOCK&&fsize;k++) {

		wrsize = fsize>PAGE_SIZE?PAGE_SIZE:fsize;

		if (fwrite(datablk+k*(PAGE_SIZE+TAG_SIZE),1,wrsize,fp) != wrsize) {
		    RMP_TRACE(fprintf(stderr, "File Write Error!\n"));
		    dlok = 0;
		    break;
		}

		fsize -= wrsize;
	    }
	    ravemp_status_dot();
	    fflush(stdout);



( run in 0.598 second using v1.01-cache-2.11-cpan-df04353d9ac )