static int download_pipe(download_t *dn, const char *args) { char **argv = NULL; int r; download_pipe_close(dn); gtimer_disarm(&dn->pipe_read_timer); /* Arguments */ if (spawn_parse_args(&argv, 64, args, NULL)) { tvherror(dn->log, "pipe: unable to parse arguments (%s)", args); return -1; } /* Grab */ r = spawn_and_give_stdout(argv[0], argv, NULL, &dn->pipe_fd, &dn->pipe_pid, 1); spawn_free_args(argv); if (r < 0) { dn->pipe_fd = -1; dn->pipe_pid = 0; tvherror(dn->log, "pipe: cannot start (%s)", args); return -1; } fcntl(dn->pipe_fd, F_SETFL, fcntl(dn->pipe_fd, F_GETFL) | O_NONBLOCK); gtimer_arm_ms(&dn->pipe_read_timer, download_pipe_read, dn, 250); return 0; }
/* * Complete data */ static int iptv_http_complete ( http_client_t *hc ) { iptv_mux_t *im = hc->hc_aux; char *url; url_t u; int r; if (im->im_m3u_header) { im->im_m3u_header = 0; sbuf_append(&im->mm_iptv_buffer, "", 1); url = iptv_http_m3u((char *)im->mm_iptv_buffer.sb_data); sbuf_reset(&im->mm_iptv_buffer, IPTV_BUF_SIZE); if (url == NULL) { tvherror("iptv", "m3u contents parsing failed"); return 0; } urlinit(&u); if (!urlparse(url, &u)) { hc->hc_keepalive = 0; r = http_client_simple_reconnect(hc, &u); if (r < 0) tvherror("iptv", "cannot reopen http client: %d'", r); } else { tvherror("iptv", "m3u url invalid '%s'", url); } urlreset(&u); free(url); return 0; } return 0; }
static int lav_muxer_open_file(muxer_t *m, const char *filename) { AVFormatContext *oc; lav_muxer_t *lm = (lav_muxer_t*)m; char buf[256]; int r; oc = lm->lm_oc; snprintf(oc->filename, sizeof(oc->filename), "%s", filename); if((r = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) { av_strerror(r, buf, sizeof(buf)); tvherror(LS_LIBAV, "%s: Could not open -- %s", filename, buf); lm->m_errors++; return -1; } /* bypass umask settings */ if (chmod(filename, lm->m_config.m_file_permissions)) tvherror(LS_LIBAV, "%s: Unable to change permissions -- %s", filename, strerror(errno)); return 0; }
static void download_fetch(void *aux) { download_t *dn = aux; http_client_t *hc; url_t u; urlinit(&u); if (dn->url == NULL) goto done; if (strncmp(dn->url, "file://", 7) == 0) { download_file(dn, dn->url + 7); goto done; } if (strncmp(dn->url, "pipe://", 7) == 0) { download_pipe(dn, dn->url + 7); goto done; } if (dn->http_client) { http_client_close(dn->http_client); dn->http_client = NULL; } if (urlparse(dn->url, &u) < 0) { tvherror(dn->log, "wrong url"); goto stop; } hc = http_client_connect(dn, HTTP_VERSION_1_1, u.scheme, u.host, u.port, NULL); if (hc == NULL) { tvherror(dn->log, "unable to open http client"); goto stop; } hc->hc_handle_location = 1; hc->hc_data_limit = 1024*1024; hc->hc_data_complete = download_fetch_complete; http_client_register(hc); http_client_ssl_peer_verify(hc, dn->ssl_peer_verify); if (http_client_simple(hc, &u) < 0) { http_client_close(hc); tvherror(dn->log, "unable to send http command"); goto stop; } dn->http_client = hc; goto done; stop: if (dn->stop) dn->stop(dn->aux); done: urlreset(&u); }
/* * Complete data */ static int iptv_http_complete ( http_client_t *hc ) { iptv_mux_t *im = hc->hc_aux; char *url, *url2, *s, *p; url_t u; int r; if (im->im_m3u_header) { im->im_m3u_header = 0; sbuf_append(&im->mm_iptv_buffer, "", 1); url = iptv_http_m3u((char *)im->mm_iptv_buffer.sb_data); sbuf_reset(&im->mm_iptv_buffer, IPTV_BUF_SIZE); if (url == NULL) { tvherror("iptv", "m3u contents parsing failed"); return 0; } urlinit(&u); if (url[0] == '/') { s = strdupa(im->mm_iptv_url_raw); if ((p = strchr(s, '/')) != NULL) *p = '\0'; if (!urlparse(s, &u)) goto invalid; url2 = malloc(512); url2[0] = '\0'; if ((p = http_arg_get(&hc->hc_args, "Host")) != NULL) { snprintf(url2, 512, "%s://%s%s", hc->hc_ssl ? "https" : "http", p, url); } else if (im->mm_iptv_url_raw) { snprintf(url2, 512, "%s%s", s, url); } free(url); url = url2; urlinit(&u); } if (!urlparse(url, &u)) { hc->hc_keepalive = 0; r = http_client_simple_reconnect(hc, &u, HTTP_VERSION_1_1); if (r < 0) tvherror("iptv", "cannot reopen http client: %d'", r); } else { invalid: tvherror("iptv", "m3u url invalid '%s'", url); } urlreset(&u); free(url); return 0; } return 0; }
/* * Output packet */ static int _timeshift_read ( timeshift_t *ts, timeshift_seek_t *seek, streaming_message_t **sm, int *wait ) { timeshift_file_t *tsf = seek->file; ssize_t r; off_t off = 0; *sm = NULL; if (tsf) { /* Open file */ if (tsf->rfd < 0 && !tsf->ram) { tsf->rfd = tvh_open(tsf->path, O_RDONLY, 0); tvhtrace(LS_TIMESHIFT, "ts %d open file %s (fd %i)", ts->id, tsf->path, tsf->rfd); if (tsf->rfd < 0) return -1; } if (tsf->rfd >= 0) if ((off = lseek(tsf->rfd, tsf->roff, SEEK_SET)) != tsf->roff) tvherror(LS_TIMESHIFT, "ts %d seek to %s failed (off %"PRId64" != %"PRId64"): %s", ts->id, tsf->path, (int64_t)tsf->roff, (int64_t)off, strerror(errno)); /* Read msg */ r = _read_msg(tsf, -1, sm); if (r < 0) { streaming_message_t *e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR); streaming_target_deliver2(ts->output, e); tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (woff %jd) (fd %i)", ts->id, (intmax_t)off, (intmax_t)tsf->woff, tsf->rfd); tvherror(LS_TIMESHIFT, "ts %d could not read buffer", ts->id); return -1; } tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (fd %i) read msg %p/%"PRId64" (%"PRId64")", ts->id, (intmax_t)off, tsf->rfd, *sm, *sm ? (*sm)->sm_time : -1, (int64_t)r); /* Special case - EOF */ if (r <= sizeof(size_t) || tsf->roff > tsf->size || *sm == NULL) { timeshift_file_get(seek->file); /* _read_close decreases file reference */ _read_close(seek); _seek_set_file(seek, timeshift_filemgr_next(tsf, NULL, 0), 0); *wait = 0; tvhtrace(LS_TIMESHIFT, "ts %d eof, seek->file %p (prev %p)", ts->id, seek->file, tsf); timeshift_filemgr_dump(ts); } } return 0; }
static ssize_t iptv_udp_read ( iptv_input_t *mi, iptv_mux_t *im ) { int i, n; struct iovec *iovec; udp_multirecv_t *um = im->im_data; ssize_t res = 0; n = udp_multirecv_read(um, im->mm_iptv_fd, IPTV_PKTS, &iovec); if (n < 0) return -1; im->mm_iptv_rtp_seq &= ~0xfff; for (i = 0; i < n; i++, iovec++) { if (iovec->iov_len <= 0) continue; if (*(uint8_t *)iovec->iov_base != 0x47) { im->mm_iptv_rtp_seq++; continue; } sbuf_append(&im->mm_iptv_buffer, iovec->iov_base, iovec->iov_len); res += iovec->iov_len; } if (im->mm_iptv_rtp_seq < 0xffff && im->mm_iptv_rtp_seq > 0x3ff) { tvherror(LS_IPTV, "receving non-raw UDP data for %s!", im->mm_nicename); im->mm_iptv_rtp_seq = 0x10000; /* no further logs! */ } return res; }
/** * Parse comskip data. * filename, in: full path to comskip file. * cut_list, in: empty list. out: the list filled with data. * return: number of read valid lines. * * Example of comskip file content (format v2): * * FILE PROCESSING COMPLETE 53999 FRAMES AT 2500 * ------------------- * 50 2459 * 14923 23398 * 42417 54004 * */ static int dvr_parse_comskip ( const char *line, dvr_cutpoint_t *cutpoint, float *frame_rate ) { int start = 0, end = 0; /* Header */ if (sscanf(line, "FILE PROCESSING COMPLETE %*d FRAMES AT %f", frame_rate) == 1) { *frame_rate /= (*frame_rate > 1000.0f ? 100.0f : 1.0f); return 1; // TODO: probably not nice this returns "error" } /* Invalid line */ if(*frame_rate <= 0.0f || sscanf(line, "%d\t%d", &start, &end) != 2) return 1; /* Sanity Checks */ if(start < 0 || end < 0 || end < start || start == end) { tvherror("dvr", "Insane EDL entry: start=%d, end=%d. Skipping.", start, end); return 1; } /* Set values */ cutpoint->dc_start_ms = (int) ((start * 1000) / *frame_rate); cutpoint->dc_end_ms = (int) ((end * 1000) / *frame_rate); // Comskip don't have different actions, so use DVR_CP_COMM (Commercial skip) cutpoint->dc_type = DVR_CP_COMM; return 0; }
/* Initialise binary */ int uuid_init_bin ( tvh_uuid_t *u, const char *str ) { memset(u, 0, sizeof(tvh_uuid_t)); if (str) { if (strlen(str) != UUID_HEX_SIZE - 1) { tvherror("uuid", "wrong uuid size"); return -EINVAL; } return hex2bin(u->bin, sizeof(u->bin), str); } else if (read(fd, u->bin, sizeof(u->bin)) != sizeof(u->bin)) { tvherror("uuid", "failed to read from %s", RANDOM_PATH); return -EINVAL; } return 0; }
int udp_connect( udp_connection_t *uc, const char *name, const char *host, int port ) { char buf[50]; int r; if (uc == NULL || uc == UDP_FATAL_ERROR) return -1; uc->peer_host = host ? strdup(host) : NULL; uc->peer_port = port; uc->peer_multicast = 0; if (udp_resolve(uc, &uc->peer, host, port, &uc->peer_multicast, 1)) return -1; if (connect(uc->fd, (struct sockaddr *)&uc->peer, sizeof(struct sockaddr_in))) { inet_ntop(uc->peer.ss_family, IP_IN_ADDR(uc->peer), buf, sizeof(buf)); tvherror(uc->subsystem, "%s - cannot bind %s:%hu [e=%s]", name, buf, ntohs(IP_PORT(uc->peer)), strerror(errno)); r = -errno; return r; } return 0; }
static void linuxdvb_ca_class_enabled_notify ( void *p, const char *lang ) { linuxdvb_ca_t *lca = (linuxdvb_ca_t *) p; if (lca->lca_enabled) { if (lca->lca_ca_fd < 0) { lca->lca_ca_fd = tvh_open(lca->lca_ca_path, O_RDWR | O_NONBLOCK, 0); tvhtrace(LS_LINUXDVB, "opening ca%u %s (fd %d)", lca->lca_number, lca->lca_ca_path, lca->lca_ca_fd); } } else { tvhtrace(LS_LINUXDVB, "closing ca%u %s (fd %d)", lca->lca_number, lca->lca_ca_path, lca->lca_ca_fd); if (lca->lca_en50221_thread_running) { lca->lca_en50221_thread_running = 0; pthread_join(lca->lca_en50221_thread, NULL); } if (ioctl(lca->lca_ca_fd, CA_RESET, NULL)) tvherror(LS_LINUXDVB, "unable to reset ca%u %s", lca->lca_number, lca->lca_ca_path); close(lca->lca_ca_fd); lca->lca_ca_fd = -1; idnode_notify_title_changed(&lca->lca_id, lang); } }
void uuid_random ( uint8_t *buf, size_t bufsize ) { if (read(fd, buf, bufsize) != bufsize) { tvherror("uuid", "random failed: %s", strerror(errno)); exit(1); } }
static int download_file(download_t *dn, const char *filename) { int fd, res; struct stat st; char *data, *last_url; ssize_t r; off_t off; fd = tvh_open(filename, O_RDONLY, 0); if (fd < 0) { tvherror(dn->log, "unable to open file '%s': %s", filename, strerror(errno)); return -1; } if (fstat(fd, &st) || st.st_size == 0) { tvherror(dn->log, "unable to stat file '%s': %s", filename, strerror(errno)); close(fd); return -1; } data = malloc(st.st_size+1); off = 0; do { r = read(fd, data + off, st.st_size - off); if (r < 0) { if (ERRNO_AGAIN(errno)) continue; break; } off += r; } while (off != st.st_size); close(fd); if (off == st.st_size) { data[off] = '\0'; last_url = strrchr(filename, '/'); if (last_url) last_url++; res = dn->process(dn->aux, last_url, NULL, data, off); } else { res = -1; } free(data); return res; }
/* * Connected */ static int iptv_rtsp_header ( http_client_t *hc ) { iptv_mux_t *im = hc->hc_aux; rtsp_priv_t *rp; int r; if (im == NULL) { /* teardown (or teardown timeout) */ if (hc->hc_cmd == RTSP_CMD_TEARDOWN) { pthread_mutex_lock(&global_lock); mtimer_arm_rel(&hc->hc_close_timer, iptv_rtsp_close_cb, hc, 0); pthread_mutex_unlock(&global_lock); } return 0; } if (hc->hc_cmd == RTSP_CMD_GET_PARAMETER && hc->hc_code != HTTP_STATUS_OK) { tvhtrace("iptv", "GET_PARAMETER command returned invalid error code %d for '%s', " "fall back to OPTIONS in keep alive loop.", hc->hc_code, im->mm_iptv_url_raw); hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_OPTIONS; return 0; } if (hc->hc_code != HTTP_STATUS_OK) { tvherror("iptv", "invalid error code %d for '%s'", hc->hc_code, im->mm_iptv_url_raw); return 0; } rp = im->im_data; switch (hc->hc_cmd) { case RTSP_CMD_SETUP: r = rtsp_setup_decode(hc, 0); if (r >= 0) { rtsp_play(hc, rp->path, rp->query); rp->play = 1; } break; case RTSP_CMD_PLAY: // Now let's set peer port for RTCP // Use the HTTP host for sending RTCP reports, NOT the hc_rtp_dest (which is where the stream is sent) if (udp_connect(rp->rtcp_info->connection, "rtcp", hc->hc_host, hc->hc_rtcp_server_port)) { tvhlog(LOG_WARNING, "rtsp", "Can't connect to remote, RTCP receiver reports won't be sent"); } hc->hc_cmd = HTTP_CMD_NONE; pthread_mutex_lock(&global_lock); iptv_input_mux_started(hc->hc_aux); mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im, sec2mono(MAX(1, (hc->hc_rtp_timeout / 2) - 1))); pthread_mutex_unlock(&global_lock); break; default: break; } return 0; }
int file_unlock(const char *lfile, int _fd) { int err; err = state_lock_(lfile, 0, 10, _fd); if (err < 0) tvherror("lock", "file %s unlock error: %s", lfile, strerror(-err)); return err; }
void uuid_init ( void ) { fd = open(RANDOM_PATH, O_RDONLY); if (fd == -1) { tvherror("uuid", "failed to open %s", RANDOM_PATH); exit(1); } }
int file_lock(const char *lfile, int timeout) { int err; err = state_lock_(lfile, 1, timeout, -1); if (err < 0) tvherror("lock", "file %s lock error: %s", lfile, strerror(-err)); return err; }
void dvr_rec_subscribe(dvr_entry_t *de) { char buf[100]; int weight; profile_t *pro; profile_chain_t *prch; assert(de->de_s == NULL); assert(de->de_chain == NULL); if(de->de_pri < ARRAY_SIZE(prio2weight)) weight = prio2weight[de->de_pri]; else weight = 300; snprintf(buf, sizeof(buf), "DVR: %s", lang_str_get(de->de_title, NULL)); pro = de->de_config->dvr_profile; prch = malloc(sizeof(*prch)); profile_chain_init(prch, pro, de->de_channel); if (profile_chain_open(prch, &de->de_config->dvr_muxcnf, 0, 0)) { tvherror("dvr", "unable to create new channel streaming chain for '%s'", channel_get_name(de->de_channel)); return; } de->de_s = subscription_create_from_channel(prch, weight, buf, prch->prch_flags, NULL, NULL, NULL); if (de->de_s == NULL) { tvherror("dvr", "unable to create new channel subcription for '%s'", channel_get_name(de->de_channel)); profile_chain_close(prch); free(prch); de->de_chain = NULL; return; } de->de_chain = prch; tvhthread_create(&de->de_thread, NULL, dvr_thread, de); }
static int udp_resolve( udp_connection_t *uc, struct sockaddr_storage *ss, const char *host, int port, int *multicast, int receiver ) { struct addrinfo hints, *res, *ressave, *use = NULL; char port_buf[6]; int x; snprintf(port_buf, 6, "%d", port); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = (receiver ? AI_PASSIVE : 0) | AI_NUMERICSERV; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; x = getaddrinfo(host, port_buf, &hints, &res); if (x < 0) { tvhlog(LOG_ERR, uc->subsystem, "getaddrinfo: %s: %s", host != NULL ? host : "*", x == EAI_SYSTEM ? strerror(errno) : gai_strerror(x)); return -1; } ressave = res; while (res) { if (res->ai_family == tcp_preferred_address_family) { use = res; break; } else if (use == NULL) { use = res; } res = res->ai_next; } if (use->ai_family == AF_INET6) { ss->ss_family = AF_INET6; IP_AS_V6(*ss, port) = htons(port); memcpy(&IP_AS_V6(*ss, addr), &((struct sockaddr_in6 *)use->ai_addr)->sin6_addr, sizeof(struct in6_addr)); *multicast = !!IN6_IS_ADDR_MULTICAST(&IP_AS_V6(*ss, addr)); } else if (use->ai_family == AF_INET) { ss->ss_family = AF_INET; IP_AS_V4(*ss, port) = htons(port); IP_AS_V4(*ss, addr) = ((struct sockaddr_in *)use->ai_addr)->sin_addr; *multicast = !!IN_MULTICAST(ntohl(IP_AS_V4(*ss, addr.s_addr))); } freeaddrinfo(ressave); if (ss->ss_family != AF_INET && ss->ss_family != AF_INET6) { tvherror(uc->subsystem, "%s - failed to process host '%s'", uc->name, uc->host); return -1; } return 0; }
static int linuxdvb_ca_rm_changed_cb(void *arg, uint8_t slot_id, uint16_t session_num) { linuxdvb_ca_t * lca = arg; tvhtrace("en50221", "rm changed cb received for slot %d", slot_id); if (en50221_app_rm_enq(lca->lca_rm_resource, session_num)) { tvherror("en50221", "failed to send ENQ to slot %d", slot_id); } return 0; }
void api_register ( const api_hook_t *hook ) { api_link_t *t; SKEL_ALLOC(api_skel); api_skel->hook = hook; t = RB_INSERT_SORTED(&api_hook_tree, api_skel, link, ah_cmp); if (t) { tvherror("api", "trying to re-register subsystem"); } else { SKEL_USED(api_skel); } }
void api_register ( const api_hook_t *hook ) { static api_link_t *t, *skel = NULL; if (!skel) skel = calloc(1, sizeof(api_link_t)); skel->hook = hook; t = RB_INSERT_SORTED(&api_hook_tree, skel, link, ah_cmp); if (t) tvherror("api", "trying to re-register subsystem"); else skel = NULL; }
static int linuxdvb_ca_dt_enquiry_cb(void *arg, uint8_t slot_id, uint16_t session_num, uint8_t response_int) { linuxdvb_ca_t * lca = arg; tvhtrace("en50221", "datetime enquiry cb received for slot %d", slot_id); if (en50221_app_datetime_send(lca->lca_dt_resource, session_num, time(NULL), -1)) { tvherror("en50221", "Failed to send datetime to slot %d", slot_id); } return 0; }
/** * Create a new libavformat based muxer */ muxer_t* lav_muxer_create(const muxer_config_t *m_cfg) { const char *mux_name; lav_muxer_t *lm; AVOutputFormat *fmt; switch(m_cfg->m_type) { case MC_MPEGPS: mux_name = "dvd"; break; case MC_MATROSKA: case MC_AVMATROSKA: mux_name = "matroska"; break; case MC_WEBM: case MC_AVWEBM: mux_name = "webm"; break; case MC_AVMP4: mux_name = "mp4"; break; default: mux_name = muxer_container_type2txt(m_cfg->m_type); break; } fmt = av_guess_format(mux_name, NULL, NULL); if(!fmt) { tvherror(LS_LIBAV, "Can't find the '%s' muxer", mux_name); return NULL; } lm = calloc(1, sizeof(lav_muxer_t)); lm->m_open_stream = lav_muxer_open_stream; lm->m_open_file = lav_muxer_open_file; lm->m_init = lav_muxer_init; lm->m_reconfigure = lav_muxer_reconfigure; lm->m_mime = lav_muxer_mime; lm->m_add_marker = lav_muxer_add_marker; lm->m_write_meta = lav_muxer_write_meta; lm->m_write_pkt = lav_muxer_write_pkt; lm->m_close = lav_muxer_close; lm->m_destroy = lav_muxer_destroy; lm->lm_oc = avformat_alloc_context(); lm->lm_oc->oformat = fmt; lm->lm_fd = -1; lm->lm_init = 0; return (muxer_t*)lm; }
int urlparse ( const char *str, url_t *url ) { regmatch_t m[16]; char buf[16]; if (str == NULL || url == NULL) return -1; urlreset(url); /* Create regexp */ if (!urlparse_exp) { urlparse_exp = calloc(1, sizeof(regex_t)); if (regcomp(urlparse_exp, URL_RE, REG_ICASE | REG_EXTENDED)) { tvherror("url", "failed to compile regexp"); exit(1); } } /* Execute */ if (regexec(urlparse_exp, str, ARRAY_SIZE(m), m, 0)) return -1; /* Extract data */ #define copy(x, i)\ {\ x = strndup(str+m[i].rm_so, m[i].rm_eo - m[i].rm_so);\ }(void)0 #define copy_static(x, i)\ {\ int len = m[i].rm_eo - m[i].rm_so;\ if (len >= sizeof(x) - 1)\ len = sizeof(x) - 1;\ memcpy(x, str+m[i].rm_so, len);\ x[len] = 0;\ }(void)0 copy(url->scheme, 1); copy(url->user, 3); copy(url->pass, 5); copy(url->host, 6); copy(url->path, 9); copy_static(buf, 8); url->port = atoi(buf); copy(url->query, 11); copy(url->frag, 13); url->raw = strdup(str); return 0; }
/* * Receive data */ static int iptv_rtsp_data ( http_client_t *hc, void *buf, size_t len ) { iptv_mux_t *im = hc->hc_aux; if (im == NULL) return 0; if (len > 0) tvherror("iptv", "unknown data %zd received for '%s'", len, im->mm_iptv_url); return 0; }
/** * Replace various chars with a dash */ static char * cleanup_filename(char *s, dvr_config_t *cfg) { int i, len = strlen(s), len2; char *s1; s1 = intlconv_utf8safestr(cfg->dvr_charset_id, s, len * 2); if (s1 == NULL) { tvherror("dvr", "Unsupported charset %s using ASCII", cfg->dvr_charset); s1 = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1), s, len * 2); if (s1 == NULL) return NULL; } s = s1; /* Do not create hidden files */ if (s[0] == '.') s[0] = '_'; len2 = strlen(s); for (i = 0; i < len2; i++) { if(s[i] == '/') s[i] = '-'; else if(cfg->dvr_whitespace_in_title && (s[i] == ' ' || s[i] == '\t')) s[i] = '-'; else if(cfg->dvr_clean_title && ((s[i] < 32) || (s[i] > 122) || (strchr("/:\\<>|*?'\"", s[i]) != NULL))) s[i] = '_'; else if(cfg->dvr_windows_compatible_filenames && (strchr("/:\\<>|*?'\"", s[i]) != NULL)) s[i] = '_'; } if(cfg->dvr_windows_compatible_filenames) { // trim trailing spaces and dots for (i = len2 - 1; i >= 0; i--) { if((s[i] != ' ') && (s[i] != '.')) break; s[i] = '\0'; } } return s; }
static int linuxdvb_ca_rm_enq_cb(void *arg, uint8_t slot_id, uint16_t session_num) { linuxdvb_ca_t * lca = arg; tvhtrace("en50221", "rm enq callback received for slot %d", slot_id); if (en50221_app_rm_reply(lca->lca_rm_resource, session_num, sizeof(resource_ids)/4, resource_ids)) { tvherror("en50221", "failed to send rm reply to slot %u session %u", slot_id, session_num); } return 0; }
int dvr_rec_subscribe(dvr_entry_t *de) { char buf[100]; int weight; profile_t *pro; profile_chain_t *prch; struct sockaddr sa; access_t *aa; uint32_t rec_count, net_count; int c1, c2; assert(de->de_s == NULL); assert(de->de_chain == NULL); if(de->de_pri >= 0 && de->de_pri < ARRAY_SIZE(prio2weight)) weight = prio2weight[de->de_pri]; else weight = 300; snprintf(buf, sizeof(buf), "DVR: %s", lang_str_get(de->de_title, NULL)); if (de->de_owner && de->de_owner[0] != '\0') aa = access_get_by_username(de->de_owner); else if (de->de_creator && de->de_creator[0] != '\0' && tcp_get_ip_from_str(de->de_creator, &sa) != NULL) aa = access_get_by_addr(&sa); else { tvherror(LS_DVR, "unable to find access (owner '%s', creator '%s')", de->de_owner, de->de_creator); return -EPERM; } if (aa->aa_conn_limit || aa->aa_conn_limit_dvr) { rec_count = dvr_usage_count(aa); net_count = aa->aa_conn_limit ? tcp_connection_count(aa) : 0; /* the rule is: allow if one condition is OK */ c1 = aa->aa_conn_limit ? rec_count + net_count >= aa->aa_conn_limit : -1; c2 = aa->aa_conn_limit_dvr ? rec_count >= aa->aa_conn_limit_dvr : -1; if (c1 && c2) { tvherror(LS_DVR, "multiple connections are not allowed for user '%s' from '%s' " "(limit %u, dvr limit %u, active DVR %u, streaming %u)", aa->aa_username ?: "", aa->aa_representative ?: "", aa->aa_conn_limit, aa->aa_conn_limit_dvr, rec_count, net_count); access_destroy(aa); return -EOVERFLOW; }
static void linuxdvb_ca_monitor ( void *aux ) { linuxdvb_ca_t *lca = aux; ca_slot_info_t csi; int state; csi.num = 0; if (lca->lca_ca_fd >= 0) { if ((ioctl(lca->lca_ca_fd, CA_GET_SLOT_INFO, &csi)) != 0) { tvherror("linuxdvb", "failed to get CAM slot %u info [e=%s]", csi.num, strerror(errno)); } if (csi.flags & CA_CI_MODULE_READY) state = CA_SLOT_STATE_MODULE_READY; else if (csi.flags & CA_CI_MODULE_PRESENT) state = CA_SLOT_STATE_MODULE_PRESENT; else state = CA_SLOT_STATE_EMPTY; lca->lca_state_str = ca_slot_state2str(state); if (lca->lca_state != state) { tvhlog(LOG_INFO, "linuxdvb", "CAM slot %u status changed to %s", csi.num, lca->lca_state_str); idnode_notify_title_changed(&lca->lca_id, NULL); lca->lca_state = state; } if ((!lca->lca_en50221_thread_running) && (state == CA_SLOT_STATE_MODULE_READY)) { lca->lca_en50221_thread_running = 1; tvhthread_create(&lca->lca_en50221_thread, NULL, linuxdvb_ca_en50221_thread, lca); } else if (lca->lca_en50221_thread_running && (state != CA_SLOT_STATE_MODULE_READY)) { lca->lca_en50221_thread_running = 0; pthread_join(lca->lca_en50221_thread, NULL); } } gtimer_arm_ms(&lca->lca_monitor_timer, linuxdvb_ca_monitor, lca, 250); }