/** * Builds and returns the next packet, or NULL * if no more data is available. */ void *get_next_packet(int sequence, int *len) { //store sent packets in buffer if (wind_cache[sequence % WIND_SIZE]) { void* cached_pkt = wind_cache[sequence % WIND_SIZE]; int cached_header_seq = read_hseq(cached_pkt); if (cached_header_seq == sequence ) { //packets are only sent from the buffer if packet loss or a timeout occured debug_time = SEND_TIMEOUT; mylog( "[From Cache] %i\n", cached_header_seq); *len = sizeof(header) + read_hlength(cached_pkt); return cached_pkt; } } //increase timeout debug_time += SHORT_TIMEOUT; char *data = malloc(DATA_SIZE); int data_length = get_next_data(data, DATA_SIZE); if (data_length == 0) { free(data); return NULL; } //create header for packet header *myheader = make_header(sequence, data_length, 0, 0); //create the packet void *pkt = malloc(sizeof(header) + data_length + sizeof(checksum_t)); memcpy(pkt, myheader, sizeof(header)); memcpy(((char *) pkt) + sizeof(header), data, data_length); //calculate the checksum for the packet and attach checksum_t chksm = chksum(data, data_length); memcpy(((char *) pkt) + sizeof(header) + data_length, &chksm, sizeof(checksum_t)); free(data); free(myheader); //len = packet size in bytes *len = sizeof(header) + data_length + sizeof(checksum_t); mylog("Checksum %d\n", get_chksum(pkt, data_length + sizeof(header))); if (wind_cache[sequence % WIND_SIZE]) { free(wind_cache[sequence % WIND_SIZE]); } wind_cache[sequence % WIND_SIZE] = (void*)malloc(sizeof(header) + data_length + sizeof(checksum_t)); memcpy(wind_cache[sequence % WIND_SIZE], pkt, sizeof(header) + data_length + sizeof(checksum_t)); return pkt; }
int main (int argc, char **argv) { int c; char *m4afile = NULL; M4A_TAG_CFG cfg; cfg.mode = M4A_MODE_INVALID; cfg.md5sum = M4A_FALSE; cfg.sha1sum = M4A_FALSE; cfg.art = M4A_FALSE; cfg.pixpath[0] = '\0'; while (1) { static struct option long_options[] = { {"literal", no_argument, 0, 'l'}, {"verbose", no_argument, 0, 'v'}, {"with-md5sum", no_argument, 0, 'm'}, {"with-sha1sum", no_argument, 0, 's'}, {"extract-art", no_argument, 0, 'e'}, {"extract-art-to", required_argument, 0, 'p'}, {"output", required_argument, 0, 'o'}, {"help", no_argument, 0, 'h'}, {"test", no_argument, 0, 't'}, {0, 0, 0, 0} }; /* getopt_long stores the option index. */ int option_index = 0; c = getopt_long (argc, argv, "p:o:lvhtmse", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: /* Is mode set ? */ if (long_options[option_index].flag != 0) break; printf ("option %s", long_options[option_index].name); if (optarg) printf (" with arg %s", optarg); printf ("\n"); break; case 'l': cfg.mode = M4A_MODE_LITERAL; break; case 'v': cfg.mode = M4A_MODE_VERBOSE; break; case 't': cfg.mode = M4A_MODE_TESTING; break; case 'm': cfg.md5sum = M4A_TRUE; break; case 's': cfg.sha1sum = M4A_TRUE; break; case 'e': cfg.art = M4A_TRUE; break; case 'p': cfg.art = M4A_TRUE; strcpy(cfg.pixpath, optarg); break; case 'o': printf ("option -o with value `%s'\n", optarg); printf ("Not Yet Supported.....\n"); return 20; case 'h': printf ("\n%s", USAGE); return 0; case '?': /* getopt_long already printed an error message. */ return 20; default: fprintf (stderr, "Invalid Option\n%s\n", USAGE); return 30; } } /* Grab File names*/ if (optind < argc) { /* For Later Use only one for now while (optind < argc) { printf ("%s ", argv[optind++]); } */ m4afile = argv[optind]; } else { fprintf(stderr, "No Files specified\n%s", USAGE); return 1; } TestFileExistence(m4afile, true); xmlInitEndianDetection(); ExtractPaddingPrefs(NULL); tree_display_only=true; APar_ScanAtoms(m4afile); if (cfg.mode == M4A_MODE_LITERAL) { unsigned char *md5sum = NULL; unsigned char *sha1sum = NULL; int cnt = 0; M4A_ART *art = NULL; M4A_ART bfr[M4A_MAX_ART]; char *bfname = NULL; char path[512]; openSomeFile(m4afile, true); get_chksum(&cfg, m4afile, &md5sum, &sha1sum); if (cfg.art == M4A_TRUE) { int cvr; int idx; int ret; cvr = m4a_get_atomidx((const char *) "covr", 1, 0); idx = parsedAtoms[cvr].NextAtomNumber; while (parsedAtoms[idx].AtomicLevel > parsedAtoms[cvr].AtomicLevel) { ret = m4a_extract_art(idx, &bfr[cnt]); if (ret != 0) break; cnt++; idx = parsedAtoms[idx].NextAtomNumber; } if (cnt != 0) { char tmp[512]; strcpy(tmp, m4afile); if (cfg.pixpath[0] != '\0') { char *bname; strcpy(path, cfg.pixpath); strcat(path, "/"); bname = basename(tmp); strcat(path, bname); // printf ("Fname: %s\n", path); bfname = path; } art = bfr; } } redirect_io(&cfg); if (metadata_style >= THIRD_GEN_PARTNER) { APar_PrintUserDataAssests(); } else if (metadata_style == ITUNES_STYLE) { APar_PrintDataAtoms(m4afile, NULL, 0, PRINT_DATA); } reset_io(&cfg); m4a_display_json_tags( cfg.str, stdout, md5sum, sha1sum, art, cnt, bfname); openSomeFile(m4afile, false); } else if (cfg.mode == M4A_MODE_VERBOSE) { redirect_io(&cfg); APar_PrintAtomicTree(); reset_io(&cfg); m4a_display_json_tree(cfg.str, stdout); } else if (cfg.mode == M4A_MODE_TESTING) { int mda; unsigned char bfr[2][64]; int cvr; mda = APar_DetermineMediaData_AtomPosition(); printf ("Location of mdat: %d\n", mda); //APar_SimpleAtomPrintout(); m4a_stream_chksum(m4afile, bfr[0], bfr[1]); cvr = m4a_get_atomidx((const char *) "covr", 1, 0); printf("\n"); } else { unsigned char *md5sum = NULL, *sha1sum = NULL; if (get_chksum(&cfg, m4afile, &md5sum, &sha1sum) == 0) { if ((md5sum != NULL) || (sha1sum != NULL)) { char pfx[2]; pfx[0] = '\0'; printf("{\n \"stream\": {"); if (md5sum != NULL) { printf(" \"md5sum\": \"%s\"", md5sum); pfx[0] = ','; pfx[1] = '\0'; } if (sha1sum != NULL) { printf("%s \"sha1sum\": \"%s\"", pfx, sha1sum); } printf(" }\n}\n"); } } else if (cfg.art == M4A_TRUE) { M4A_ART art[M4A_MAX_ART]; int cvr; int idx; int ret; int cnt = 0; char path[512]; FILE *fp; FILE *out = stdout; if (cfg.pixpath[0] != '\0') { char tmp[256]; char *bname = NULL; strcpy(tmp, m4afile); strcpy(path, cfg.pixpath); strcat(path, "/"); bname = basename(tmp); strcat(path, bname); } fputs ("{\n \"@img\": [ ", out); openSomeFile(m4afile, true); cvr = m4a_get_atomidx((const char *) "covr", 1, 0); idx = parsedAtoms[cvr].NextAtomNumber; while (parsedAtoms[idx].AtomicLevel > parsedAtoms[cvr].AtomicLevel) { int err = M4A_FALSE; const char *extn = NULL; ret = m4a_extract_art(idx, &art[cnt]); if (ret != 0) break; if ( art[cnt].type == M4A_PNG) { extn = "png"; } else if ( art[cnt].type == M4A_JPG) { extn = "jpg"; } if (cfg.pixpath[0] != '\0') { char fname[512]; sprintf(fname, "%s.%d.%s", path, cnt+1, extn); if ((fp = fopen(fname, "wb")) != NULL) { if (fwrite(art[cnt].data, 1, art[cnt].size, fp) != art[cnt].size) { perror("img write:"); err = M4A_TRUE; } fclose(fp); } else { perror("img create:"); err = M4A_TRUE; } if (cnt != 0) fputs(", ", out); if (err == M4A_TRUE) fputs("null", out); else fprintf(out, "\"%s\"", fname); } else { base64_encodestate inst; char bfr[M4A_B64_BFR_SZ*2]; int clen; int blks; int j; base64_init_encodestate(&inst); blks = art[cnt].size/1024; if (cnt != 0) fputs(", ", out); fprintf (out, "{\"type\": \"%s\", \"data\": \"", extn); for (j = 0; j < blks; j++) { clen = base64_encode_block( (const char*) &art[cnt].data[j * M4A_B64_BFR_SZ], M4A_B64_BFR_SZ, bfr, &inst); //fwrite((void *)bfr, clen, 1, out); m4a_print_without_newlines(out, bfr, clen); } clen = base64_encode_block( (const char*) &art[cnt].data[j * M4A_B64_BFR_SZ], art[cnt].size % M4A_B64_BFR_SZ, bfr, &inst); m4a_print_without_newlines(out, bfr, clen); clen = base64_encode_blockend(bfr, &inst); m4a_print_without_newlines(out, bfr, clen); if (cnt != 0) fputs(", ", out); fputs ("\"}", out); } cnt++; idx = parsedAtoms[idx].NextAtomNumber; } openSomeFile(m4afile, false); fputs (" ]\n}\n", out); } } exit (0); }