/** * Read from block device * * @v http HTTP transaction * @v data Data interface * @v lba Starting logical block address * @v count Number of logical blocks * @v buffer Data buffer * @v len Length of data buffer * @ret rc Return status code */ int http_block_read ( struct http_transaction *http, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len ) { struct http_request_range range; int rc; /* Sanity check */ assert ( len == ( count * HTTP_BLKSIZE ) ); /* Construct request range descriptor */ range.start = ( lba * HTTP_BLKSIZE ); range.len = len; /* Start a range request to retrieve the block(s) */ if ( ( rc = http_open ( data, &http_get, http->uri, &range, NULL ) ) != 0 ) goto err_open; /* Insert block device translator */ if ( ( rc = block_translate ( data, buffer, len ) ) != 0 ) { DBGC ( http, "HTTP %p could not insert block translator: %s\n", http, strerror ( rc ) ); goto err_translate; } return 0; err_translate: intf_restart ( data, rc ); err_open: return rc; }
hstream stream_detect( const char *url ) { FILE *fd; char *hdr = NULL; hstream ret = HS_NONE; if (!url) return HS_NONE; if (!strstr(url, HTTP_PREFIX)) return HS_NONE; if ((fd=http_open(url)) == NULL) return HS_NONE; hdr = read_header(fd); func("stream detect got header:\n%s\n",hdr); fclose(fd); if (!hdr) return HS_NONE; // simple analysis of Content-Type: if (strstr(hdr,"audio/mpeg")) ret = HS_MP3; else if (strstr(hdr,"application/ogg")) ret = HS_OGG; else if (strstr(hdr,"SHOUTcast") || strstr(hdr,"ICY 200")) ret = HS_MP3; else if (strstr(hdr,"icy-")) // add for compatibility to proton ret = HS_MP3; free(hdr); return ret; }
int bb_is_paper_in_adf(struct ledm_session *ps) /* 0 = no paper in adf, 1 = paper in adf, -1 = error */ { char buf[1024]; int bytes_read; struct bb_ledm_session *pbb = ps->bb_session; if(http_open(ps->dd, HPMUD_S_LEDM_SCAN, &pbb->http_handle) != HTTP_R_OK) { _BUG("unable to open channel HPMUD_S_LEDM_SCAN \n"); return -1; } if (http_write(pbb->http_handle, GET_SCANNER_STATUS, sizeof(GET_SCANNER_STATUS)-1, 10) != HTTP_R_OK) { _BUG("unable to get scanner status \n"); } read_http_payload(ps, buf, sizeof(buf), EXCEPTION_TIMEOUT, &bytes_read); http_close(pbb->http_handle); /* error, close http connection */ pbb->http_handle = 0; _DBG("bb_is_paper_in_adf .job_id=%d page_id=%d buf=%s \n", ps->job_id, ps->page_id, buf ); if(strstr(buf, ADF_LOADED)) return 1; if(strstr(buf, ADF_EMPTY)) { if (strstr(buf, SCANNER_BUSY_WITH_SCAN_JOB)) return 1; if (ps->currentInputSource ==IS_ADF_DUPLEX && ps->page_id % 2 == 1) return 1; else return 0; } else return -1; }
static JSBool req_open(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) { JSBool ret = JS_FALSE; if(argc == 2) { ret = http_open(cx, obj, argv[0], argv[1], JSVAL_FALSE); } else if(argc == 3) { ret = http_open(cx, obj, argv[0], argv[1], argv[2]); } else { JS_ReportError(cx, "Invalid call to CouchHTTP.open"); } *rval = JSVAL_VOID; return ret; }
static JSBool req_open(JSContext* cx, uintN argc, jsval* vp) { JSObject* obj = JS_THIS_OBJECT(cx, vp); jsval* argv = JS_ARGV(cx, vp); JSBool ret = JS_FALSE; if(argc == 2) { ret = http_open(cx, obj, argv[0], argv[1], JSVAL_FALSE); } else if(argc == 3) { ret = http_open(cx, obj, argv[0], argv[1], argv[2]); } else { JS_ReportError(cx, "Invalid call to CouchHTTP.open"); } JS_SET_RVAL(cx, vp, JSVAL_VOID); return ret; }
static int cancel_job(struct ledm_session *ps) { struct bb_ledm_session *pbb = ps->bb_session; int len, stat=1, tmo=5/*EXCEPTION_TIMEOUT*/; char buf[2048]; int bytes_read; _DBG("cancel_job user_cancel=%d job_id=%d url=%s \n", ps->user_cancel, ps->job_id, ps->url); if (ps->job_id == 0 || ps->user_cancel == 0) { ps->job_id = 0; ps->page_id = 0; return 0 ; } if (http_open(ps->dd, HPMUD_S_LEDM_SCAN, &pbb->http_handle) != HTTP_R_OK) { _BUG("unable to open http connection %s\n", ps->uri); goto bugout; } len = snprintf(buf, sizeof(buf), CANCEL_JOB_REQUEST, ps->url, strlen(CANCEL_JOB_DATA)); if (http_write(pbb->http_handle, buf, len, 1) != HTTP_R_OK) { _BUG("unable to cancel_job %s\n", ps->url); } len = snprintf(buf, sizeof(buf), CANCEL_JOB_DATA); if (http_write(pbb->http_handle, buf, len, 1) != HTTP_R_OK) { _BUG("unable to cancel_job %s\n", ps->url); } if (read_http_payload(ps, buf, sizeof(buf), tmo, &bytes_read)) goto bugout; stat=0; bugout: if (pbb->http_handle) { http_close(pbb->http_handle); pbb->http_handle = 0; } return stat; }; /* cancel_job */
FILE * hopen( const char *url, const char *mode ) { FILE *fd = NULL; if (!url) return NULL; act("opening stream: '%s'", url); if (strstr(url, HTTP_PREFIX)) { fd = http_open(url); if (fd) { strip_header(fd); /*if server replies with err message and closes*/ if (feof(fd)) {fclose(fd); fd=NULL;} } return fd; } else { return fopen(url, mode); } }
static int get_scanner_elements(struct ledm_session *ps, struct wscn_scan_elements *elements) { struct bb_ledm_session *pbb = ps->bb_session; int bytes_read = 0; int stat=1, tmo=10; char buf[8192]; if (http_open(ps->dd, HPMUD_S_LEDM_SCAN, &pbb->http_handle) != HTTP_R_OK) { _BUG("unable to open http connection %s\n", ps->uri); goto bugout; } /* Write the xml payload. */ if (http_write(pbb->http_handle, GET_SCANNER_ELEMENTS, sizeof(GET_SCANNER_ELEMENTS)-1, tmo) != HTTP_R_OK) { _BUG("unable to get_scanner_elements %s\n", ps->uri); goto bugout; } /* Read http response. */ if (read_http_payload(ps, buf, sizeof(buf), tmo, &bytes_read)) goto bugout; _DBG("get_scanner_elements bytes_read=%d len=%d buf=%s\n", bytes_read, strlen(buf), buf); http_unchunk_data(buf); bytes_read=strlen(buf); _DBG("get_scanner_elements buf=%s\n", buf); parse_scan_elements(buf, bytes_read, elements); stat=0; bugout: if (pbb->http_handle) { http_close(pbb->http_handle); pbb->http_handle = 0; } return stat; } /* get_scanner_elements */
/** * Read block device capacity * * @v control Control interface * @v data Data interface * @ret rc Return status code */ int http_block_read_capacity ( struct http_transaction *http, struct interface *data ) { int rc; /* Start a HEAD request to retrieve the capacity */ if ( ( rc = http_open ( data, &http_head, http->uri, NULL, NULL ) ) != 0 ) goto err_open; /* Insert block device translator */ if ( ( rc = block_translate ( data, UNULL, HTTP_BLKSIZE ) ) != 0 ) { DBGC ( http, "HTTP %p could not insert block translator: %s\n", http, strerror ( rc ) ); goto err_translate; } return 0; err_translate: intf_restart ( data, rc ); err_open: return rc; }
int main(int argc, char *argv[]) { int fd = 0; char *currentfile, old_dir[PATH_MAX]; playlist *pl = NULL; struct id3_file *id3struct = NULL; struct id3_tag *id3tag = NULL; int retval; buffer playbuf; struct mad_decoder decoder; pthread_t keyb_thread; key_t sem_key; key_t mem_key; key_t frames_key; union semun sem_ops; int shm_id; int frames_id; mad_decoder_position = 0; output_buffer_position = 0; old_dir[0] = '\0'; playbuf.pl = pl = new_playlist(); if (!pl) { fprintf(stderr, "malloc failed at startup!\n"); exit(1); } loop_remaining = 1; options.volume = MAD_F_ONE; status = MPG321_PLAYING; /* Get the command line options */ parse_options(argc, argv, pl); if(options.opt & MPG321_PRINT_FFT) if(!(options.opt & MPG321_REMOTE_PLAY)) { /* printf("FFT analysis can only be used in Remote mode play.\n\n"); */ usage(argv[0]); exit(0); } /* If there were no files and no playlist specified just print the usage */ if (!playlist_file && optind == argc) { usage(argv[0]); exit(0); } if (playlist_file) load_playlist(pl, playlist_file); if(options.opt & MPG321_RECURSIVE_DIR) add_cmdline_files_recursive_dir(pl, argv); else add_cmdline_files(pl, argv); if (shuffle_play) shuffle_files(pl); if(options.opt & MPG321_ENABLE_BUFFER) { /* Initialize semaphore and shared memeory */ if(access(argv[0],X_OK) == 0) sem_key = ftok(argv[0],0); else sem_key = ftok(MPG321_PATH,0); if(sem_key == -1) { perror("Cannot obtain resources for semaphores"); exit(EXIT_FAILURE); } semarray = semget(sem_key,3,IPC_CREAT | IPC_EXCL | S_IRWXU); if(semarray == -1) { perror("Cannot initialize semaphores"); exit(EXIT_FAILURE); } sem_ops.val = buffer_size-1; if(semctl(semarray,0,SETVAL,sem_ops) == -1) { perror("Error while initializing mad_decoder semaphore"); if(semctl(semarray,0,IPC_RMID) == -1) perror("Error while destroying semaphores"); goto out; //exit(EXIT_FAILURE); } sem_ops.val = 0; if(semctl(semarray,1,SETVAL,sem_ops) == -1) { perror("Error while initializing mad_decoder semaphore"); if(semctl(semarray,0,IPC_RMID) == -1) perror("Error while destroying semaphores"); goto out; //exit(EXIT_FAILURE); } sem_ops.val = 0; if(semctl(semarray,2,SETVAL,sem_ops) == -1) { perror("Error while initializing mad_decoder semaphore"); if(semctl(semarray,0,IPC_RMID) == -1) perror("Error while destroying semaphores"); goto out; //exit(EXIT_FAILURE); } /* Shared Memory */ mem_key = ftok(argv[0],1); shm_id = shmget(mem_key,buffer_size * sizeof(output_frame), IPC_CREAT | S_IREAD | S_IWRITE); if(shm_id == -1) { perror("Cannot initialize shared buffer"); goto out; //exit(EXIT_FAILURE); } Output_Queue = shmat(shm_id,NULL,0); if(*(int *)Output_Queue == -1) { perror("Error while attaching shared buffer to mad_decoder"); if(shmctl(shm_id,IPC_RMID,NULL)) perror("Cannot destroy shared buffer"); goto out; //exit(EXIT_FAILURE); } static int n; for(n=0;n<buffer_size;n++) { memset((Output_Queue+n)->data,'\0',4608); memset((Output_Queue+n)->time,'\0',80); (Output_Queue+n)->length = 0; (Output_Queue+n)->seconds = 0; (Output_Queue+n)->num_frames = 0; } frames_key = ftok(argv[0],2); frames_id = shmget(frames_key,buffer_size * sizeof(decoded_frames), IPC_CREAT | S_IREAD | S_IWRITE); if(frames_id == -1) { perror("Cannot initialize shared frames counter"); goto out; //exit(EXIT_FAILURE); } Decoded_Frames = shmat(frames_id,NULL,0); if(*(int *)Decoded_Frames == -1) { perror("Error while attaching shared frames counter to mad_decoder"); if(shmctl(frames_id,IPC_RMID,NULL)) perror("Cannot destroy shared frames counter"); goto out; //exit(EXIT_FAILURE); } Decoded_Frames->is_http = 0; Decoded_Frames->is_file = 0; } else { ao_initialize(); check_default_play_device(); } if (!(options.opt & MPG321_REMOTE_PLAY)) { handle_signals(-1); /* initialize signal handler */ remote_input_buf[0] = '\0'; } if (!(options.opt & MPG321_QUIET_PLAY)) mpg123_boilerplate(); if (options.opt & MPG321_REMOTE_PLAY) { printf ("@R MPG123\n"); if(options.opt & MPG321_ENABLE_BUFFER) { #ifdef HAVE_ALSA init_alsa_volume_control("default"); /* For the moment use "default", it works on most of the systems. Tested in Debian,Fedora,Ubuntu,RedHat,CentOS,Gentoo */ if(options.volume != MAD_F_ONE) mpg321_alsa_set_volume((long)options.volume*volume_max/100); #endif } } /* Fork here. */ if(options.opt & MPG321_ENABLE_BUFFER) { output_pid = fork(); if(output_pid == -1) { perror("Error while forking output process"); goto out; /* Release shared memeory and semaphores */ // exit(EXIT_FAILURE); } if(output_pid == 0) { frame_buffer_p(); exit(EXIT_SUCCESS); } signal(SIGUSR1,handle_signals); if(!(options.opt & MPG321_REMOTE_PLAY)) { #ifdef HAVE_ALSA init_alsa_volume_control("default"); if(options.volume != MAD_F_ONE) mpg321_alsa_set_volume((long)options.volume*volume_max/100); #endif } } if( (options.volume != MAD_F_ONE) && !(options.opt & MPG321_ENABLE_BUFFER)) { options.volume = mad_f_tofixed((long)options.volume/100.0); } else{ options.volume = MAD_F_ONE; /* When using the buffer options.volume when decoding each frame should be equal to MAD_F_ONE */ // options.volume = mad_f_tofixed((long)100.0/100.0); } if (!(options.opt & MPG321_REMOTE_PLAY)) { if(options.opt & MPG321_ENABLE_BASIC) { /* Now create and detach the basic controls thread */ sem_init(&main_lock,0,0); pthread_create(&keyb_thread,NULL,read_keyb,NULL); pthread_detach(keyb_thread); } } if(set_xterm) { tty_control(); get_term_title(title); }else { if (!(options.opt & MPG321_REMOTE_PLAY)) { if (tcgetattr(0, &terminal_settings) < 0) perror("tcgetattr()"); memcpy(&old_terminal_settings, &terminal_settings, sizeof(struct termios)); /* Early thread start */ sem_post(&main_lock); } } /* Play the mpeg files or zip it! */ while((currentfile = get_next_file(pl, &playbuf))) { //printf("Current File: %s\n",currentfile); if (quit_now) break; signal(SIGINT, SIG_DFL); playbuf.buf = NULL; playbuf.fd = -1; playbuf.length = 0; playbuf.done = 0; playbuf.num_frames = 0; current_frame = 0; playbuf.max_frames = -1; strncpy(playbuf.filename,currentfile, PATH_MAX); playbuf.filename[PATH_MAX-1] = '\0'; if (status == MPG321_PLAYING || status == MPG321_STOPPED) file_change = 1; mad_timer_reset(&playbuf.duration); mad_timer_reset(¤t_time); id3struct = NULL; if (!(options.opt & MPG321_QUIET_PLAY) && file_change) { /* id3struct = id3_file_open (currentfile, ID3_FILE_MODE_READONLY);*/ if (id3struct == NULL) get_id3_info(currentfile, &id3struct, &id3tag); if(id3tag) show_id3(id3tag); } scrobbler_time = -1; if(options.opt & MPG321_USE_SCROBBLER) { if(id3struct == NULL) get_id3_info(currentfile,&id3struct,&id3tag); if (id3tag) { char emptystring[31], emptyyear[5] = " "; int i; if(parse_id3(scrobbler_args, id3tag)) { memset(emptystring, ' ', 30); emptystring[30] = '\0'; if((options.opt & MPG321_VERBOSE_PLAY) && (options.opt & MPG321_USE_SCROBBLER)) { fprintf(stderr, "\nPreparing for the AudioScrobbler:\n"); for(i = 0; i < 6; i++) { if(scrobbler_args[i] == NULL) scrobbler_args[i] = ( i == 3 ? emptyyear: emptystring); fprintf(stderr, "- %s\n", scrobbler_args[i]); } } } } } if (options.opt & MPG321_REMOTE_PLAY && file_change) { if(id3struct == NULL) get_id3_info(currentfile, &id3struct, &id3tag); if(id3tag) { if (!show_id3(id3tag)) { /* This shouldn't be necessary, but it appears that libid3tag doesn't necessarily know if there are no id3 tags on a given mp3 */ char * basec = strdup(currentfile); char * basen = basename(basec); char * dot = strrchr(basen, '.'); if (dot) *dot = '\0'; printf("@I %s\n", basen); free(basec); } } else { char * basec = strdup(currentfile); char * basen = basename(basec); char * dot = strrchr(basen, '.'); if (dot) *dot = '\0'; printf("@I %s\n", basen); free(basec); } } if(id3struct != NULL) id3_file_close(id3struct); /* Create the MPEG stream */ /* Check if source is on the network */ if((fd = raw_open(currentfile)) != 0 || (fd = http_open(currentfile)) != 0 || (fd = ftp_open(currentfile)) != 0) { playbuf.fd = fd; playbuf.buf = malloc(BUF_SIZE); playbuf.length = BUF_SIZE; if(options.opt & MPG321_ENABLE_BUFFER) { Decoded_Frames->is_http = 1; Decoded_Frames->is_file = 0; } calc_http_length(&playbuf); mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0, output, handle_error, /* message */ 0); } /* Check if we are to use stdin for input */ else if(strcmp(currentfile, "-") == 0) { playbuf.fd = fileno(stdin); playbuf.buf = malloc(BUF_SIZE); playbuf.length = BUF_SIZE; mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0, output, handle_error, /* message */ 0); } /* currentfile is a local file (presumably.) mmap() it */ else { struct stat stat; if((fd = open(currentfile, O_RDONLY)) == -1) { mpg321_error(currentfile); /* Restore TTY from keyboard reader thread */ if(options.opt & MPG321_ENABLE_BASIC) if (tcsetattr(0, TCSANOW, &old_terminal_settings) < 0) perror("tcsetattr ICANON"); if(set_xterm) { set_tty_restore(); osc_print(0,0,title); if (ctty) fclose(ctty); } if( options.opt & MPG321_REMOTE_PLAY) if(remote_restart) { clear_remote_file(pl); /* If restart is enabled, restart remote shell when file doesn't exist*/ continue; } if(options.opt & MPG321_ENABLE_BUFFER) goto out; else exit(1); /* mpg123 stops immediately if it can't open a file */ /* If sth goes wrong break!!!*/ break; } if(options.opt & MPG321_ENABLE_BUFFER) { Decoded_Frames->is_http = 0; Decoded_Frames->is_file = 1; } if(fstat(fd, &stat) == -1) { mpg321_error(currentfile); close(fd); continue; } if (!S_ISREG(stat.st_mode)) { if(S_ISFIFO(stat.st_mode)) { fallback = 1; goto fall_back_to_read_from_fd; } close(fd); continue; } retval = calc_length(currentfile, &playbuf); //FIXME Check also if it is an mp3 file. If not break and go to the next file possible if(retval < 0) { if(options.opt & MPG321_REMOTE_PLAY) { fprintf(stderr,"@E Corrupted file: %s\n",currentfile); close(fd); if(remote_restart) { clear_remote_file(pl); /* If restart is enabled, restart remote shell when file is corrupted */ continue; } break; } mpg321_error(currentfile); close(fd); // break; //FIXME Break and stop OR continue the playlist ???? continue; } if((options.opt & MPG321_VERBOSE_PLAY) && (options.opt & MPG321_USE_SCROBBLER)) fprintf(stderr, "Track duration: %ld seconds\n",playbuf.duration.seconds); if(options.opt & MPG321_USE_SCROBBLER) scrobbler_set_time(playbuf.duration.seconds); if ((options.maxframes != -1) && (options.maxframes <= playbuf.num_frames)) { playbuf.max_frames = options.maxframes; } playbuf.frames = malloc((playbuf.num_frames + 1) * sizeof(void*)); playbuf.times = malloc((playbuf.num_frames + 1) * sizeof(mad_timer_t)); #ifdef __uClinux__ if((playbuf.buf = mmap(0, playbuf.length, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) #else if((playbuf.buf = mmap(0, playbuf.length, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) #endif { mpg321_error(currentfile); continue; } playbuf.frames[0] = playbuf.buf; mad_decoder_init(&decoder, &playbuf, read_from_mmap, read_header, /*filter*/0, output, handle_error, /* message */ 0); fall_back_to_read_from_fd: //FIXME. Reported that on some embedded systems with low memory, less than 16MB doesn't work properly. if(fallback) { playbuf.fd = fd; playbuf.buf = malloc(BUF_SIZE); playbuf.length = BUF_SIZE; mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0, output, handle_error, /* message */ 0); fallback = 1; } } if(!(options.opt & MPG321_QUIET_PLAY))/*zip it!!!*/ { /* Because dirname might modify the argument */ char * dirc = strdup(currentfile); char * basec = strdup(currentfile); char * basen = basename(basec); char * dirn = dirname(dirc); /* make sure that the file has a pathname; otherwise don't print out a Directory: listing */ if(strchr(currentfile, '/') && strncmp(old_dir, dirn, PATH_MAX) != 0) { /* Print information about the file */ fprintf(stderr, "\n"); fprintf(stderr,"Directory: %s\n", dirn); strncpy(old_dir, dirn, PATH_MAX); old_dir[PATH_MAX-1] = '\0'; } /* print a newline between different songs only, not after Directory: listing */ else { fprintf(stderr, "\n"); } fprintf(stderr,"Playing MPEG stream from %s ...\n", basen); /* Printing xterm title */ if(set_xterm) { osc_print(0,0,basen); } free(dirc); free(basec); } signal(SIGINT, handle_signals); signal(SIGCHLD, handle_sigchld); /*Give control back so that we can implement SIG's*/ if(set_xterm) { set_tty_restore(); if (tcgetattr(0, &terminal_settings) < 0) perror("tcgetattr()"); memcpy(&old_terminal_settings, &terminal_settings, sizeof(struct termios)); /* disable canonical mode processing in the line discipline driver */ terminal_settings.c_lflag &= ~(ICANON | ECHO); /* apply our new settings */ if (tcsetattr(0, TCSANOW, &terminal_settings) < 0) perror("tcsetattr ICANON"); if(options.opt & MPG321_ENABLE_BASIC) { /* Late thread start */ sem_post(&main_lock); } } /* Every time the user gets us to rewind, we exit decoding, reinitialize it, and re-start it */ if(options.opt & MPG321_ENABLE_BUFFER) { Decoded_Frames->total_decoded_frames = 0; Decoded_Frames->done = 0; } while (1) { decoder.options |= MAD_OPTION_IGNORECRC; mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); if(options.opt & MPG321_ENABLE_BUFFER) { static struct sembuf start_sops = {2,-1,0}; semop(semarray,&start_sops,1); mad_decoder_position = 0; output_buffer_position = 0; union semun sem_ops; sem_ops.val = 0; semctl(semarray,2,SETVAL,sem_ops); Decoded_Frames->total_decoded_frames = 0; Decoded_Frames->done = 0; Decoded_Frames->is_http = 0; Decoded_Frames->is_file = 0; } /* if we're rewinding on an mmap()ed stream */ if(status == MPG321_REWINDING && playbuf.fd == -1) { mad_decoder_init(&decoder, &playbuf, read_from_mmap, read_header, /*filter*/0, output, /*error*/0, /* message */ 0); } else break; } if (!(options.opt & MPG321_QUIET_PLAY)) { char time_formatted[11]; mad_timer_string(current_time, time_formatted, "%.1u:%.2u", MAD_UNITS_MINUTES, MAD_UNITS_SECONDS, 0); fprintf(stderr," \r"); fprintf(stderr, "\n[%s] Decoding of %s finished.\n",time_formatted, basename(currentfile)); /* Report total decoded seconds. Maybe for the frame buffer report only total played time?? */ } if (options.opt & MPG321_REMOTE_PLAY && status == MPG321_STOPPED) { clear_remote_file(pl); } mad_decoder_finish(&decoder); if (playbuf.frames) free(playbuf.frames); if (playbuf.times) free(playbuf.times); if (playbuf.fd == -1) { munmap(playbuf.buf, playbuf.length); close(fd); } else { free(playbuf.buf); if (playbuf.fd != fileno(stdin)) close(playbuf.fd); } } if(!(options.opt & MPG321_ENABLE_BUFFER)) { if(playdevice) ao_close(playdevice); ao_shutdown(); } if (!(options.opt & MPG321_REMOTE_PLAY)) { if(options.opt & MPG321_ENABLE_BASIC) { pflag = 1; /* Restore TTY from keyboard reader thread */ if (tcsetattr(0, TCSANOW, &old_terminal_settings) < 0) perror("tcsetattr ICANON"); } } /*Restoring TTY*/ if(set_xterm) { set_tty_restore(); osc_print(0,0,title); if (ctty) fclose(ctty); } out: if(options.opt & MPG321_ENABLE_BUFFER) { if(kill(output_pid,SIGUSR1) == -1) perror("Error while stopping output process"); static int wstatus; wait(&wstatus); if(wstatus == -1) perror("Error while waiting for output process to exit"); if(semctl(semarray,0,IPC_RMID) == -1) perror("Error while destroying semaphores"); if(shmdt(Output_Queue) == -1) perror("Error while detaching shared buffer"); if(shmctl(shm_id,IPC_RMID,NULL)) perror("Cannot destroy shared buffer"); if(shmctl(frames_id,IPC_RMID,NULL)) perror("Cannot destroy shared buffer"); } return(0); }
/* 1 on success, 0 on failure */ int open_track(char *fname) { filept=-1; httpdata_reset(&htd); if(MPG123_OK != mpg123_param(mh, MPG123_ICY_INTERVAL, 0, 0)) error1("Cannot (re)set ICY interval: %s", mpg123_strerror(mh)); if(!strcmp(fname, "-")) { filept = STDIN_FILENO; #ifdef WIN32 _setmode(STDIN_FILENO, _O_BINARY); #endif return open_track_fd(); } else if (!strncmp(fname, "http://", 7)) /* http stream */ { #if defined (WANT_WIN32_SOCKETS) if(param.streamdump != NULL) { fprintf(stderr, "\nWarning: win32 networking conflicts with stream dumping. Aborting the dump.\n"); dump_close(); } /*Use recv instead of stdio functions */ win32_net_replace(mh); filept = win32_net_http_open(fname, &htd); #else filept = http_open(fname, &htd); #endif network_sockets_used = 1; /* utf-8 encoded URLs might not work under Win32 */ /* now check if we got sth. and if we got sth. good */ if( (filept >= 0) && (htd.content_type.p != NULL) && !APPFLAG(MPG123APP_IGNORE_MIME) && !(debunk_mime(htd.content_type.p) & IS_FILE) ) { error1("Unknown mpeg MIME type %s - is it perhaps a playlist (use -@)?", htd.content_type.p == NULL ? "<nil>" : htd.content_type.p); error("If you know the stream is mpeg1/2 audio, then please report this as "PACKAGE_NAME" bug"); return 0; } if(filept < 0) { error1("Access to http resource %s failed.", fname); return 0; } if(MPG123_OK != mpg123_param(mh, MPG123_ICY_INTERVAL, htd.icy_interval, 0)) error1("Cannot set ICY interval: %s", mpg123_strerror(mh)); if(param.verbose > 1) fprintf(stderr, "Info: ICY interval %li\n", (long)htd.icy_interval); } if(param.icy_interval > 0) { if(MPG123_OK != mpg123_param(mh, MPG123_ICY_INTERVAL, param.icy_interval, 0)) error1("Cannot set ICY interval: %s", mpg123_strerror(mh)); if(param.verbose > 1) fprintf(stderr, "Info: Forced ICY interval %li\n", param.icy_interval); } debug("OK... going to finally open."); /* Now hook up the decoder on the opened stream or the file. */ if(network_sockets_used) { return open_track_fd(); } else if(mpg123_open(mh, fname) != MPG123_OK) { error2("Cannot open %s: %s", fname, mpg123_strerror(mh)); return 0; } debug("Track successfully opened."); fresh = TRUE; return 1; }
SANE_Status bb_start_scan(struct ledm_session *ps) { char buf[4096] = {0}; char buf1[1024]={0}; int len, bytes_read, paper_status; int i, timeout = 10 ; char szPage_ID[5] = {0}; char szJob_ID[5] = {0}; SANE_Status stat = SANE_STATUS_IO_ERROR; struct bb_ledm_session *pbb = ps->bb_session; ps->user_cancel = 0; _DBG("bb_start_scan() entering...job_id=%d\n", ps->job_id); if (ps->job_id == 0) { if(http_open(ps->dd, HPMUD_S_LEDM_SCAN, &pbb->http_handle) != HTTP_R_OK) { _BUG("unable to open channel HPMUD_S_LEDM_SCAN \n"); goto bugout; } if (http_write(pbb->http_handle, GET_SCANNER_STATUS, sizeof(GET_SCANNER_STATUS)-1, timeout) != HTTP_R_OK) { _BUG("unable to GET_SCANNER_STATUS \n"); goto bugout; } read_http_payload(ps, buf, sizeof(buf), timeout, &bytes_read); if(!strstr(buf, SCANNER_IDLE)) { stat = SANE_STATUS_DEVICE_BUSY; goto bugout; } http_close(pbb->http_handle); pbb->http_handle = 0; if(http_open(ps->dd, HPMUD_S_LEDM_SCAN, &pbb->http_handle) != HTTP_R_OK) { _BUG("unable to open channel HPMUD_S_LEDM_SCAN \n"); goto bugout; } len = snprintf(buf, sizeof(buf), CREATE_SCAN_JOB_REQUEST, ps->currentResolution,//<XResolution> ps->currentResolution,//<YResolution> (int) (ps->currentTlx / 5548.7133),//<XStart> (int) ((ps->currentBrx / 5548.7133) - (ps->currentTlx / 5548.7133)),//<Width> (int) (ps->currentTly / 5548.7133),//<YStart> (int) ((ps->currentBry / 5548.7133) - (ps->currentTly / 5548.7133)),//<Height> "Jpeg",//<Format> (! strcmp(ce_element[ps->currentScanMode], "Color8")) ? "Color" : (! strcmp(ce_element[ps->currentScanMode], "Gray8")) ? "Gray" : "Gray",//<ColorSpace> ((! strcmp(ce_element[ps->currentScanMode], "Color8")) || (! strcmp(ce_element[ps->currentScanMode], "Gray8"))) ? 8: 8,//<BitDepth> ps->currentInputSource == IS_PLATEN ? is_element[1] : is_element[2],//<InputSource> ps->currentInputSource == IS_PLATEN ? is_element[1] : is_element[2],//<InputSourceType> ps->currentInputSource != IS_ADF_DUPLEX ? "" : "<AdfOptions><AdfOption>Duplex</AdfOption></AdfOptions>", (int)ps->currentBrightness,//<Brightness> (int)ps->currentContrast);//<Contrast> len = len + strlen(ZERO_FOOTER); len = snprintf(buf1, sizeof(buf1), POST_HEADER, len); if (http_write(pbb->http_handle, buf1, strlen(buf1), timeout) != HTTP_R_OK) { //goto bugout; } if (http_write(pbb->http_handle, buf, strlen(buf), 1) != HTTP_R_OK) { //goto bugout; } /* Write zero footer. */ if (http_write(pbb->http_handle, ZERO_FOOTER, sizeof(ZERO_FOOTER)-1, 1) != HTTP_R_OK) { //goto bugout; } memset(buf, 0, sizeof(buf)); /* Read response. */ if (read_http_payload(ps, buf, sizeof(buf), timeout, &bytes_read)) goto bugout; http_close(pbb->http_handle); pbb->http_handle = 0; char joblist[64]; char* jl=strstr(buf, "Location:"); if (!jl) goto bugout; jl=jl+10; int i=0; while(*jl != '\r') { joblist[i]=*jl; jl=jl+1; i++; } joblist[i]='\0'; strcpy(ps->url, joblist); char *c=ps->url; c=strstr(c, "JobList"); if (c) { c=c+8; int job_id=strtol(c, NULL, 10); itoa(job_id, szJob_ID,10); itoa(1, szPage_ID,10); ps->page_id = 1; ps->job_id = job_id; } } else { if (ps->currentInputSource == IS_PLATEN) { stat = SANE_STATUS_INVAL; goto bugout; } ps->page_id++; itoa(ps->job_id,szJob_ID,10); itoa(ps->page_id, szPage_ID,10); } _DBG("bb_start_scan() url=%s page_id=%d\n", ps->url, ps->page_id); memset(buf, 0, sizeof(buf)-1); if(http_open(ps->dd, HPMUD_S_LEDM_SCAN, &pbb->http_handle) != HTTP_R_OK) { _BUG("unable to open channel HPMUD_S_LEDM_SCAN \n"); goto bugout; } while(strstr(buf, READY_TO_UPLOAD) == NULL) { _DBG("bb_start_scan() ENTERING....buf=%s\n", buf); len = snprintf(buf, sizeof(buf), GET_SCAN_JOB_URL, ps->url); if (http_write(pbb->http_handle, buf, strlen(buf), 1) != HTTP_R_OK) { //goto bugout; break ; } if (read_http_payload (ps, buf, sizeof(buf), 5, &len) != HTTP_R_OK) { //goto bugout _DBG("bb_start_scan() read_http_payload FAILED len=%d buf=%s\n", len, buf); break; } //For a new scan, buf must contain <PreScanPage>. if (NULL == strstr(buf,PRESCANPAGE)) { //i.e Paper is not present in Scanner stat = SANE_STATUS_NO_DOCS; goto bugout; } if (strstr(buf,JOBSTATE_CANCELED) || strstr(buf, CANCELED_BY_DEVICE) || strstr(buf, CANCELED_BY_CLIENT)) { _DBG("bb_start_scan() SCAN CANCELLED\n"); stat = SANE_STATUS_GOOD; ps->user_cancel = 1; goto bugout; } if (strstr(buf, JOBSTATE_COMPLETED)) { stat = SANE_STATUS_GOOD; goto bugout; } usleep(500000);//0.5 sec delay }//end while() char *c = strstr(buf, "<BinaryURL>"); _DBG("bb_start_scan() BinaryURL=%s \n", c); if (!c) goto bugout; c +=11; char BinaryURL[30]; i = 0; while(*c != '<') { BinaryURL[i++] = *c ; c++; } BinaryURL[i] = '\0'; //_DBG("bb_start_scan() BinaryURL=%s\n", BinaryURL); len = snprintf(buf, sizeof(buf), GET_SCAN_JOB_URL, BinaryURL); if (http_write(pbb->http_handle, buf, strlen(buf), timeout) != HTTP_R_OK) { //goto bugout; } if (http_read_header(pbb->http_handle, buf, sizeof(buf), timeout, &len) != HTTP_R_OK) { //goto bugout; } if(strstr(buf, "HTTP/1.1 400 Bad Request")) http_read_header(pbb->http_handle, buf, sizeof(buf), timeout, &len); stat = SANE_STATUS_GOOD; bugout: if (stat && pbb->http_handle) { http_close(pbb->http_handle); /* error, close http connection */ pbb->http_handle = 0; } return stat; } /* bb_start_scan */
int main(int argc, char *argv[]) { int use_audio, use_video; int fullscreen; int scalesize; int scale_width, scale_height; int loop_play; int i, pause; int volume; Uint32 seek; float skip; int bilinear_filtering; SDL_Surface *screen = NULL; SMPEG *mpeg; SMPEG_Info info; char *basefile; const char *title = NULL; SDL_version sdlver; SMPEG_version smpegver; int fd; char buf[32]; int status; /* Get the command line options */ use_audio = 1; use_video = 1; fullscreen = 0; scalesize = 1; scale_width = 0; scale_height = 0; loop_play = 0; volume = 100; seek = 0; skip = 0; bilinear_filtering = 0; fd = 0; for ( i=1; argv[i] && (argv[i][0] == '-') && (argv[i][1] != 0); ++i ) { if ( (strcmp(argv[i], "--noaudio") == 0) || (strcmp(argv[i], "--nosound") == 0) ) { use_audio = 0; } else if ( strcmp(argv[i], "--novideo") == 0 ) { use_video = 0; } else if ( strcmp(argv[i], "--fullscreen") == 0 ) { fullscreen = 1; } else if ((strcmp(argv[i], "--double") == 0)||(strcmp(argv[i], "-2") == 0)) { scalesize = 2; } else if ((strcmp(argv[i], "--loop") == 0) || (strcmp(argv[i], "-l") == 0)) { loop_play = 1; } else if ( strcmp(argv[i], "--bilinear") == 0 ) { bilinear_filtering = 1; } else if ((strcmp(argv[i], "--seek") == 0)||(strcmp(argv[i], "-S") == 0)) { ++i; if ( argv[i] ) { seek = atol(argv[i]); } } else if ((strcmp(argv[i], "--skip") == 0)||(strcmp(argv[i], "-k") == 0)) { ++i; if ( argv[i] ) { skip = (float)atof(argv[i]); } } else if ((strcmp(argv[i], "--volume") == 0)||(strcmp(argv[i], "-v") == 0)) { ++i; if (i >= argc) { fprintf(stderr, "Please specify volume when using --volume or -v\n"); return(1); } if ( argv[i] ) { volume = atoi(argv[i]); } if ( ( volume < 0 ) || ( volume > 100 ) ) { fprintf(stderr, "Volume must be between 0 and 100\n"); volume = 100; } } else if ((strcmp(argv[i], "--title") == 0)||(strcmp(argv[i], "-t") == 0)) { ++i; if (i >= argc) { fprintf(stderr, "Please specify title when using --title or -t\n"); return(1); } if ( argv[i] ) { title = argv[i]; } } else if ((strcmp(argv[i], "--version") == 0) || (strcmp(argv[i], "-V") == 0)) { sdlver = *SDL_Linked_Version(); SMPEG_VERSION(&smpegver); printf("SDL version: %d.%d.%d\n" "SMPEG version: %d.%d.%d\n", sdlver.major, sdlver.minor, sdlver.patch, smpegver.major, smpegver.minor, smpegver.patch); return(0); } else if ((strcmp(argv[i], "--scale") == 0)||(strcmp(argv[i], "-s") == 0)) { ++i; if ( argv[i] ) { sscanf(argv[i], "%dx%d", &scale_width, &scale_height); } } else if ((strcmp(argv[i], "--help") == 0) || (strcmp(argv[i], "-h") == 0)) { usage(argv[0]); return(0); } else { fprintf(stderr, "Warning: Unknown option: %s\n", argv[i]); } } /* If there were no arguments just print the usage */ if (argc == 1) { usage(argv[0]); return(0); } #if defined(linux) || defined(__FreeBSD__) /* Plaympeg doesn't need a mouse */ putenv("SDL_NOMOUSE=1"); #endif /* Play the mpeg files! */ status = 0; for ( ; argv[i]; ++i ) { /* Initialize SDL */ if ( use_video ) { if ((SDL_Init(SDL_INIT_VIDEO) < 0) || !SDL_VideoDriverName(buf, 1)) { fprintf(stderr, "Warning: Couldn't init SDL video: %s\n", SDL_GetError()); fprintf(stderr, "Will ignore video stream\n"); use_video = 0; } } if ( use_audio ) { if ((SDL_Init(SDL_INIT_AUDIO) < 0) || !SDL_AudioDriverName(buf, 1)) { fprintf(stderr, "Warning: Couldn't init SDL audio: %s\n", SDL_GetError()); fprintf(stderr, "Will ignore audio stream\n"); use_audio = 0; } } /* Allow Ctrl-C when there's no video output */ signal(SIGINT, next_movie); /* Create the MPEG stream */ #ifdef NET_SUPPORT #ifdef RAW_SUPPORT /* Check if source is an IP address and port*/ if((fd = raw_open(argv[i])) != 0) mpeg = SMPEG_new_descr(fd, &info, use_audio); else #endif #ifdef HTTP_SUPPORT /* Check if source is an http URL */ if((fd = http_open(argv[i])) != 0) mpeg = SMPEG_new_descr(fd, &info, use_audio); else #endif #ifdef FTP_SUPPORT /* Check if source is an http URL */ if((fd = ftp_open(argv[i])) != 0) mpeg = SMPEG_new_descr(fd, &info, use_audio); else #endif #endif #ifdef VCD_SUPPORT /* Check if source is a CDROM device */ if((fd = vcd_open(argv[i])) != 0) mpeg = SMPEG_new_descr(fd, &info, use_audio); else #endif { if(strcmp(argv[i], "-") == 0) /* Use stdin for input */ mpeg = SMPEG_new_descr(0, &info, use_audio); else mpeg = SMPEG_new(argv[i], &info, use_audio); } if ( SMPEG_error(mpeg) ) { fprintf(stderr, "%s: %s\n", argv[i], SMPEG_error(mpeg)); SMPEG_delete(mpeg); status = -1; continue; } SMPEG_enableaudio(mpeg, use_audio); SMPEG_enablevideo(mpeg, use_video); SMPEG_setvolume(mpeg, volume); /* Enable software bilinear filtering, if desired */ if ( bilinear_filtering ) { SMPEG_Filter *filter; filter = SMPEGfilter_bilinear(); filter = SMPEG_filter( mpeg, filter ); filter->destroy(filter); } /* Print information about the video */ basefile = strrchr(argv[i], '/'); if ( basefile ) { ++basefile; } else { basefile = argv[i]; } if ( info.has_audio && info.has_video ) { printf("%s: MPEG system stream (audio/video)\n", basefile); } else if ( info.has_audio ) { printf("%s: MPEG audio stream\n", basefile); } else if ( info.has_video ) { printf("%s: MPEG video stream\n", basefile); } if ( info.has_video ) { printf("\tVideo %dx%d resolution\n", info.width, info.height); } if ( info.has_audio ) { printf("\tAudio %s\n", info.audio_string); } if ( info.total_size ) { printf("\tSize: %d\n", info.total_size); } if ( info.total_time ) { printf("\tTotal time: %f\n", info.total_time); } /* Set up video display if needed */ if ( info.has_video && use_video ) { const SDL_VideoInfo *video_info; Uint32 video_flags; int video_bpp; int width, height; /* Get the "native" video mode */ video_info = SDL_GetVideoInfo(); switch (video_info->vfmt->BitsPerPixel) { case 16: case 24: case 32: video_bpp = video_info->vfmt->BitsPerPixel; break; default: video_bpp = 16; break; } if ( scale_width ) { width = scale_width; } else { width = info.width; } width *= scalesize; if ( scale_height ) { height = scale_height; } else { height = info.height; } height *= scalesize; video_flags = SDL_SWSURFACE; if ( fullscreen ) { video_flags = SDL_FULLSCREEN|SDL_DOUBLEBUF|SDL_HWSURFACE; } video_flags |= SDL_ASYNCBLIT; video_flags |= SDL_RESIZABLE; screen = SDL_SetVideoMode(width, height, video_bpp, video_flags); if ( screen == NULL ) { fprintf(stderr, "Unable to set %dx%d video mode: %s\n", width, height, SDL_GetError()); continue; } if (title != NULL) { SDL_WM_SetCaption(title, title); } else { SDL_WM_SetCaption(argv[i], "plaympeg"); } if ( screen->flags & SDL_FULLSCREEN ) { SDL_ShowCursor(0); } SMPEG_setdisplay(mpeg, screen, NULL, update); SMPEG_scaleXY(mpeg, screen->w, screen->h); } else { SDL_QuitSubSystem(SDL_INIT_VIDEO); use_video = 0; } /* Set any special playback parameters */ if ( loop_play ) { SMPEG_loop(mpeg, 1); } /* Seek starting position */ if(seek) SMPEG_seek(mpeg, seek); /* Skip seconds to starting position */ if(skip) SMPEG_skip(mpeg, skip); /* Play it, and wait for playback to complete */ SMPEG_play(mpeg); done = 0; pause = 0; while ( ! done && ( pause || (SMPEG_status(mpeg) == SMPEG_PLAYING) ) ) { SDL_Event event; while ( use_video && SDL_PollEvent(&event) ) { switch (event.type) { case SDL_VIDEORESIZE: { SDL_Surface *old_screen = screen; SMPEG_pause(mpeg); screen = SDL_SetVideoMode(event.resize.w, event.resize.h, screen->format->BitsPerPixel, screen->flags); if ( old_screen != screen ) { SMPEG_setdisplay(mpeg, screen, NULL, update); } SMPEG_scaleXY(mpeg, screen->w, screen->h); SMPEG_pause(mpeg); } break; case SDL_KEYDOWN: if ( (event.key.keysym.sym == SDLK_ESCAPE) || (event.key.keysym.sym == SDLK_q) ) { // Quit done = 1; } else if ( event.key.keysym.sym == SDLK_RETURN ) { // toggle fullscreen if ( event.key.keysym.mod & KMOD_ALT ) { SDL_WM_ToggleFullScreen(screen); fullscreen = (screen->flags & SDL_FULLSCREEN); SDL_ShowCursor(!fullscreen); } } else if ( event.key.keysym.sym == SDLK_UP ) { // Volume up if ( volume < 100 ) { if ( event.key.keysym.mod & KMOD_SHIFT ) { // 10+ volume += 10; } else if ( event.key.keysym.mod & KMOD_CTRL ) { // 100+ volume = 100; } else { // 1+ volume++; } if ( volume > 100 ) volume = 100; SMPEG_setvolume(mpeg, volume); } } else if ( event.key.keysym.sym == SDLK_DOWN ) { // Volume down if ( volume > 0 ) { if ( event.key.keysym.mod & KMOD_SHIFT ) { volume -= 10; } else if ( event.key.keysym.mod & KMOD_CTRL ) { volume = 0; } else { volume--; } if ( volume < 0 ) volume = 0; SMPEG_setvolume(mpeg, volume); } } else if ( event.key.keysym.sym == SDLK_PAGEUP ) { // Full volume volume = 100; SMPEG_setvolume(mpeg, volume); } else if ( event.key.keysym.sym == SDLK_PAGEDOWN ) { // Volume off volume = 0; SMPEG_setvolume(mpeg, volume); } else if ( event.key.keysym.sym == SDLK_SPACE ) { // Toggle play / pause if ( SMPEG_status(mpeg) == SMPEG_PLAYING ) { SMPEG_pause(mpeg); pause = 1; } else { SMPEG_play(mpeg); pause = 0; } } else if ( event.key.keysym.sym == SDLK_RIGHT ) { // Forward if ( event.key.keysym.mod & KMOD_SHIFT ) { SMPEG_skip(mpeg, 100); } else if ( event.key.keysym.mod & KMOD_CTRL ) { SMPEG_skip(mpeg, 50); } else { SMPEG_skip(mpeg, 5); } } else if ( event.key.keysym.sym == SDLK_LEFT ) { // Reverse if ( event.key.keysym.mod & KMOD_SHIFT ) { } else if ( event.key.keysym.mod & KMOD_CTRL ) { } else { } } else if ( event.key.keysym.sym == SDLK_KP_MINUS ) { // Scale minus if ( scalesize > 1 ) { scalesize--; } } else if ( event.key.keysym.sym == SDLK_KP_PLUS ) { // Scale plus scalesize++; } else if ( event.key.keysym.sym == SDLK_f ) { // Toggle filtering on/off if ( bilinear_filtering ) { SMPEG_Filter *filter = SMPEGfilter_null(); filter = SMPEG_filter( mpeg, filter ); filter->destroy(filter); bilinear_filtering = 0; } else { SMPEG_Filter *filter = SMPEGfilter_bilinear(); filter = SMPEG_filter( mpeg, filter ); filter->destroy(filter); bilinear_filtering = 1; } } break; case SDL_QUIT: done = 1; break; default: break; } } SDL_Delay(1000/2); } SMPEG_delete(mpeg); } SDL_Quit(); #if defined(RAW_SUPPORT) || defined(HTTP_SUPPORT) || defined(FTP_SUPPORT) || \ defined(VCD_SUPPORT) if(fd) close(fd); #endif return(status); }
/* Construct an OCSP request, send it to the configured OCSP responder and parse the response. On success the OCSP context may be used to further process the reponse. */ static gpg_error_t do_ocsp_request (ctrl_t ctrl, ksba_ocsp_t ocsp, gcry_md_hd_t md, const char *url, ksba_cert_t cert, ksba_cert_t issuer_cert) { gpg_error_t err; unsigned char *request, *response; size_t requestlen, responselen; http_t http; ksba_ocsp_response_status_t response_status; const char *t; int redirects_left = 2; char *free_this = NULL; (void)ctrl; if (opt.disable_http) { log_error (_("OCSP request not possible due to disabled HTTP\n")); return gpg_error (GPG_ERR_NOT_SUPPORTED); } err = ksba_ocsp_add_target (ocsp, cert, issuer_cert); if (err) { log_error (_("error setting OCSP target: %s\n"), gpg_strerror (err)); return err; } { size_t n; unsigned char nonce[32]; n = ksba_ocsp_set_nonce (ocsp, NULL, 0); if (n > sizeof nonce) n = sizeof nonce; gcry_create_nonce (nonce, n); ksba_ocsp_set_nonce (ocsp, nonce, n); } err = ksba_ocsp_build_request (ocsp, &request, &requestlen); if (err) { log_error (_("error building OCSP request: %s\n"), gpg_strerror (err)); return err; } once_more: err = http_open (&http, HTTP_REQ_POST, url, NULL, (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0), opt.http_proxy, NULL, NULL, NULL); if (err) { log_error (_("error connecting to '%s': %s\n"), url, gpg_strerror (err)); xfree (free_this); return err; } es_fprintf (http_get_write_ptr (http), "Content-Type: application/ocsp-request\r\n" "Content-Length: %lu\r\n", (unsigned long)requestlen ); http_start_data (http); if (es_fwrite (request, requestlen, 1, http_get_write_ptr (http)) != 1) { err = gpg_error_from_errno (errno); log_error ("error sending request to '%s': %s\n", url, strerror (errno)); http_close (http, 0); xfree (request); xfree (free_this); return err; } xfree (request); request = NULL; err = http_wait_response (http); if (err || http_get_status_code (http) != 200) { if (err) log_error (_("error reading HTTP response for '%s': %s\n"), url, gpg_strerror (err)); else { switch (http_get_status_code (http)) { case 301: case 302: { const char *s = http_get_header (http, "Location"); log_info (_("URL '%s' redirected to '%s' (%u)\n"), url, s?s:"[none]", http_get_status_code (http)); if (s && *s && redirects_left-- ) { xfree (free_this); url = NULL; free_this = xtrystrdup (s); if (!free_this) err = gpg_error_from_errno (errno); else { url = free_this; http_close (http, 0); goto once_more; } } else err = gpg_error (GPG_ERR_NO_DATA); log_error (_("too many redirections\n")); } break; default: log_error (_("error accessing '%s': http status %u\n"), url, http_get_status_code (http)); err = gpg_error (GPG_ERR_NO_DATA); break; } } http_close (http, 0); xfree (free_this); return err; } err = read_response (http_get_read_ptr (http), &response, &responselen); http_close (http, 0); if (err) { log_error (_("error reading HTTP response for '%s': %s\n"), url, gpg_strerror (err)); xfree (free_this); return err; } err = ksba_ocsp_parse_response (ocsp, response, responselen, &response_status); if (err) { log_error (_("error parsing OCSP response for '%s': %s\n"), url, gpg_strerror (err)); xfree (response); xfree (free_this); return err; } switch (response_status) { case KSBA_OCSP_RSPSTATUS_SUCCESS: t = "success"; break; case KSBA_OCSP_RSPSTATUS_MALFORMED: t = "malformed"; break; case KSBA_OCSP_RSPSTATUS_INTERNAL: t = "internal error"; break; case KSBA_OCSP_RSPSTATUS_TRYLATER: t = "try later"; break; case KSBA_OCSP_RSPSTATUS_SIGREQUIRED: t = "must sign request"; break; case KSBA_OCSP_RSPSTATUS_UNAUTHORIZED: t = "unauthorized"; break; case KSBA_OCSP_RSPSTATUS_REPLAYED: t = "replay detected"; break; case KSBA_OCSP_RSPSTATUS_OTHER: t = "other (unknown)"; break; case KSBA_OCSP_RSPSTATUS_NONE: t = "no status"; break; default: t = "[unknown status]"; break; } if (response_status == KSBA_OCSP_RSPSTATUS_SUCCESS) { if (opt.verbose) log_info (_("OCSP responder at '%s' status: %s\n"), url, t); err = ksba_ocsp_hash_response (ocsp, response, responselen, HASH_FNC, md); if (err) log_error (_("hashing the OCSP response for '%s' failed: %s\n"), url, gpg_strerror (err)); } else { log_error (_("OCSP responder at '%s' status: %s\n"), url, t); err = gpg_error (GPG_ERR_GENERAL); } xfree (response); xfree (free_this); return err; }
/* Get the key from URL which is expected to specify a http style scheme. On success R_FP has an open stream to read the data. */ gpg_error_t ks_http_fetch (ctrl_t ctrl, const char *url, estream_t *r_fp) { gpg_error_t err; http_session_t session = NULL; http_t http = NULL; int redirects_left = MAX_REDIRECTS; estream_t fp = NULL; char *request_buffer = NULL; err = http_session_new (&session, NULL); if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); *r_fp = NULL; once_more: err = http_open (&http, HTTP_REQ_GET, url, /* httphost */ NULL, /* fixme: AUTH */ NULL, 0, /* fixme: proxy*/ NULL, session, NULL, /*FIXME curl->srvtag*/NULL); if (!err) { fp = http_get_write_ptr (http); /* Avoid caches to get the most recent copy of the key. We set both the Pragma and Cache-Control versions of the header, so we're good with both HTTP 1.0 and 1.1. */ es_fputs ("Pragma: no-cache\r\n" "Cache-Control: no-cache\r\n", fp); http_start_data (http); if (es_ferror (fp)) err = gpg_error_from_syserror (); } if (err) { /* Fixme: After a redirection we show the old host name. */ log_error (_("error connecting to '%s': %s\n"), url, gpg_strerror (err)); goto leave; } /* Wait for the response. */ dirmngr_tick (ctrl); err = http_wait_response (http); if (err) { log_error (_("error reading HTTP response for '%s': %s\n"), url, gpg_strerror (err)); goto leave; } switch (http_get_status_code (http)) { case 200: err = 0; break; /* Success. */ case 301: case 302: case 307: { const char *s = http_get_header (http, "Location"); log_info (_("URL '%s' redirected to '%s' (%u)\n"), url, s?s:"[none]", http_get_status_code (http)); if (s && *s && redirects_left-- ) { xfree (request_buffer); request_buffer = xtrystrdup (s); if (request_buffer) { url = request_buffer; http_close (http, 0); http = NULL; goto once_more; } err = gpg_error_from_syserror (); } else err = gpg_error (GPG_ERR_NO_DATA); log_error (_("too many redirections\n")); } goto leave; default: log_error (_("error accessing '%s': http status %u\n"), url, http_get_status_code (http)); err = gpg_error (GPG_ERR_NO_DATA); goto leave; } fp = http_get_read_ptr (http); if (!fp) { err = gpg_error (GPG_ERR_BUG); goto leave; } /* Return the read stream and close the HTTP context. */ *r_fp = fp; http_close (http, 1); http = NULL; leave: http_close (http, 0); http_session_release (session); xfree (request_buffer); return err; }
/* HTTP Functions */ int http_parse(http_t *http, char ch) { int mode = 0; if (http->mode < MD_POST) { if (ch == '\r') return 0; if (ch == ' ' && http->idx == 0) return 0; } switch (http->mode) { /* HTTP Parsing */ case MD_METHOD: if (ch == ' ') http_mode(http, MD_PATH, http->req_method); else if (http->idx < MAX_METHOD) http->req_method[http->idx++] = ch; return 0; case MD_PATH: if (ch == ' ') http_mode(http, MD_VERSION, http->req_path); else if (http->idx < MAX_PATH) http->req_path[http->idx++] = ch; return 0; case MD_VERSION: if (ch == '\n') { http_mode(http, MD_FIELD, http->req_version); http_open(http, http->req_method, http->req_path, http->req_version); } else if (http->idx < MAX_VERSION) http->req_version[http->idx++] = ch; return 0; case MD_FIELD: if (ch == '\n') { mode = http_body(http); http_mode(http, mode, http->hdr_field); switch (mode) { case MD_METHOD: return HTTP_DONE; case MD_SOCK: return HTTP_SOCK; case MD_POST: return HTTP_POST; } } else if (ch == ':') http_mode(http, MD_VALUE, http->hdr_field); else if (http->idx < MAX_FIELD) http->hdr_field[http->idx++] = ch; return 0; case MD_VALUE: if (ch == '\n') { http_mode(http, MD_FIELD, http->hdr_value); http_head(http, http->hdr_field, http->hdr_value); } else if (http->idx < MAX_VALUE) http->hdr_value[http->idx++] = ch; return 0; case MD_POST: return 0; case MD_SOCK: return 0; default: return 0; } }
CURLcode curl_easy_perform(CURL *curl) { int rc; CURLcode err=CURLE_OK; const char *errstr=NULL; char *proxy=NULL; struct http_srv srv; memset(&srv,0,sizeof(srv)); /* Emulate the libcurl proxy behavior. If the calling program set a proxy, use it. If it didn't set a proxy or set it to NULL, check for one in the environment. If the calling program explicitly set a null-string proxy the http code doesn't use a proxy at all. */ if(curl->proxy) proxy=curl->proxy; else proxy=getenv(HTTP_PROXY_ENV); if(curl->srvtag) srv.srvtag=curl->srvtag; if(curl->flags.verbose) { fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null"); fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url); if(srv.srvtag) fprintf(curl->errors, "* SRV tag is \"%s\": host and port may be overridden\n", srv.srvtag); fprintf(curl->errors,"* HTTP auth is \"%s\"\n", curl->auth?curl->auth:"null"); fprintf(curl->errors,"* HTTP method is %s\n", curl->flags.post?"POST":"GET"); } if(curl->flags.post) { rc=http_open(&curl->hd,HTTP_REQ_POST,curl->url,curl->auth,0,proxy, &srv,curl->headers?curl->headers->list:NULL); if(rc==0) { char content_len[50]; unsigned int post_len=strlen(curl->postfields); if(curl->flags.verbose && srv.used_server && srv.used_port) fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n", srv.used_server, srv.used_port); iobuf_writestr(curl->hd.fp_write, "Content-Type: application/x-www-form-urlencoded\r\n"); sprintf(content_len,"Content-Length: %u\r\n",post_len); iobuf_writestr(curl->hd.fp_write,content_len); http_start_data(&curl->hd); iobuf_write(curl->hd.fp_write,curl->postfields,post_len); rc=http_wait_response(&curl->hd,&curl->status); if(rc==0 && curl->flags.failonerror && curl->status>=300) err=CURLE_HTTP_RETURNED_ERROR; } } else { rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,curl->auth,0,proxy, &srv,curl->headers?curl->headers->list:NULL); if(rc==0) { if(curl->flags.verbose && srv.used_server && srv.used_port) fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n", srv.used_server, srv.used_port); rc=http_wait_response(&curl->hd,&curl->status); if(rc==0) { if(curl->flags.failonerror && curl->status>=300) err=CURLE_HTTP_RETURNED_ERROR; else { unsigned int maxlen=1024,buflen,len; byte *line=NULL; while((len=iobuf_read_line(curl->hd.fp_read, &line,&buflen,&maxlen))) { size_t ret; maxlen=1024; ret=(curl->writer)(line,len,1,curl->file); if(ret!=len) { err=CURLE_WRITE_ERROR; break; } } xfree(line); http_close(&curl->hd); } } else http_close(&curl->hd); } } free (srv.used_server); switch(rc) { case 0: break; case G10ERR_INVALID_URI: err=CURLE_UNSUPPORTED_PROTOCOL; break; case G10ERR_NETWORK: errstr=strerror(errno); err=CURLE_COULDNT_CONNECT; break; default: errstr=g10_errstr(rc); err=CURLE_COULDNT_CONNECT; break; } return handle_error(curl,err,errstr); }
/* Send an HTTP request. On success returns an estream object at R_FP. HOSTPORTSTR is only used for diagnostics. If HTTPHOST is not NULL it will be used as HTTP "Host" header. If POST_CB is not NULL a post request is used and that callback is called to allow writing the post data. */ static gpg_error_t send_request (ctrl_t ctrl, const char *request, const char *hostportstr, const char *httphost, unsigned int httpflags, gpg_error_t (*post_cb)(void *, http_t), void *post_cb_value, estream_t *r_fp) { gpg_error_t err; http_session_t session = NULL; http_t http = NULL; int redirects_left = MAX_REDIRECTS; estream_t fp = NULL; char *request_buffer = NULL; *r_fp = NULL; err = http_session_new (&session, NULL); if (err) goto leave; http_session_set_log_cb (session, cert_log_cb); once_more: err = http_open (&http, post_cb? HTTP_REQ_POST : HTTP_REQ_GET, request, httphost, /* fixme: AUTH */ NULL, (httpflags | (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0)), ctrl->http_proxy, session, NULL, /*FIXME curl->srvtag*/NULL); if (!err) { fp = http_get_write_ptr (http); /* Avoid caches to get the most recent copy of the key. We set both the Pragma and Cache-Control versions of the header, so we're good with both HTTP 1.0 and 1.1. */ es_fputs ("Pragma: no-cache\r\n" "Cache-Control: no-cache\r\n", fp); if (post_cb) err = post_cb (post_cb_value, http); if (!err) { http_start_data (http); if (es_ferror (fp)) err = gpg_error_from_syserror (); } } if (err) { /* Fixme: After a redirection we show the old host name. */ log_error (_("error connecting to '%s': %s\n"), hostportstr, gpg_strerror (err)); goto leave; } /* Wait for the response. */ dirmngr_tick (ctrl); err = http_wait_response (http); if (err) { log_error (_("error reading HTTP response for '%s': %s\n"), hostportstr, gpg_strerror (err)); goto leave; } if (http_get_tls_info (http, NULL)) { /* Update the httpflags so that a redirect won't fallback to an unencrypted connection. */ httpflags |= HTTP_FLAG_FORCE_TLS; } switch (http_get_status_code (http)) { case 200: err = 0; break; /* Success. */ case 301: case 302: case 307: { const char *s = http_get_header (http, "Location"); log_info (_("URL '%s' redirected to '%s' (%u)\n"), request, s?s:"[none]", http_get_status_code (http)); if (s && *s && redirects_left-- ) { xfree (request_buffer); request_buffer = xtrystrdup (s); if (request_buffer) { request = request_buffer; http_close (http, 0); http = NULL; goto once_more; } err = gpg_error_from_syserror (); } else err = gpg_error (GPG_ERR_NO_DATA); log_error (_("too many redirections\n")); } goto leave; default: log_error (_("error accessing '%s': http status %u\n"), request, http_get_status_code (http)); err = gpg_error (GPG_ERR_NO_DATA); goto leave; } /* FIXME: We should register a permanent redirection and whether a host has ever used TLS so that future calls will always use TLS. */ fp = http_get_read_ptr (http); if (!fp) { err = gpg_error (GPG_ERR_BUG); goto leave; } /* Return the read stream and close the HTTP context. */ *r_fp = fp; http_close (http, 1); http = NULL; leave: http_close (http, 0); http_session_release (session); xfree (request_buffer); return err; }
int main(int argc, char *argv[]) { char *url; char data[1024], response[4096]; int i, ret, size; HTTP_INFO hi1, hi2; // Init http session. verify: check the server CA cert. http_init(&hi1, FALSE); http_init(&hi2, TRUE); /* url = "https://localhost:8080/upload"; sprintf(data, "--1234567890abcdef\r\n" "Content-Disposition: form-data; name=\"upload\"; filename=\"test.txt\"\r\n" "Content-Type: text/plain\r\n\r\n" "test message\r\n" "--1234567890abcdef--\r\n\r\n" ); ret = http_post(&hi1, url, data, response, sizeof(response)); printf("return code: %d \n", ret); printf("return body: %s \n", response); */ url = "https://localhost:8080/upload"; if(http_open(&hi1, url) < 0) { http_strerror(data, 1024); printf("socket error: %s \n", data); goto error; } snprintf(hi1.request.method, 8, "POST"); hi1.request.close = FALSE; hi1.request.chunked = FALSE; snprintf(hi1.request.content_type, 256, "multipart/form-data; boundary=1234567890abcdef"); size = sprintf(data, "--1234567890abcdef\r\n" "Content-Disposition: form-data; name=\"upload\"; filename=\"test.txt\"\r\n" "Content-Type: text/plain\r\n\r\n" "test message\r\n" "--1234567890abcdef--\r\n" ); hi1.request.content_length = size; if(http_write_header(&hi1) < 0) { http_strerror(data, 1024); printf("socket error: %s \n", data); goto error; } if(http_write(&hi1, data, size) != size) { http_strerror(data, 1024); printf("socket error: %s \n", data); goto error; } // Write end-chunked if(http_write_end(&hi1) < 0) { http_strerror(data, 1024); printf("socket error: %s \n", data); goto error; } ret = http_read_chunked(&hi1, response, sizeof(response)); printf("return code: %d \n", ret); printf("return body: %s \n", response); /* // Test a http get method. url = "http://httpbin.org/get?message=https_client"; ret = http_get(&hi1, url, response, sizeof(response)); printf("return code: %d \n", ret); printf("return body: %s \n", response); // Test a http post method. url = "http://httpbin.org/post"; sprintf(data, "{\"message\":\"Hello, https_client!\"}"); ret = http_post(&hi1, url, data, response, sizeof(response)); printf("return code: %d \n", ret); printf("return body: %s \n", response); // Test a https get method. url = "https://httpbin.org/get?message=https_client"; ret = http_get(&hi2, url, response, sizeof(response)); printf("return code: %d \n", ret); printf("return body: %s \n", response); // Test a https post method. url = "https://httpbin.org/post"; sprintf(data, "{\"message\":\"Hello, https_client!\"}"); ret = http_post(&hi2, url, data, response, sizeof(response)); printf("return code: %d \n", ret); printf("return body: %s \n", response); // Test a https post with the chunked-encoding data. url = "https://httpbin.org/post"; if(http_open_chunked(&hi2, url) == 0) { size = sprintf(data, "[{\"message\":\"Hello, https_client %d\"},", 0); if(http_write_chunked(&hi2, data, size) != size) { http_strerror(data, 1024); printf("socket error: %s \n", data); goto error; } for(i=1; i<4; i++) { size = sprintf(data, "{\"message\":\"Hello, https_client %d\"},", i); if(http_write_chunked(&hi2, data, size) != size) { http_strerror(data, 1024); printf("socket error: %s \n", data); goto error; } } size = sprintf(data, "{\"message\":\"Hello, https_client %d\"}]", i); if(http_write_chunked(&hi2, data, strlen(data)) != size) { http_strerror(data, 1024); printf("socket error: %s \n", data); goto error; } ret = http_read_chunked(&hi2, response, sizeof(response)); printf("return code: %d \n", ret); printf("return body: %s \n", response); } else { http_strerror(data, 1024); printf("socket error: %s \n", data); } error: */ error: http_close(&hi1); http_close(&hi2); return 0; }
// read from a web server connection int http_read(dev_file_t *f, var_t *var_p) { char rxbuff[1024]; int inHeader = 1; int httpOK = 0; v_free(var_p); var_p->type = V_STR; var_p->v.p.ptr = 0; var_p->v.p.size = 0; while (1) { int bytes = net_read(f->handle, (char *) rxbuff, sizeof(rxbuff)); if (bytes == 0) { break; // no more data } // assumes http header < 1024 bytes if (inHeader) { int i = 0; while (1) { int iattr = i; while (rxbuff[i] != 0 && rxbuff[i] != '\n') { i++; } if (rxbuff[i] == 0) { inHeader = 0; break; // no end delimiter } if (rxbuff[i + 2] == '\n') { var_p->v.p.size = bytes - i - 3; var_p->v.p.ptr = malloc(var_p->v.p.size + 1); memcpy(var_p->v.p.ptr, rxbuff + i + 3, var_p->v.p.size); var_p->v.p.ptr[var_p->v.p.size] = 0; inHeader = 0; break; // found start of content } // null terminate attribute (in \r) rxbuff[i - 1] = 0; i++; if (strstr(rxbuff + iattr, "200 OK") != 0) { httpOK = 1; } if (strncmp(rxbuff + iattr, "Location: ", 10) == 0) { // handle redirection sockcl_close(f); strcpy(f->name, rxbuff + iattr + 10); if (http_open(f) == 0) { return 0; } break; // scan next header } } } else { var_p->v.p.ptr = realloc(var_p->v.p.ptr, var_p->v.p.size + bytes + 1); memcpy(var_p->v.p.ptr + var_p->v.p.size, rxbuff, bytes); var_p->v.p.size += bytes; var_p->v.p.ptr[var_p->v.p.size] = 0; } } return httpOK; }
int main(int argc, char *argv[]) { int fd = 0; char *currentfile, old_dir[PATH_MAX]; playlist *pl = NULL; struct id3_file *id3struct = NULL; struct id3_tag *id3tag = NULL; buffer playbuf; struct mad_decoder decoder; old_dir[0] = '\0'; playbuf.pl = pl = new_playlist(); if (!pl) { fprintf(stderr, "malloc failed at startup!\n"); exit(1); } options.volume = MAD_F_ONE; status = MPG321_PLAYING; /* Get the command line options */ parse_options(argc, argv, pl); /* If there were no files and no playlist specified just print the usage */ if (!playlist_file && optind == argc) { usage(argv[0]); exit(0); } if (playlist_file) load_playlist(pl, playlist_file); add_cmdline_files(pl, argv); if (shuffle_play) shuffle_files(pl); ao_initialize(); check_default_play_device(); if (!(options.opt & MPG321_REMOTE_PLAY)) { handle_signals(-1); /* initialize signal handler */ remote_input_buf[0] = '\0'; } if (!(options.opt & MPG321_QUIET_PLAY)) mpg123_boilerplate(); if (options.opt & MPG321_REMOTE_PLAY) { printf ("@R MPG123\n"); } /* Play the mpeg files or zip it! */ while((currentfile = get_next_file(pl, &playbuf))) { if (quit_now) break; signal(SIGINT, SIG_DFL); playbuf.buf = NULL; playbuf.fd = -1; playbuf.length = 0; playbuf.done = 0; playbuf.num_frames = 0; playbuf.max_frames = -1; strncpy(playbuf.filename,currentfile, PATH_MAX); playbuf.filename[PATH_MAX-1] = '\0'; if (status == MPG321_PLAYING) file_change = 1; mad_timer_reset(&playbuf.duration); mad_timer_reset(¤t_time); if (!(options.opt & MPG321_QUIET_PLAY) && file_change) { id3struct = id3_file_open (currentfile, ID3_FILE_MODE_READONLY); if (id3struct) { id3tag = id3_file_tag (id3struct); if (id3tag) { show_id3 (id3tag); } id3_file_close (id3struct); } } if (options.opt & MPG321_REMOTE_PLAY && file_change) { id3struct = id3_file_open (currentfile, ID3_FILE_MODE_READONLY); if (id3struct) { id3tag = id3_file_tag (id3struct); if (id3tag) { if (!show_id3(id3tag)) { /* This shouldn't be necessary, but it appears that libid3tag doesn't necessarily know if there are no id3 tags on a given mp3 */ char * basec = strdup(currentfile); char * basen = basename(basec); char * dot = strrchr(basen, '.'); if (dot) *dot = '\0'; printf("@I %s\n", basen); free(basec); } } else { fprintf(stderr, "Allocation error"); exit(1); } id3_file_close (id3struct); } else { char * basec = strdup(currentfile); char * basen = basename(basec); char * dot = strrchr(basen, '.'); if (dot) *dot = '\0'; printf("@I %s\n", basen); free(basec); } } /* Create the MPEG stream */ /* Check if source is on the network */ if((fd = raw_open(currentfile)) != 0 || (fd = http_open(currentfile)) != 0 || (fd = ftp_open(currentfile)) != 0) { playbuf.fd = fd; playbuf.buf = malloc(BUF_SIZE); playbuf.length = BUF_SIZE; mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0, output, /*error*/0, /* message */ 0); } /* Check if we are to use stdin for input */ else if(strcmp(currentfile, "-") == 0) { playbuf.fd = fileno(stdin); playbuf.buf = malloc(BUF_SIZE); playbuf.length = BUF_SIZE; mad_decoder_init(&decoder, &playbuf, read_from_fd, read_header, /*filter*/0, output, /*error*/0, /* message */ 0); } /* currentfile is a local file (presumably.) mmap() it */ else { struct stat stat; if((fd = open(currentfile, O_RDONLY)) == -1) { mpg321_error(currentfile); /* mpg123 stops immediately if it can't open a file */ break; } if(fstat(fd, &stat) == -1) { close(fd); mpg321_error(currentfile); continue; } if (!S_ISREG(stat.st_mode)) { close(fd); continue; } calc_length(currentfile, &playbuf); if ((options.maxframes != -1) && (options.maxframes <= playbuf.num_frames)) { playbuf.max_frames = options.maxframes; } playbuf.frames = malloc((playbuf.num_frames + 1) * sizeof(void*)); playbuf.times = malloc((playbuf.num_frames + 1) * sizeof(mad_timer_t)); if((playbuf.buf = mmap(0, playbuf.length, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) { close(fd); mpg321_error(currentfile); continue; } close(fd); playbuf.frames[0] = playbuf.buf; mad_decoder_init(&decoder, &playbuf, read_from_mmap, read_header, /*filter*/0, output, /*error*/0, /* message */ 0); } if(!(options.opt & MPG321_QUIET_PLAY))/*zip it!!!*/ { /* Because dirname might modify the argument */ char * dirc = strdup(currentfile); char * basec = strdup(currentfile); char * basen = basename(basec); char * dirn = dirname(dirc); /* make sure that the file has a pathname; otherwise don't print out a Directory: listing */ if(strchr(currentfile, '/') && strncmp(old_dir, dirn, PATH_MAX) != 0) { /* Print information about the file */ fprintf(stderr, "\n"); fprintf(stderr,"Directory: %s/\n", dirn); strncpy(old_dir, dirn, PATH_MAX); old_dir[PATH_MAX-1] = '\0'; } /* print a newline between different songs only, not after Directory: listing */ else { fprintf(stderr, "\n"); } fprintf(stderr,"Playing MPEG stream from %s ...\n", basen); free(dirc); free(basec); } signal(SIGINT, handle_signals); /* Every time the user gets us to rewind, we exit decoding, reinitialize it, and re-start it */ while (1) { mad_decoder_run(&decoder, MAD_DECODER_MODE_SYNC); /* if we're rewinding on an mmap()ed stream */ if(status == MPG321_REWINDING && playbuf.fd == -1) { mad_decoder_init(&decoder, &playbuf, read_from_mmap, read_header, /*filter*/0, output, /*error*/0, /* message */ 0); } else break; } if (!(options.opt & MPG321_QUIET_PLAY)) { char time_formatted[11]; mad_timer_string(current_time, time_formatted, "%.1u:%.2u", MAD_UNITS_MINUTES, MAD_UNITS_SECONDS, 0); fprintf(stderr, "\n[%s] Decoding of %s finished.\n",time_formatted, basename(currentfile)); } if (options.opt & MPG321_REMOTE_PLAY && status == MPG321_STOPPED) { clear_remote_file(pl); } mad_decoder_finish(&decoder); if (quit_now) break; if (playbuf.frames) free(playbuf.frames); if (playbuf.times) free(playbuf.times); if (playbuf.fd == -1) { munmap(playbuf.buf, playbuf.length); } else { free(playbuf.buf); if (playbuf.fd != fileno(stdin)) close(playbuf.fd); } } if(playdevice) ao_close(playdevice); ao_shutdown(); #if defined(RAW_SUPPORT) || defined(HTTP_SUPPORT) || defined(FTP_SUPPORT) if(fd) close(fd); #endif return(0); }