static pixmap_t * fa_image_from_video(const char *url0, const image_meta_t *im, char *errbuf, size_t errlen, int *cache_control, cancellable_t *c) { static char *stated_url; static fa_stat_t fs; time_t stattime = 0; time_t mtime = 0; pixmap_t *pm = NULL; char cacheid[512]; char *url = mystrdupa(url0); char *tim = strchr(url, '#'); const char *siz; *tim++ = 0; int secs = atoi(tim); hts_mutex_lock(&image_from_video_mutex[0]); if(strcmp(url, stated_url ?: "")) { free(stated_url); stated_url = NULL; if(fa_stat(url, &fs, errbuf, errlen)) { hts_mutex_unlock(&image_from_video_mutex[0]); return NULL; } stated_url = strdup(url); } stattime = fs.fs_mtime; hts_mutex_unlock(&image_from_video_mutex[0]); if(im->im_req_width < 100 && im->im_req_height < 100) { siz = "min"; } else if(im->im_req_width < 200 && im->im_req_height < 200) { siz = "mid"; } else { siz = "max"; } snprintf(cacheid, sizeof(cacheid), "%s-%s", url0, siz); buf_t *b = blobcache_get(cacheid, "videothumb", 0, 0, NULL, &mtime); if(b != NULL && mtime == stattime) { pm = pixmap_alloc_coded(b->b_ptr, b->b_size, PIXMAP_JPEG); buf_release(b); return pm; } buf_release(b); if(ONLY_CACHED(cache_control)) { snprintf(errbuf, errlen, "Not cached"); return NULL; } hts_mutex_lock(&image_from_video_mutex[1]); pm = fa_image_from_video2(url, im, cacheid, errbuf, errlen, secs, stattime, c); hts_mutex_unlock(&image_from_video_mutex[1]); return pm; }
/** * Load a view file and do lexographical parsing * * Returns pointer to last token, or NULL if an error occured. * If an error occured 'ei' will be filled with data */ token_t * glw_view_load1(glw_root_t *gr, rstr_t *url, errorinfo_t *ei, token_t *prev, int may_unlock) { token_t *last; char errbuf[256]; rstr_t *p = fa_absolute_path(url, prev->file); if(may_unlock) glw_unlock(gr); buf_t *b = fa_load(rstr_get(p), FA_LOAD_VPATHS(gr->gr_vpaths), FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)), NULL); if(may_unlock) glw_lock(gr); if(b == NULL) { snprintf(ei->error, sizeof(ei->error), "Unable to open \"%s\" -- %s", rstr_get(p), errbuf); snprintf(ei->file, sizeof(ei->file), "%s", rstr_get(prev->file)); ei->line = prev->line; rstr_release(p); return NULL; } last = glw_view_lexer(gr, buf_cstr(b), ei, p, prev); buf_release(b); rstr_release(p); return last; }
static GLuint glw_compile_shader(const char *path, int type, glw_root_t *gr) { GLint v, len; GLuint s; char log[4096]; buf_t *b; if((b = fa_load(path, FA_LOAD_VPATHS(gr->gr_vpaths), FA_LOAD_ERRBUF(log, sizeof(log)), NULL)) == NULL) { TRACE(TRACE_ERROR, "glw", "Unable to load shader %s -- %s", path, log); return 0; } b = buf_make_writable(b); char *src = buf_str(b); s = glCreateShader(type); glShaderSource(s, 1, (const char **)&src, NULL); glCompileShader(s); glGetShaderInfoLog(s, sizeof(log), &len, log); glGetShaderiv(s, GL_COMPILE_STATUS, &v); buf_release(b); if(!v) { TRACE(TRACE_ERROR, "GLW", "Unable to compile shader %s", path); TRACE(TRACE_ERROR, "GLW", "%s", log); return 0; } return s; }
/* * Format the seqset `seq' as a string. Returns a newly allocated * string which must be free()d by the caller. */ EXPORTED char *seqset_cstring(const struct seqset *seq) { struct buf buf = BUF_INITIALIZER; unsigned i; if (!seq) return NULL; if (!seq->len) return NULL; for (i = 0; i < seq->len; i++) { /* join with comma if not the first item */ if (i) buf_putc(&buf, ','); /* single value only */ if (seq->set[i].low == seq->set[i].high) format_num(&buf, seq->set[i].low); /* value range */ else { format_num(&buf, seq->set[i].low); buf_putc(&buf, ':'); format_num(&buf, seq->set[i].high); } } return buf_release(&buf); }
static event_t * be_gmeplayer_play(const char *url0, media_pipe_t *mp, char *errbuf, size_t errlen, int hold, const char *mimetype) { event_t *e; char *url, *p; int track; url0 += strlen("gmeplayer:"); url = mystrdupa(url0); p = strrchr(url, '/'); if(p == NULL) { snprintf(errbuf, errlen, "Invalid filename"); return NULL; } *p++= 0; track = atoi(p) - 1; buf_t *b; if((b = fa_load(url, NULL, errbuf, errlen, NULL, 0, NULL, NULL)) == NULL) return NULL; e = fa_gme_playfile_internal(mp, b->b_ptr, b->b_size, errbuf, errlen, hold, track, url0); buf_release(b); return e; }
static void write_thumb(const AVCodecContext *src, const AVFrame *sframe, int width, int height, const char *cacheid, time_t mtime) { if(thumbcodec == NULL) return; AVCodecContext *ctx = thumbctx; if(ctx == NULL || ctx->width != width || ctx->height != height) { if(ctx != NULL) { avcodec_close(ctx); free(ctx); } ctx = avcodec_alloc_context3(thumbcodec); ctx->pix_fmt = AV_PIX_FMT_YUVJ420P; ctx->time_base.den = 1; ctx->time_base.num = 1; ctx->sample_aspect_ratio.num = 1; ctx->sample_aspect_ratio.den = 1; ctx->width = width; ctx->height = height; if(avcodec_open2(ctx, thumbcodec, NULL) < 0) { TRACE(TRACE_ERROR, "THUMB", "Unable to open thumb encoder"); thumbctx = NULL; return; } thumbctx = ctx; } AVFrame *oframe = av_frame_alloc(); avpicture_alloc((AVPicture *)oframe, ctx->pix_fmt, width, height); struct SwsContext *sws; sws = sws_getContext(src->width, src->height, src->pix_fmt, width, height, ctx->pix_fmt, SWS_BILINEAR, NULL, NULL, NULL); sws_scale(sws, (const uint8_t **)sframe->data, sframe->linesize, 0, src->height, &oframe->data[0], &oframe->linesize[0]); sws_freeContext(sws); oframe->pts = AV_NOPTS_VALUE; AVPacket out; memset(&out, 0, sizeof(AVPacket)); int got_packet; int r = avcodec_encode_video2(ctx, &out, oframe, &got_packet); if(r >= 0 && got_packet) { buf_t *b = buf_create_and_adopt(out.size, out.data, &av_free); blobcache_put(cacheid, "videothumb", b, INT32_MAX, NULL, mtime, 0); buf_release(b); } else { assert(out.data == NULL); } av_frame_free(&oframe); }
int audio_decoder_init (dtaudio_decoder_t * decoder) { int ret = 0; pthread_t tid; /*select decoder */ ret = select_audio_decoder (decoder); if (ret < 0) { ret = -1; goto ERR0; } /*init decoder */ decoder->pts_current = decoder->pts_first = -1; decoder->decoder_priv = decoder->aparam.avctx_priv; if (decoder->aparam.num == 0 || decoder->aparam.den == 0) decoder->aparam.num = decoder->aparam.den = 1; else dt_info (TAG, "[%s:%d] param: num:%d den:%d\n", __FUNCTION__, __LINE__, decoder->aparam.num, decoder->aparam.den); ad_wrapper_t *wrapper = decoder->wrapper; ret = wrapper->init (wrapper,decoder); if (ret < 0) { ret = -1; goto ERR0; } dt_info (TAG, "[%s:%d] audio decoder init ok\n", __FUNCTION__, __LINE__); /*init pcm buffer */ dtaudio_context_t *actx = (dtaudio_context_t *) decoder->parent; int size = DTAUDIO_PCM_BUF_SIZE; ret = buf_init (&actx->audio_decoded_buf, size); if (ret < 0) { ret = -1; goto ERR1; } /*create thread */ ret = pthread_create (&tid, NULL, audio_decode_loop, (void *) decoder); if (ret != 0) { dt_info (DTAUDIO_LOG_TAG, "create audio decoder thread failed\n"); ret = -1; goto ERR2; } decoder->audio_decoder_pid = tid; audio_decoder_start (decoder); return ret; ERR2: buf_release (&actx->audio_decoded_buf); ERR1: wrapper->release (wrapper); ERR0: return ret; }
int audio_decoder_stop (dtaudio_decoder_t * decoder) { ad_wrapper_t *wrapper = decoder->wrapper; /*Decode thread exit */ decoder->status = ADEC_STATUS_EXIT; pthread_join (decoder->audio_decoder_pid, NULL); wrapper->release (wrapper); /*uninit buf */ dtaudio_context_t *actx = (dtaudio_context_t *) decoder->parent; buf_release (&actx->audio_decoded_buf); dt_info (DTAUDIO_LOG_TAG, "audio decoder stop ok\n"); return 0; }
/* * Create a sync log reader object which will read from the given sync log * channel 'channel'. The channel may be NULL for the default channel. * Returns a new object which must be freed with sync_log_reader_free(). * Does not return NULL. */ EXPORTED sync_log_reader_t *sync_log_reader_create_with_channel(const char *channel) { sync_log_reader_t *slr = sync_log_reader_alloc(); struct buf buf = BUF_INITIALIZER; slr->log_file = xstrdup(sync_log_fname(channel)); /* Create a work log filename. We will process this * first if it exists */ buf_printf(&buf, "%s-run", slr->log_file); slr->work_file = buf_release(&buf); return slr; }
event_t * fa_gme_playfile(media_pipe_t *mp, fa_handle_t *fh, char *errbuf, size_t errlen, int hold, const char *url) { buf_t *b; event_t *e; if((b = fa_load_and_close(fh)) == NULL) { snprintf(errbuf, errlen, "Unable to read data from file"); return NULL; } e = fa_gme_playfile_internal(mp, b->b_ptr, b->b_size, errbuf, errlen, hold, 0, url); buf_release(b); return e; }
int demuxer_close(dtdemuxer_context_t * dem_ctx) { int i = 0; demuxer_wrapper_t *wrapper = dem_ctx->demuxer; wrapper->close(wrapper); /*free media info */ dtp_media_info_t *info = &(dem_ctx->media_info); track_info_t *tracks = &(info->tracks); if (info->has_audio) for (i = 0; i < tracks->ast_num; i++) { if (tracks->astreams[i] == NULL) { continue; } if (tracks->astreams[i]->extradata_size) { free(tracks->astreams[i]->extradata); } free(tracks->astreams[i]); tracks->astreams[i] = NULL; } if (info->has_video) for (i = 0; i < tracks->vst_num; i++) { if (tracks->vstreams[i] == NULL) { continue; } free(tracks->vstreams[i]); tracks->vstreams[i] = NULL; } if (info->has_sub) for (i = 0; i < tracks->sst_num; i++) { if (tracks->sstreams[i] == NULL) { continue; } if (tracks->sstreams[i]->extradata_size) { free(tracks->sstreams[i]->extradata); } free(tracks->sstreams[i]); tracks->sstreams[i] = NULL; } /* release probe buf */ buf_release(&dem_ctx->probe_buf); /* close stream */ dtstream_close(dem_ctx->stream_priv); return 0; }
static htsmsg_t * tmdb_load_movie_cast(const char *lookup_id) { char url[300]; char errbuf[256]; buf_t *result; snprintf(url, sizeof(url), "http://api.themoviedb.org/3/movie/%s/casts", lookup_id); retry: tmdb_check_rate_limit(); int http_response_code = 0; struct http_header_list response_headers; LIST_INIT(&response_headers); result = fa_load(url, FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)), FA_LOAD_QUERY_ARG("api_key", TMDB_APIKEY), FA_LOAD_QUERY_ARG("language", getlang()), FA_LOAD_RESPONSE_HEADERS(&response_headers), FA_LOAD_PROTOCOL_CODE(&http_response_code), FA_LOAD_FLAGS(FA_COMPRESSION), NULL); if(result == NULL) { if(http_response_code == 429) { tmdb_handle_rate_limit(&response_headers); goto retry; } http_headers_free(&response_headers); TRACE(TRACE_INFO, "TMDB", "Load error %s", errbuf); return NULL; } http_headers_free(&response_headers); htsmsg_t *doc = htsmsg_json_deserialize2(buf_cstr(result), errbuf, sizeof(errbuf)); if(doc == NULL) { TRACE(TRACE_ERROR, "TMDB", "Got bad JSON from %s -- %s", url, errbuf); } buf_release(result); return doc; }
static int getmetadata(void *sc, const char *extname, const char *keyname, char **res) { script_data_t *sd = (script_data_t *)sc; struct buf attrib = BUF_INITIALIZER; char *intname = extname ? mboxname_from_external(extname, sd->ns, mbname_userid(sd->mbname)) : xstrdup(""); int r; if (!strncmp(keyname, "/private/", 9)) { r = annotatemore_lookup(intname, keyname+8, mbname_userid(sd->mbname), &attrib); } else if (!strncmp(keyname, "/shared/", 8)) { r = annotatemore_lookup(intname, keyname+7, "", &attrib); } else { r = IMAP_MAILBOX_NONEXISTENT; } *res = (r || !attrib.len) ? NULL : buf_release(&attrib); free(intname); buf_free(&attrib); return r ? 0 : 1; }
/** * Load entire image into memory using fileaccess load method. * Faster than open+read+close. */ static image_t * fa_imageloader2(const char *url, const char **vpaths, char *errbuf, size_t errlen, int *cache_control, cancellable_t *c) { buf_t *buf; buf = fa_load(url, FA_LOAD_VPATHS(vpaths), FA_LOAD_ERRBUF(errbuf, errlen), FA_LOAD_CACHE_CONTROL(cache_control), FA_LOAD_CANCELLABLE(c), FA_LOAD_FLAGS(FA_CONTENT_ON_ERROR), NULL); if(buf == NULL || buf == NOT_MODIFIED) return (image_t *)buf; image_t *img = fa_imageloader_buf(buf, errbuf, errlen); buf_release(buf); return img; }
JSBool js_cache_get(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { buf_t *b; char stash[256]; char errbuf[256]; const char *key,*lstash; JSObject *o; js_plugin_t *jsp = JS_GetPrivate(cx, obj); if (!JS_ConvertArguments(cx, argc, argv, "ss", &lstash, &key)) return JS_FALSE; // fetch json from cache snprintf(stash, sizeof(stash), "plugin/%s/%s", jsp->jsp_id, lstash); b = blobcache_get(key, stash, 0, NULL, NULL, NULL); if(b == NULL) { *rval = OBJECT_TO_JSVAL(NULL); return JS_TRUE; } // deserialize into json object if(!JS_EnterLocalRootScope(cx)) return JS_FALSE; o = json_deserialize(buf_cstr(b), &json_to_jsapi, cx, errbuf, sizeof(errbuf)); buf_release(b); *rval = OBJECT_TO_JSVAL(o); JS_LeaveLocalRootScope(cx); if(o == NULL) { JS_ReportError(cx, "Invalid JSON stored in cache -- %s", errbuf); return JS_FALSE; } return JS_TRUE; }
static int tmdb_configure(void) { hts_mutex_lock(&tmdb_mutex); if(!tmdb_configured) { buf_t *result; char errbuf[256]; result = fa_load("http://api.themoviedb.org/3/configuration", FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)), FA_LOAD_QUERY_ARG("api_key", TMDB_APIKEY), FA_LOAD_QUERY_ARG("language", getlang()), FA_LOAD_FLAGS(FA_COMPRESSION | FA_IMPORTANT), NULL); if(result == NULL) { TRACE(TRACE_INFO, "TMDB", "Unable to get configuration -- %s", errbuf); goto done; } htsmsg_t *doc = htsmsg_json_deserialize2(buf_cstr(result), errbuf, sizeof(errbuf)); buf_release(result); if(doc == NULL) { TRACE(TRACE_ERROR, "TMDB", "Got bad JSON from config -- %s", errbuf); goto done; } tmdb_parse_config(doc); htsmsg_release(doc); tmdb_configured = 1; } done: hts_mutex_unlock(&tmdb_mutex); return !tmdb_configured; }
void cvs_add_loginfo(char *repo) { BUF *buf; char pwd[MAXPATHLEN]; if (getcwd(pwd, sizeof(pwd)) == NULL) fatal("Can't get working directory"); buf = buf_alloc(1024); cvs_trigger_loginfo_header(buf, repo); buf_puts(buf, "Log Message:\nDirectory "); buf_puts(buf, current_cvsroot->cr_dir); buf_putc(buf, '/'); buf_puts(buf, repo); buf_puts(buf, " added to the repository\n"); buf_putc(buf, '\0'); loginfo = buf_release(buf); }
JSBool js_get_descriptor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { char pdesc[PATH_MAX]; char *pe; buf_t *b; char errbuf[128]; JSObject *o; js_plugin_t *jsp = JS_GetPrivate(cx, obj); snprintf(pdesc, sizeof(pdesc),"%s", jsp->jsp_url); pe = strrchr(pdesc, '/'); if (pe == NULL) return JS_FALSE; snprintf(pe + 1, sizeof(pdesc) - (pe - pdesc), "plugin.json"); b = fa_load(pdesc, FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)), NULL); if (b == NULL) { TRACE(TRACE_ERROR, "JS", "Unable to read %s -- %s", pdesc, errbuf); return JS_FALSE; } if (!JS_EnterLocalRootScope(cx)) return JS_FALSE; o = json_deserialize(buf_cstr(b), &json_to_jsapi, cx, errbuf, sizeof(errbuf)); buf_release(b); *rval = OBJECT_TO_JSVAL(o); JS_LeaveLocalRootScope(cx); return JS_TRUE; }
static loaded_msg_t * htsmsg_store_obtain(const char *key, int create) { char errbuf[512]; htsmsg_t *r = NULL; loaded_msg_t *lm; LIST_FOREACH(lm, &loaded_msgs, lm_link) if(!strcmp(lm->lm_key, key)) return lm; buf_t *b = persistent_load("settings", key, errbuf, sizeof(errbuf)); if(b == NULL) { if(!create) { return NULL; } } else { r = htsmsg_json_deserialize(buf_cstr(b)); buf_release(b); if(r == NULL && !create) return NULL; } if(r == NULL) r = htsmsg_create_map(); lm = calloc(1, sizeof(loaded_msg_t)); atomic_set(&lm->lm_refcount, 1); lm->lm_key = strdup(key); LIST_INSERT_HEAD(&loaded_msgs, lm, lm_link); lm->lm_msg = r; callout_arm_managed(&lm->lm_timer, htsmsg_store_timer_cb, lm, SETTINGS_CACHE_DELAY, htsmsg_store_lockmgr); return lm; }
JSBool js_cache_put(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { char stash[256]; const char *key,*lstash; uint32_t len, maxage; JSObject *o; htsbuf_queue_t out; js_plugin_t *jsp = JS_GetPrivate(cx, obj); if (!JS_ConvertArguments(cx, argc, argv, "ssou", &lstash, &key, &o, &maxage)) return JS_FALSE; if (o == NULL) { JS_ReportError(cx, "Not an object"); return JS_FALSE; } // json encode object htsbuf_queue_init(&out, 0); if (js_json_encode_from_object(cx, o, &out) != 0) { JS_ReportError(cx, "Not an JSON object"); return JS_FALSE; } len = out.hq_size; buf_t *b = buf_create(len + 1); htsbuf_read(&out, b->b_ptr, len); buf_str(b)[len] = '\0'; // put json encoded object onto cache snprintf(stash, sizeof(stash), "plugin/%s/%s", jsp->jsp_id, lstash); blobcache_put(key, stash, b, maxage, NULL, 0, 0); buf_release(b); return JS_TRUE; }
static image_t * thumb_from_attachment(const char *url, int64_t offset, int size, char *errbuf, size_t errlen, const char *cacheid, time_t mtime) { fa_handle_t *fh = fa_open(url, errbuf, errlen); if(fh == NULL) return NULL; fh = fa_slice_open(fh, offset, size); buf_t *buf = fa_load_and_close(fh); if(buf == NULL) { snprintf(errbuf, errlen, "Load error"); return NULL; } image_t *img = fa_imageloader_buf(buf, errbuf, errlen); if(img != NULL) { blobcache_put(cacheid, "videothumb", buf, INT32_MAX, NULL, mtime, 0); } buf_release(buf); return img; }
/** * Load entire image into memory using fileaccess load method. * Faster than open+read+close. */ static pixmap_t * fa_imageloader2(const char *url, const char **vpaths, char *errbuf, size_t errlen, int *cache_control, cancellable_t *c) { buf_t *buf; jpeg_meminfo_t mi; pixmap_type_t fmt; int width = -1, height = -1, orientation = 0; buf = fa_load(url, FA_LOAD_VPATHS(vpaths), FA_LOAD_ERRBUF(errbuf, errlen), FA_LOAD_CACHE_CONTROL(cache_control), FA_LOAD_CANCELLABLE(c), NULL); if(buf == NULL || buf == NOT_MODIFIED) return (pixmap_t *)buf; const uint8_t *p = buf_c8(buf); mi.data = p; mi.size = buf->b_size; if(buf->b_size < 16) goto bad; /* Probe format */ if((p[6] == 'J' && p[7] == 'F' && p[8] == 'I' && p[9] == 'F') || (p[6] == 'E' && p[7] == 'x' && p[8] == 'i' && p[9] == 'f')) { jpeginfo_t ji; if(jpeg_info(&ji, jpeginfo_mem_reader, &mi, JPEG_INFO_DIMENSIONS | JPEG_INFO_ORIENTATION, p, buf->b_size, errbuf, errlen)) { buf_release(buf); return NULL; } fmt = PIXMAP_JPEG; width = ji.ji_width; height = ji.ji_height; orientation = ji.ji_orientation; jpeg_info_clear(&ji); } else if(!memcmp(pngsig, p, 8)) { fmt = PIXMAP_PNG; } else if(!memcmp(gif87sig, p, sizeof(gif87sig)) || !memcmp(gif89sig, p, sizeof(gif89sig))) { fmt = PIXMAP_GIF; } else if(!memcmp(svgsig1, p, sizeof(svgsig1)) || !memcmp(svgsig2, p, sizeof(svgsig2))) { fmt = PIXMAP_SVG; } else { bad: snprintf(errbuf, errlen, "Unknown format"); buf_release(buf); return NULL; } pixmap_t *pm = pixmap_alloc_coded(p, buf->b_size, fmt); if(pm != NULL) { pm->pm_width = width; pm->pm_height = height; pm->pm_orientation = orientation; } else { snprintf(errbuf, errlen, "Out of memory"); } buf_release(buf); return pm; }
buf_t * gz_inflate(buf_t *bin, char *errbuf, size_t errlen) { z_stream z = {0}; unsigned char *out; size_t outlen; int r; if(!gz_check(bin)) { snprintf(errbuf, errlen, "Invalid header"); buf_release(bin); return NULL; } const uint8_t *in = buf_c8(bin); size_t inlen = bin->b_size; if(in[3] != 0) { snprintf(errbuf, errlen, "Header extensions is not supported"); buf_release(bin); return NULL; } in += 10; inlen -= 10; z.next_in = (void *)in; z.avail_in = inlen; if(inflateInit2(&z, -MAX_WBITS) != Z_OK) { snprintf(errbuf, errlen, "Inflate init failed"); buf_release(bin); return NULL; } outlen = inlen * 2; out = mymalloc(outlen + 1); if(out == NULL) { snprintf(errbuf, errlen, "Out of memory"); inflateEnd(&z); buf_release(bin); return NULL; } while(1) { if(outlen - z.total_out == 0) { outlen *= 2; out = realloc(out, outlen+1); } z.next_out = out + z.total_out; z.avail_out = outlen - z.total_out; r = inflate(&z, 0); if(r == Z_STREAM_END) break; if(r != Z_OK) { snprintf(errbuf, errlen, "inflate: %s", z.msg); inflateEnd(&z); free(out); buf_release(bin); return NULL; } } out[z.total_out] = 0; inflateEnd(&z); buf_release(bin); return buf_create_and_adopt(z.total_out, out, &free); }
static struct index_node_f *index_read(FILE *in, uint32_t offset) { struct index_node_f *node; char *prefix; int i, child_count = 0; if ((offset & INDEX_NODE_MASK) == 0) return NULL; fseek(in, offset & INDEX_NODE_MASK, SEEK_SET); if (offset & INDEX_NODE_PREFIX) { struct buffer buf; buf_init(&buf); buf_freadchars(&buf, in); prefix = buf_steal(&buf); } else prefix = NOFAIL(strdup("")); if (offset & INDEX_NODE_CHILDS) { char first = read_char(in); char last = read_char(in); child_count = last - first + 1; node = NOFAIL(malloc(sizeof(struct index_node_f) + sizeof(uint32_t) * child_count)); node->first = first; node->last = last; for (i = 0; i < child_count; i++) node->children[i] = read_long(in); } else { node = NOFAIL(malloc(sizeof(struct index_node_f))); node->first = INDEX_CHILDMAX; node->last = 0; } node->values = NULL; if (offset & INDEX_NODE_VALUES) { int value_count; struct buffer buf; const char *value; unsigned int priority; value_count = read_long(in); buf_init(&buf); while (value_count--) { priority = read_long(in); buf_freadchars(&buf, in); value = buf_str(&buf); add_value(&node->values, value, buf.used, priority); buf_clear(&buf); } buf_release(&buf); } node->prefix = prefix; node->file = in; return node; }
static void screenshot_process(void *task) { pixmap_t *pm = task; if(pm == NULL) { screenshot_response(NULL, "Screenshot not supported on this platform"); return; } TRACE(TRACE_DEBUG, "Screenshot", "Processing image %d x %d", pm->pm_width, pm->pm_height); int codecid = AV_CODEC_ID_PNG; if(screenshot_connection) codecid = AV_CODEC_ID_MJPEG; buf_t *b = screenshot_compress(pm, codecid); pixmap_release(pm); if(b == NULL) { screenshot_response(NULL, "Unable to compress image"); return; } if(!screenshot_connection) { char path[512]; char errbuf[512]; snprintf(path, sizeof(path), "%s/screenshot.png", gconf.cache_path); fa_handle_t *fa = fa_open_ex(path, errbuf, sizeof(errbuf), FA_WRITE, NULL); if(fa == NULL) { TRACE(TRACE_ERROR, "SCREENSHOT", "Unable to open %s -- %s", path, errbuf); buf_release(b); return; } fa_write(fa, buf_data(b), buf_len(b)); fa_close(fa); TRACE(TRACE_INFO, "SCREENSHOT", "Written to %s", path); buf_release(b); return; } buf_t *result = NULL; htsbuf_queue_t hq; htsbuf_queue_init(&hq, 0); htsbuf_append(&hq, "image=", 6); htsbuf_append_and_escape_url_len(&hq, buf_cstr(b), buf_len(b)); char errbuf[256]; int ret = http_req("https://api.imgur.com/3/upload", HTTP_FLAGS(FA_CONTENT_ON_ERROR), HTTP_REQUEST_HEADER("Authorization", "Client-ID 7c79b311d4797ed"), HTTP_RESULT_PTR(&result), HTTP_POSTDATA(&hq, "application/x-www-form-urlencoded"), HTTP_ERRBUF(errbuf, sizeof(errbuf)), NULL); if(ret) { screenshot_response(NULL, errbuf); } else { htsmsg_t *response = htsmsg_json_deserialize(buf_cstr(result)); if(response == NULL) { screenshot_response(NULL, "Unable to parse imgur response"); } else { if(htsmsg_get_u32_or_default(response, "success", 0)) { const char *url = htsmsg_get_str_multi(response, "data", "link", NULL); screenshot_response(url, "No link in imgur response"); } else { const char *msg = htsmsg_get_str_multi(response, "data", "error", NULL); if(msg == NULL) { screenshot_response(NULL, "Unkown imgur error"); } else { snprintf(errbuf, sizeof(errbuf), "Imgur error: %s", msg); screenshot_response(NULL, errbuf); } } htsmsg_release(response); } buf_release(result); } buf_release(b); }
static int gmefile_scandir(fa_dir_t *fd, const char *url, char *errbuf, size_t errlen) { char *p, *fpath = mystrdupa(url); char name[32]; char turl[URL_MAX]; int tracks, i; fa_dir_entry_t *fde; const char *title; Music_Emu *emu; gme_info_t *info; gme_err_t err; if((p = strrchr(fpath, '/')) == NULL) { snprintf(errbuf, errlen, "Invalid filename"); return -1; } *p = 0; buf_t *b; if((b = fa_load(fpath, NULL, errbuf, errlen, NULL, 0, NULL, NULL)) == NULL) return -1; err = gme_open_data(b->b_ptr, b->b_size, &emu, gme_info_only); buf_release(b); if(err != NULL) return 0; tracks = gme_track_count(emu); for(i = 0; i < tracks; i++) { snprintf(turl, sizeof(turl), "gmeplayer:%s/%d", fpath, i + 1); err = gme_track_info(emu, &info, i); if(err == NULL && info->song[0]) { title = info->song; } else { snprintf(name, sizeof(name), "Track %02d", i + 1); title = name; } fde = fa_dir_add(fd, turl, title, CONTENT_AUDIO); fde->fde_probestatus = FDE_PROBE_DEEP; fde->fde_metadata = prop_create_root("metadata"); prop_set_string(prop_create(fde->fde_metadata, "title"), title); if(err == NULL) { if(info->game[0]) prop_set_string(prop_create(fde->fde_metadata, "album"), info->game); if(info->author[0]) prop_set_string(prop_create(fde->fde_metadata, "artist"), info->author); prop_set_float(prop_create(fde->fde_metadata, "duration"), info->play_length / 1000.0); gme_free_info(info); } } gme_delete(emu); return 0; }
int cvs_import(int argc, char **argv) { int i, ch; char repo[MAXPATHLEN], *arg = "."; struct cvs_recursion cr; struct trigger_list *line_list; while ((ch = getopt(argc, argv, cvs_cmd_import.cmd_opts)) != -1) { switch (ch) { case 'b': import_branch = optarg; break; case 'd': dflag = 1; break; case 'k': koptstr = optarg; kflag = rcs_kflag_get(koptstr); if (RCS_KWEXP_INVAL(kflag)) { cvs_log(LP_ERR, "invalid RCS keyword expansion mode"); fatal("%s", cvs_cmd_import.cmd_synopsis); } break; case 'm': logmsg = optarg; break; default: fatal("%s", cvs_cmd_import.cmd_synopsis); break; } } argc -= optind; argv += optind; if (argc < 3) fatal("%s", cvs_cmd_import.cmd_synopsis); import_repository = argv[0]; vendor_tag = argv[1]; argc -= 2; argv += 2; release_tags = argv; tagcount = argc; if (!rcs_sym_check(vendor_tag)) fatal("invalid symbol: %s", vendor_tag); for (i = 0; i < tagcount; i++) { if (!rcs_sym_check(release_tags[i])) fatal("invalid symbol: %s", release_tags[i]); } if (logmsg == NULL) { if (cvs_server_active) fatal("no log message specified"); else logmsg = cvs_logmsg_create(NULL, NULL, NULL, NULL); } if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) { cvs_client_connect_to_server(); cvs_client_send_request("Argument -b%s", IMPORT_DEFAULT_BRANCH); if (kflag) cvs_client_send_request("Argument -k%s", koptstr); cvs_client_send_logmsg(logmsg); cvs_client_send_request("Argument %s", import_repository); cvs_client_send_request("Argument %s", vendor_tag); for (i = 0; i < tagcount; i++) cvs_client_send_request("Argument %s", release_tags[i]); cr.enterdir = NULL; cr.leavedir = NULL; cr.fileproc = cvs_client_sendfile; cr.flags = CR_RECURSE_DIRS; cvs_file_run(1, &arg, &cr); cvs_client_senddir("."); cvs_client_send_request("import"); cvs_client_get_responses(); return (0); } if (cvs_logmsg_verify(logmsg)) return (0); (void)xsnprintf(repo, sizeof(repo), "%s/%s", current_cvsroot->cr_dir, import_repository); import_loginfo(import_repository); if (cvs_noexec != 1) cvs_mkdir(repo, 0755); cr.enterdir = NULL; cr.leavedir = NULL; cr.fileproc = cvs_import_local; cr.flags = CR_RECURSE_DIRS; cvs_file_run(1, &arg, &cr); if (import_conflicts != 0) { import_printf("\n%d conflicts created by this import.\n\n", import_conflicts); import_printf("Use the following command to help the merge:\n"); import_printf("\topencvs checkout "); import_printf("-j%s:yesterday -j%s %s\n\n", vendor_tag, vendor_tag, import_repository); } else { import_printf("\nNo conflicts created by this import.\n\n"); } loginfo = buf_release(logbuf); logbuf = NULL; line_list = cvs_trigger_getlines(CVS_PATH_LOGINFO, import_repository); if (line_list != NULL) { cvs_trigger_handle(CVS_TRIGGER_LOGINFO, import_repository, loginfo, line_list, NULL); cvs_trigger_freelist(line_list); } xfree(loginfo); return (0); }
void load_site_news(void) { #if ENABLE_WEBPOPUP struct http_header_list response_headers; buf_t *b; char errbuf[512]; b = fa_load("https://movian.tv/projects/movian/news.json", FA_LOAD_FLAGS(FA_DISABLE_AUTH | FA_COMPRESSION), FA_LOAD_RESPONSE_HEADERS(&response_headers), FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)), NULL); if(b == NULL) { TRACE(TRACE_DEBUG, "News", "Unable to load news -- %s", errbuf); return; } const char *dateheader = http_header_get(&response_headers, "date"); if(dateheader == NULL) { buf_release(b); http_headers_free(&response_headers); return; } dateheader = mystrdupa(dateheader); http_headers_free(&response_headers); htsmsg_t *newsinfo = htsmsg_store_load("sitenews"); time_t no_news_before; if(newsinfo == NULL) newsinfo = htsmsg_create_map(); no_news_before = htsmsg_get_u32_or_default(newsinfo, "nothingbefore", 0); if(no_news_before == 0) { if(http_ctime(&no_news_before, dateheader)) { buf_release(b); htsmsg_release(newsinfo); return; } htsmsg_add_u32(newsinfo, "nothingbefore", no_news_before); htsmsg_store_save(newsinfo, "sitenews"); htsmsg_release(newsinfo); } htsmsg_t *doc = htsmsg_json_deserialize(buf_cstr(b)); buf_release(b); if(doc == NULL) { return; } hts_mutex_lock(&news_mutex); htsmsg_t *news = htsmsg_get_list(doc, "news"); if(news != NULL) { htsmsg_field_t *f; HTSMSG_FOREACH(f, news) { htsmsg_t *entry; if((entry = htsmsg_get_map_by_field(f)) == NULL) continue; const char *title = htsmsg_get_str(entry, "title"); const char *created_on = htsmsg_get_str(entry, "created_on"); int id = htsmsg_get_u32_or_default(entry, "id", 0); if(created_on == NULL || title == NULL || id == 0) continue; time_t t; if(parse_created_on_time(&t, created_on)) continue; if(t < no_news_before) continue; char idstr[64]; snprintf(idstr, sizeof(idstr), "sitenews:%d", id); prop_t *p = add_news_locked(idstr, title, NULL, "Read more", idstr); if(p != NULL) { prop_subscribe(PROP_SUB_TRACK_DESTROY, PROP_TAG_CALLBACK, open_news, p, PROP_TAG_ROOT, prop_create(p, "eventSink"), PROP_TAG_MUTEX, &news_mutex, NULL); } }
static char * parse_cmd(int type, char *cmd, const char *repo, struct file_info_list *file_info) { int expanded = 0; char argbuf[2] = { '\0', '\0' }; char *allowed_args, *default_args, *args, *file, *p, *q = NULL; size_t pos; BUF *buf; switch (type) { case CVS_TRIGGER_COMMITINFO: allowed_args = "prsS{}"; default_args = " %p/%r %S"; file = CVS_PATH_COMMITINFO; break; case CVS_TRIGGER_LOGINFO: allowed_args = "prsSvVt{}"; default_args = NULL; file = CVS_PATH_LOGINFO; break; case CVS_TRIGGER_VERIFYMSG: allowed_args = "l"; default_args = " %l"; file = CVS_PATH_VERIFYMSG; break; case CVS_TRIGGER_TAGINFO: allowed_args = "btoprsSvV{}"; default_args = " %t %o %p/%r %{sv}"; file = CVS_PATH_TAGINFO; break; default: return (NULL); } /* before doing any stuff, check if the command starts with % */ for (p = cmd; *p != '%' && !isspace((unsigned char)*p) && *p != '\0'; p++) ; if (*p == '%') return (NULL); buf = buf_alloc(1024); p = cmd; again: for (; *p != '\0'; p++) { if ((pos = strcspn(p, "$%")) != 0) { buf_append(buf, p, pos); p += pos; } q = NULL; if (*p == '\0') break; if (*p++ == '$') { if (*p == '{') { pos = strcspn(++p, "}"); if (p[pos] == '\0') goto bad; } else { for (pos = 0; isalpha(p[pos]); pos++) ; if (pos == 0) { cvs_log(LP_ERR, "unrecognized variable syntax"); goto bad; } } q = xmalloc(pos + 1); memcpy(q, p, pos); q[pos] = '\0'; if (expand_var(buf, q)) goto bad; p += pos - (*(p - 1) == '{' ? 0 : 1); } else { switch (*p) { case '\0': goto bad; case '{': if (strchr(allowed_args, '{') == NULL) goto bad; pos = strcspn(++p, "}"); if (p[pos] == '\0') goto bad; q = xmalloc(pos + 1); memcpy(q, p, pos); q[pos] = '\0'; args = q; p += pos; break; default: argbuf[0] = *p; args = argbuf; break; } if (expand_args(buf, file_info, repo, allowed_args, args)) goto bad; expanded = 1; } free(q); } if (!expanded && default_args != NULL) { p = default_args; expanded = 1; goto again; } buf_putc(buf, '\0'); return (buf_release(buf)); bad: free(q); cvs_log(LP_NOTICE, "%s contains malformed command '%s'", file, cmd); buf_free(buf); return (NULL); }
/** * Play given track. * * We only expect this to be called from the playqueue system. */ static event_t * be_sid2player_play(const char *url0, media_pipe_t *mp, char *errbuf, size_t errlen, int hold, const char *mimetype) { media_queue_t *mq = &mp->mp_audio; char *url, *p; int sample = 0; media_buf_t *mb = NULL; event_t *e; int subsong; int registered_play = 0; void *player; url0 += strlen("sidplayer:"); url = mystrdupa(url0); p = strrchr(url, '/'); if(p == NULL) { snprintf(errbuf, errlen, "Invalid filename"); return NULL; } *p++= 0; subsong = atoi(p); buf_t *b; if((b = fa_load(url, NULL, errbuf, errlen, NULL, 0, NULL, NULL)) == NULL) return NULL; player = sidcxx_load(b->b_ptr, b->b_size, subsong, errbuf, errlen); buf_release(b); if(player == NULL) return NULL; mp_set_playstatus_by_hold(mp, hold, NULL); mp->mp_audio.mq_stream = 0; mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_NONE, 0); mp_become_primary(mp); while(1) { if(mb == NULL) { mb = media_buf_alloc_unlocked(mp, sizeof(int16_t) * CHUNK_SIZE * 2); mb->mb_data_type = MB_AUDIO; mb->mb_channels = 2; mb->mb_rate = 44100; mb->mb_pts = sample * 1000000LL / mb->mb_rate; mb->mb_drive_clock = 1; if(!registered_play && mb->mb_pts > METADB_AUDIO_PLAY_THRESHOLD) { registered_play = 1; metadb_register_play(url0, 1, CONTENT_AUDIO); } sample += CHUNK_SIZE; int16_t *samples = mb->mb_data; sidcxx_play(player, samples, CHUNK_SIZE * sizeof(int16_t) * mb->mb_channels); // Crossmix 25% int i, l, r, L, R; for(i = 0; i < CHUNK_SIZE; i++) { l = samples[i * 2 + 0]; r = samples[i * 2 + 1]; L = 3 * l + r * 2; R = 3 * r + l * 2; L = L / 4; R = R / 4; if(L > 32767) L = 32767; if(L < -32768) L = -32768; if(R > 32767) R = 32767; if(R < -32768) R = -32768; samples[i * 2 + 0] = L; samples[i * 2 + 1] = R; } } if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) { mb = NULL; /* Enqueue succeeded */ continue; } if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) { mp_flush(mp, 0); break; } else if(event_is_action(e, ACTION_SKIP_BACKWARD) || event_is_action(e, ACTION_SKIP_FORWARD) || event_is_action(e, ACTION_STOP)) { mp_flush(mp, 0); break; } event_release(e); } sidcxx_stop(player); return e; }