cmyth_chain_t cmyth_chain_create(cmyth_recorder_t rec, char *chain_id) { cmyth_chain_t chain; struct event_loop_args *args; args = ref_alloc(sizeof(*args)); chain = ref_alloc(sizeof(*chain)); chain->chain_id = ref_strdup(chain_id); chain->chain_count = 0; chain->chain_current = -1; chain->chain_list = NULL; chain->chain_callback = NULL; chain->chain_event = NULL; chain->chain_thread = 0; chain->chain_conn = ref_hold(rec->rec_conn); pthread_mutex_init(&chain->chain_mutex, NULL); pthread_cond_init(&chain->chain_cond, NULL); ref_set_destroy(chain, (ref_destroy_t)cmyth_chain_destroy); args->rec = ref_hold(rec); args->chain = ref_hold(chain); chain->chain_thread_args = (void*)args; pthread_create(&chain->chain_thread, NULL, cmyth_chain_event_loop, (void*)args); return chain; }
static int o_files(int f, struct path_info *info, struct fuse_file_info *fi) { int i; cmyth_conn_t control; cmyth_proglist_t list; int count; int ret = -ENOENT; pthread_mutex_lock(&mutex); if ((i=lookup_server(info->host)) < 0) { pthread_mutex_unlock(&mutex); return -ENOENT; } control = ref_hold(conn[i].control); if (conn[i].list == NULL) { list = cmyth_proglist_get_all_recorded(control); conn[i].list = list; parse_progs(conn+i); } else { list = conn[i].list; } list = ref_hold(list); pthread_mutex_unlock(&mutex); count = cmyth_proglist_get_count(list); for (i=0; i<count; i++) { cmyth_proginfo_t prog; char *pn; prog = cmyth_proglist_get_item(list, i); pn = cmyth_proginfo_pathname(prog); if (strcmp(pn+1, info->file) == 0) { if (do_open(prog, fi, f) < 0) { ref_release(pn); ref_release(prog); goto out; } ref_release(pn); ref_release(prog); ret = 0; goto out; } ref_release(pn); ref_release(prog); } out: ref_release(control); ref_release(list); return ret; }
static int rd_files(struct path_info *info, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { int i; cmyth_conn_t control; cmyth_proglist_t list; int count; pthread_mutex_lock(&mutex); if ((i=lookup_server(info->host)) < 0) { pthread_mutex_unlock(&mutex); return 0; } control = ref_hold(conn[i].control); if (conn[i].list == NULL) { list = cmyth_proglist_get_all_recorded(control); conn[i].list = list; } else { list = conn[i].list; } list = ref_hold(list); pthread_mutex_unlock(&mutex); count = cmyth_proglist_get_count(list); for (i=0; i<count; i++) { cmyth_proginfo_t prog; long long len; char *fn, *pn; struct stat st; prog = cmyth_proglist_get_item(list, i); pn = cmyth_proginfo_pathname(prog); len = cmyth_proginfo_length(prog); fn = pn+1; memset(&st, 0, sizeof(st)); st.st_mode = S_IFREG | 0444; st.st_size = len; debug("%s(): file '%s' len %lld\n", __FUNCTION__, fn, len); filler(buf, fn, &st, 0); ref_release(prog); ref_release(pn); } ref_release(control); ref_release(list); return 0; }
/* * cmyth_livetv_chain_add_url(cmyth_recorder_t rec, char * url) * * Scope: PRIVATE * * Description * * Called to add a url to a livetv chain structure. The url is added * only if it is not already there. * * Return Value: * * Success: 0 * * Faiure: -1 */ static int cmyth_livetv_chain_add_url(cmyth_recorder_t rec, char * url) { char ** tmp; cmyth_file_t * fp; cmyth_proginfo_t * pi; int ret = 0; if(cmyth_livetv_chain_has_url(rec,url) == -1) { if(rec->rec_livetv_chain->chain_current == -1) { rec->rec_livetv_chain->chain_ct = 1; rec->rec_livetv_chain->chain_current = 0; /* Nothing in the chain yet, allocate the space */ tmp = (char**)ref_alloc(sizeof(char *)); fp = (cmyth_file_t *)ref_alloc(sizeof(cmyth_file_t)); pi = (cmyth_proginfo_t *)ref_alloc(sizeof(cmyth_proginfo_t)); } else { rec->rec_livetv_chain->chain_ct++; tmp = (char**)ref_realloc(rec->rec_livetv_chain->chain_urls, sizeof(char *)*rec->rec_livetv_chain->chain_ct); fp = (cmyth_file_t *) ref_realloc(rec->rec_livetv_chain->chain_files, sizeof(cmyth_file_t)*rec->rec_livetv_chain->chain_ct); pi = (cmyth_proginfo_t *) ref_realloc(rec->rec_livetv_chain->progs, sizeof(cmyth_proginfo_t)*rec->rec_livetv_chain->chain_ct); } if(tmp != NULL && fp != NULL) { rec->rec_livetv_chain->chain_urls = ref_hold(tmp); rec->rec_livetv_chain->chain_files = ref_hold(fp); rec->rec_livetv_chain->progs = ref_hold(pi); ref_release(tmp); ref_release(fp); ref_release(pi); rec->rec_livetv_chain->chain_urls[rec->rec_livetv_chain->chain_ct-1] = ref_strdup(url); rec->rec_livetv_chain->chain_files[rec->rec_livetv_chain->chain_ct-1] = ref_hold(NULL); rec->rec_livetv_chain->progs[rec->rec_livetv_chain->chain_ct-1] = ref_hold(NULL); } else { ret = -1; cmyth_dbg(CMYTH_DBG_ERROR, "%s: memory allocation request failed\n", __FUNCTION__); } } return ret; }
/* * cmyth_livetv_chain_switch(cmyth_recorder_t rec, int dir) * * Scope: PUBLIC * * Description * * Switches to the next or previous chain depending on the * value of dir. Dir is usually 1 or -1. * * Return Value: * * Sucess: 1 * * Failure: 0 */ int cmyth_livetv_chain_switch(cmyth_recorder_t rec, int dir) { int ret; ret = 0; if(dir == LAST) { PRINTF("**SSDEBUG:(cmyth_livetv_chain_switch) dir: %d\n", dir); dir = rec->rec_livetv_chain->chain_ct - rec->rec_livetv_chain->chain_current - 1; ret = 1; } if((dir < 0 && rec->rec_livetv_chain->chain_current + dir >= 0) || (rec->rec_livetv_chain->chain_current < rec->rec_livetv_chain->chain_ct - dir )) { ref_release(rec->rec_livetv_file); ret = rec->rec_livetv_chain->chain_current += dir; PRINTF("**SSDEBUG:(cmyth_livetv_chain_switch): %s:%d\n", "dooingSwitcheroo",ret); rec->rec_livetv_file = ref_hold(rec->rec_livetv_chain->chain_files[ret]); rec->rec_livetv_chain ->prog_update_callback(rec->rec_livetv_chain->progs[ret]); ret = 1; } return ret; }
/** * Allocate a dynamic query string to have parameters added to it * \param db database connection object * \param query_string Query string with ? placemarks for all dynamic * parameters, this is NOT copied and must therefore * remain valid for the life of the query. */ cmyth_mysql_query_t * cmyth_mysql_query_create(cmyth_database_t db, const char * query_string) { cmyth_mysql_query_t * out; out = ref_alloc(sizeof(*out)); if(out != NULL) { ref_set_destroy(out,query_destroy); out->source = out->source_pos = query_string; out->source_len = strlen(out->source); out->buf_size = out->source_len *2; out->buf_used = 0; out->db = ref_hold(db); out->buf = ref_alloc(out->buf_size); if(out->buf == NULL) { ref_release(out); out = NULL; } else { out->buf[0] = '\0'; } } return out; }
int cmyth_chain_set_current(cmyth_chain_t chain, cmyth_proginfo_t prog) { unsigned int i; int rc = -1; void (*callback)(cmyth_proginfo_t prog) = NULL; cmyth_proginfo_t cb_prog = NULL; if ((chain == NULL) || (prog == NULL)) { return -1; } pthread_mutex_lock(&chain->chain_mutex); for (i=0; i<chain->chain_count; i++) { if (cmyth_proginfo_compare(prog, chain->chain_list[i]->prog) == 0) { chain->chain_current = i; callback = chain->chain_callback; if (callback) { cb_prog = ref_hold(chain->chain_list[i]->prog); } break; } } pthread_mutex_unlock(&chain->chain_mutex); if (callback && cb_prog) { callback(cb_prog); ref_release(cb_prog); } return rc; }
cmyth_file_t cmyth_chain_current_file(cmyth_chain_t chain) { cmyth_file_t file = NULL; if (chain == NULL) { return NULL; } pthread_mutex_lock(&chain->chain_mutex); if (chain->chain_list) { file = chain->chain_list[chain->chain_current]->file; if (file == NULL) { cmyth_chain_switch_to_locked(chain, chain->chain_current); file = chain->chain_list[chain->chain_current]->file; } ref_hold(file); } pthread_mutex_unlock(&chain->chain_mutex); return file; }
/* * cmyth_livetv_chain_add_prog(cmyth_recorder_t rec, char * url, * cmyth_proginfo_t prog) * * Scope: PRIVATE * * Description * * Called to add program info to a livetv chain structure. The info is added * only if the url is already there. * * Return Value: * * Success: 0 * * Faiure: -1 */ static int cmyth_livetv_chain_add_prog(cmyth_recorder_t rec, char * url, cmyth_proginfo_t prog) { int cur; int ret = 0; cmyth_proginfo_t tmp; if(rec->rec_livetv_chain) { if(rec->rec_livetv_chain->chain_current != -1) { /* Is this file already in the chain? */ if((cur = cmyth_livetv_chain_has_url(rec, url)) != -1) { /* Release the existing handle after holding the new */ /* this allows them to be the same. */ tmp = rec->rec_livetv_chain->progs[cur]; rec->rec_livetv_chain->progs[cur] = ref_hold(prog); ref_release(tmp); } } else { cmyth_dbg(CMYTH_DBG_ERROR, "%s: attempted to add prog for %s to an empty chain\n", __FUNCTION__, url); ret = -1; } } else { cmyth_dbg(CMYTH_DBG_ERROR, "%s: attempted to add prog for %s to an non existant chain\n", __FUNCTION__, url); ret = -1; } return ret; }
char * cmyth_recordingrule_playgroup(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->playgroup); }
char * cmyth_recordingrule_storagegroup(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->storagegroup); }
/* * cmyth_channel_icon() * * * Scope: PUBLIC * * Description * * Retrieves the 'icon' field of a channel structure. * * The returned string is a pointer to the string within the channel * structure, so it should not be modified by the caller. The * return value is a 'char *' for this reason. * Before forgetting the reference to this string the caller * must call ref_release(). * * Return Value: * * Success: A pointer to a 'char *' pointing to the field. * * Failure: NULL */ char * cmyth_channel_icon(cmyth_channel_t channel) { if (!channel) { return NULL; } return ref_hold(channel->icon); }
char * cmyth_recordingrule_category(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->category); }
/* * cmyth_proginfo_prodyear(cmyth_proginfo_t prog) * * * Scope: PUBLIC * * Description * * Retrieves the 'proginfo_prodyear' field of a program info * structure. * * The returned string is a pointer to the string within the program * info structure, so it should not be modified by the caller. The * return value is a 'char *' for this reason. * * Return Value: * * Success: A pointer to a 'char *' pointing to the field. * * Failure: NULL */ char * cmyth_proginfo_prodyear(cmyth_proginfo_t prog) { if (!prog) { return NULL; } return ref_hold(prog->proginfo_prodyear); }
char * cmyth_recordingrule_seriesid(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->seriesid); }
/* * cmyth_channel_name() * * * Scope: PUBLIC * * Description * * Retrieves the 'name' field of a channel structure. * * The returned string is a pointer to the string within the channel * structure, so it should not be modified by the caller. The * return value is a 'char *' for this reason. * Before forgetting the reference to this string the caller * must call ref_release(). * * Return Value: * * Success: A pointer to a 'char *' pointing to the field. * * Failure: NULL */ char * cmyth_channel_name(cmyth_channel_t channel) { if (!channel) { return NULL; } return ref_hold(channel->name); }
/* * cmyth_proginfo_rec_end(cmyth_proginfo_t prog) * * * Scope: PUBLIC * * Description * * Retrieves the 'rec_end' timestamp from a program info structure. * This tells when a recording started. * * The returned timestamp is returned held. It should be released * when no longer needed using ref_release(). * * Return Value: * * Success: A non-NULL cmyth_timestamp_t * * Failure: NULL */ cmyth_timestamp_t cmyth_proginfo_rec_end(cmyth_proginfo_t prog) { if (!prog) { return NULL; } return ref_hold(prog->proginfo_rec_end_ts); }
/* * cmyth_proginfo_start(cmyth_proginfo_t prog) * * * Scope: PUBLIC * * Description * * Retrieves the 'start' timestamp from a program info structure. * This indicates a programmes start time. * * The returned timestamp is returned held. It should be released * when no longer needed using ref_release(). * * Return Value: * * Success: A non-NULL cmyth_timestamp_t * * Failure: NULL */ cmyth_timestamp_t cmyth_proginfo_start(cmyth_proginfo_t prog) { if (!prog) { return NULL; } return ref_hold(prog->proginfo_start_ts); }
/* * cmyth_proginfo_channame(cmyth_proginfo_t prog) * * * Scope: PUBLIC * * Description * * Retrieves the 'proginfo_pathname' field of a program info * structure. * * The returned string is a pointer to the string within the program * info structure, so it should not be modified by the caller. The * return value is a 'char *' for this reason. * * Return Value: * * Success: A pointer to a 'char *' pointing to the field. * * Failure: NULL */ char * cmyth_proginfo_pathname(cmyth_proginfo_t prog) { if (!prog) { return NULL; } return ref_hold(prog->proginfo_pathname); }
char * cmyth_recordingrule_profile(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->profile); }
char * cmyth_recordingrule_programid(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->programid); }
char * cmyth_recordingrule_callsign(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->callsign); }
char * cmyth_recordingrule_inetref(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->inetref); }
char * cmyth_recordingrule_subtitle(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->subtitle); }
char * cmyth_recordingrule_description(cmyth_recordingrule_t rr) { if (!rr) { return NULL; } return ref_hold(rr->description); }
/* * cmyth_channel_callsign() * * * Scope: PUBLIC * * Description * * Retrieves the 'callsign' field of a channel structure. * * The returned string is a pointer to the string within the channel * structure, so it should not be modified by the caller. The * return value is a 'char *' for this reason. * Before forgetting the reference to this string the caller * must call ref_release(). * * Return Value: * * Success: A pointer to a 'char *' pointing to the field. * * Failure: NULL */ char * cmyth_channel_callsign(cmyth_channel_t channel) { if (!channel) { return NULL; } return ref_hold(channel->callsign); }
/* * cmyth_channel_channumstr() * * * Scope: PUBLIC * * Description * * Retrieves the 'chanstr' field of a channel structure. * * The returned string is a pointer to the string within the channel * structure, so it should not be modified by the caller. The * return value is a 'char *' for this reason. * Before forgetting the reference to this string the caller * must call ref_release(). * * Return Value: * * Success: A pointer to a 'char *' pointing to the field. * * Failure: NULL */ char * cmyth_channel_channumstr(cmyth_channel_t channel) { if (!channel) { return NULL; } return ref_hold(channel->chanstr); }
char * cmyth_storagegroup_file_filename(cmyth_storagegroup_file_t file) { if (!file) { return NULL; } return ref_hold(file->filename); }
cmyth_chain_t cmyth_livetv_get_chain(cmyth_recorder_t rec) { if (rec == NULL) { return NULL; } return ref_hold(rec->rec_chain); }
cmyth_storagegroup_file_t cmyth_storagegroup_filelist_get_item(cmyth_storagegroup_filelist_t fl, int index) { if (!fl || index >= fl->storagegroup_filelist_count) { return NULL; } ref_hold(fl->storagegroup_filelist_list[index]); return fl->storagegroup_filelist_list[index]; }