int main(int argc,char *argv[]) { short error; /* general purpose error variable */ int pid; gProcessNumber = atoi(argv[1]); gPid = getpid(); printf("Worker Process %03d is now running. Pid=%d Logfile=%s.\n", gProcessNumber,gPid,argv[3]); // get name of input command file which will be remapped to STDIN // all parms and commands are input through stdin file strcpy(gCommandFile,argv[2]); /* open a log file */ LogInit(argv[3],5); /* print header */ LogMsg(LINEAFTER,"ODBC/SQL/TM Query/Transaction Generator (NOMAD)\n" "Compiled: %s %s\n\n", __DATE__,__TIME__); /* read in command file contents and see what we're supposed to do */ if(get_commands()!=SUCCESS) exit(EXIT_FAILURE); LogMsg(LINEAFTER,"MasterSeed = %d\n",gMasterSeed); /* initialize some globals, find and open required files */ if(initialize()!=0) exit(EXIT_FAILURE); post_status(STARTED); /* get needed info about each of the tables this process will use */ if(get_table_info(gpTableDesc,(short)gTableCount)!=0) exit(EXIT_FAILURE); /* now start the main execution loop */ error=execute_command_list(0,gpList[0]->duration); /*>>> handle error somehow */ /*>>> may not be a need to handle errors if it already posts... */ /*>>>...error messages to the logfile */ post_status(FINISHED); /* perform any clean up */ /*>>> there currently isn't anything to do for clean-up, but later... */ /*>>> ...versions will support this option */ exit(EXIT_SUCCESS); } /* end of main() */
/* * This is called by ripstream when we get a new track. * most logic is handled by filelib_start() so we just * make sure there are no bad characters in the name and * update via the callback */ error_code rip_manager_start_track (RIP_MANAGER_INFO *rmi, TRACK_INFO* ti) { int ret; #if defined (commmentout) /* GCS FIX -- here is where i would compose the incomplete filename */ char* trackname = ti->raw_metadata; debug_printf("rip_manager_start_track: %s\n", trackname); if (rmi->write_data && (ret = filelib_start(trackname)) != SR_SUCCESS) { return ret; } #endif rmi->write_data = ti->save_track; if (rmi->write_data && (ret = filelib_start (rmi, ti)) != SR_SUCCESS) { return ret; } rmi->filesize = 0; /* Compose the string for the console output */ compose_console_string (rmi, ti); rmi->filename[SR_MAX_PATH-1] = '\0'; rmi->status_callback (rmi, RM_NEW_TRACK, (void*) rmi->filename); post_status(rmi, 0); return SR_SUCCESS; }
/* Ok, the end_track()'s function is actually to move * tracks out from the incomplete directory. It does * get called, but only after the 2nd track is played. * the first track is *never* complete. */ error_code rip_manager_end_track (RIP_MANAGER_INFO* rmi, TRACK_INFO* ti) { mchar mfullpath[SR_MAX_PATH]; char fullpath[SR_MAX_PATH]; if (rmi->write_data) { filelib_end (rmi, ti, rmi->prefs->overwrite, GET_TRUNCATE_DUPS(rmi->prefs->flags), mfullpath); } post_status(rmi, 0); string_from_gstring (rmi, fullpath, SR_MAX_PATH, mfullpath, CODESET_FILESYS); rmi->status_callback (rmi, RM_TRACK_DONE, (void*)fullpath); return SR_SUCCESS; }
static error_code start_ripping (RIP_MANAGER_INFO* rmi) { STREAM_PREFS* prefs = rmi->prefs; error_code ret; const char *pproxy = prefs->proxyurl[0] ? prefs->proxyurl : NULL; debug_printf ("start_ripping: checkpoint 1\n"); /* If proxy URL not spec'd on command line (or plugin field), check the environment variable */ if (!pproxy) { char const *env_http_proxy = getenv ("http_proxy"); if (env_http_proxy) { pproxy = env_http_proxy; debug_printf ("Getting proxy from $http_proxy: %s\n", pproxy); } } debug_printf ("start_ripping: checkpoint 2\n"); /* Connect to the stream */ ret = http_sc_connect (rmi, &rmi->stream_sock, prefs->url, pproxy, &rmi->http_info, prefs->useragent, prefs->referer, prefs->if_name); if (ret != SR_SUCCESS) { debug_printf ("http_sc_connect() returned error\n"); goto RETURN_ERR; } /* If the icy_name exists, but is empty, set to a bogus name so that we can create the directory correctly, etc. */ if (strlen(rmi->http_info.icy_name) == 0) { strcpy (rmi->http_info.icy_name, "Streamripper_rips"); } /* Set the ripinfo struct from the data we now know about the * stream, this info are things like server name, type, * bitrate etc.. */ rmi->meta_interval = rmi->http_info.meta_interval; rmi->http_bitrate = rmi->http_info.icy_bitrate; rmi->detected_bitrate = -1; rmi->bitrate = -1; strcpy (rmi->streamname, rmi->http_info.icy_name); strcpy (rmi->server_name, rmi->http_info.server); /* Initialize file writing code. */ ret = filelib_init (rmi, GET_INDIVIDUAL_TRACKS(rmi->prefs->flags), GET_COUNT_FILES(rmi->prefs->flags), rmi->prefs->count_start, GET_KEEP_INCOMPLETE(rmi->prefs->flags), GET_SINGLE_FILE_OUTPUT(rmi->prefs->flags), rmi->http_info.content_type, rmi->prefs->output_directory, rmi->prefs->output_pattern, rmi->prefs->showfile_pattern, GET_SEPARATE_DIRS(rmi->prefs->flags), GET_DATE_STAMP(rmi->prefs->flags), rmi->http_info.icy_name); if (ret != SR_SUCCESS) { debug_printf ("filelib_init() returned error\n"); goto RETURN_ERR; } /* Start up external program to get metadata. */ rmi->ep = 0; if (GET_EXTERNAL_CMD(rmi->prefs->flags)) { debug_printf ("Spawn external: %s\n", rmi->prefs->ext_cmd); rmi->ep = spawn_external (rmi->prefs->ext_cmd); if (rmi->ep) { debug_printf ("Spawn external succeeded\n"); } else { debug_printf ("Spawn external failed\n"); } } /* Allocate buffers for ripstream */ strcpy(rmi->no_meta_name, rmi->http_info.icy_name); rmi->getbuffer = 0; ripstream_clear (rmi); ret = ripstream_init(rmi); if (ret != SR_SUCCESS) { ripstream_clear (rmi); goto RETURN_ERR; } /* Launch relay server threads */ if (GET_MAKE_RELAY (rmi->prefs->flags)) { u_short new_port = 0; ret = relaylib_start (rmi, GET_SEARCH_PORTS(rmi->prefs->flags), rmi->prefs->relay_port, rmi->prefs->max_port, &new_port, rmi->prefs->if_name, rmi->prefs->max_connections, rmi->prefs->relay_ip, rmi->http_info.meta_interval != NO_META_INTERVAL); if (ret != SR_SUCCESS) { goto RETURN_ERR; } rmi->prefs->relay_port = new_port; /* Create pls file with address of relay stream */ if (0 != rmi->prefs->pls_file[0]) { create_pls_file (rmi); } } /* Done. */ post_status (rmi, RM_STATUS_BUFFERING); return SR_SUCCESS; RETURN_ERR: socklib_close(&rmi->stream_sock); return ret; }
static void ripthread (void *thread_arg) { error_code ret; RIP_MANAGER_INFO* rmi = (RIP_MANAGER_INFO*) thread_arg; debug_ripthread (rmi); debug_stream_prefs (rmi->prefs); /* Connect to remote server */ ret = start_ripping (rmi); if (ret != SR_SUCCESS) { debug_printf ("Ripthread did start_ripping()\n"); threadlib_signal_sem (&rmi->started_sem); post_error (rmi, ret); goto DONE; } rmi->status_callback (rmi, RM_STARTED, (void *)NULL); post_status (rmi, RM_STATUS_BUFFERING); debug_printf ("Ripthread did initialization\n"); threadlib_signal_sem(&rmi->started_sem); while (TRUE) { debug_printf ("Gonna ripstream_rip\n"); ret = ripstream_rip(rmi); debug_printf ("Did ripstream_rip\n"); if (!rmi->started) { break; } else if (rmi->megabytes_ripped >= rmi->prefs->maxMB_rip_size && GET_CHECK_MAX_BYTES (rmi->prefs->flags)) { /* GCS Aug 23, 2003: bytes_ripped can still overflow */ socklib_close (&rmi->stream_sock); destroy_subsystems (rmi); //post_error (rmi, SR_ERROR_MAX_BYTES_RIPPED); break; } else if (ret == SR_SUCCESS_BUFFERING) { post_status (rmi, RM_STATUS_BUFFERING); /* Fall through */ } else if (ret == SR_ERROR_CANT_DECODE_MP3) { post_error (rmi, ret); continue; } else if ((ret == SR_ERROR_RECV_FAILED || ret == SR_ERROR_TIMEOUT || ret == SR_ERROR_NO_TRACK_INFO || ret == SR_ERROR_SELECT_FAILED) && GET_AUTO_RECONNECT (rmi->prefs->flags)) { /* Try to reconnect */ post_status (rmi, RM_STATUS_RECONNECTING); while (rmi->started) { socklib_close(&rmi->stream_sock); if (rmi->ep) { debug_printf ("Close external\n"); close_external (&rmi->ep); } destroy_subsystems (rmi); ret = start_ripping (rmi); if (ret == SR_SUCCESS) break; Sleep(1000); } if (!rmi->started) { break; } /* Fall through */ } else if (ret == SR_ERROR_ABORT_PIPE_SIGNALLED) { /* Normal exit condition CTRL-C on unix */ destroy_subsystems (rmi); break; } else if (ret != SR_SUCCESS) { destroy_subsystems (rmi); post_error (rmi, ret); break; } /* All systems go. Caller should update GUI that it is ripping */ if (rmi->filesize > 0) { post_status (rmi, RM_STATUS_RIPPING); } } // We get here when there was either a fatal error // or we we're not auto-reconnecting and the stream just stopped // or when we have been told to stop, via the rmi->started flag DONE: rmi->status_callback (rmi, RM_DONE, 0); rmi->started = 0; debug_printf ("ripthread() exiting!\n"); }
/********************************************************************** ** execute_command_list() ** ** This function is recursive. It steps through the commands in the ** command list passed to it. If the command list contains another ** command list (as is the case with nested loops) then it will call ** itself to execute that command list. It will also propogate the ** time limits (if any) from the outer most loop. So, a sub-loop with ** a time limit of 15 minutes within an outer loop with a time limit ** of only 10 minutes would not execute longer than the time limit of ** outer loop's time limit of 10 minutes. **********************************************************************/ short execute_command_list(short list_num,time_t time_limit) { short error; time_t run_time; time_t elapsed_time; time_t start_time; list_desc *l_ptr; Boolean done; Boolean done2; short i,j; short iterations; l_ptr=gpList[list_num]; post_status(OK); /* see if someone has told us to stop */ check_for_stop(); start_time=time(NULL); /* adjust <run_time> to minimum of our <time_limit> or list's duration */ run_time=l_ptr->duration; if(run_time>0) run_time*=60; if(time_limit>0){ if((run_time<0)||(run_time>time_limit)) run_time=time_limit; } iterations=0; done=FALSE; while(!done){ i=0; done2=FALSE; while(!done2){ /* see if it is a list of percentages */ if(l_ptr->item[i].code>0) { for(j=0;j<MAX_ACTION_TYPES;j++) g_percent[j]=NOT_SPECIFIED; for(j=0;j<l_ptr->item_count;j++) { g_percent[l_ptr->item[j].code]=l_ptr->item[j].u1.percentage; i++; } i--; if(adjust_percents()==FAILURE) return(FAILURE); execute_by_percent(run_time); } /* if a loop code then execute command list for the loop... */ /* ...recursively */ else if(l_ptr->item[i].code==0) { error=execute_command_list(l_ptr->item[i].u1.loop_number,run_time); /*>>> handle error somehow */ } /* if an action code then go do action for 'n' repetitions */ else if(l_ptr->item[i].code<0) { execute_by_action(l_ptr->item[i].code, l_ptr->item[i].u1.repetitions); } /* see if someone has told us to stop */ post_status(OK); check_for_stop(); /* check if we've reached our stop time or end of item list */ if(run_time>0) { elapsed_time=(time_t)difftime(time(NULL),start_time); if(elapsed_time>run_time) done2=TRUE; } else{ i++; if(i>=l_ptr->item_count) done2=TRUE; } } /* end of while(!done2) */ /* see if someone has told us to stop */ post_status(OK); check_for_stop(); /* check if we've reached our stop time or end of iterations */ if(run_time>0) { elapsed_time=(time_t)difftime(time(NULL),start_time); if(elapsed_time>run_time) done=TRUE; } if(l_ptr->duration<0){ iterations++; if(l_ptr->duration+iterations>=0) done=TRUE; } } /* end of while(!done) */ return(0); } /* end of execute_command_list() */