static struct variant *new_variant(AppleHTTPContext *c, int bandwidth, const char *url, const char *base) { struct variant *var = av_mallocz(sizeof(struct variant)); if (!var) return NULL; reset_packet(&var->pkt); var->bandwidth = bandwidth; make_absolute_url(var->url, sizeof(var->url), base, url); dynarray_add(&c->variants, &c->n_variants, var); return var; }
static int parse_playlist(AppleHTTPContext *c, const char *url, struct variant *var, ByteIOContext *in) { int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0; char line[1024]; const char *ptr; int close_in = 0; if (!in) { close_in = 1; if ((ret = url_fopen(&in, url, URL_RDONLY)) < 0) return ret; } read_chomp_line(in, line, sizeof(line)); if (strcmp(line, "#EXTM3U")) { ret = AVERROR_INVALIDDATA; goto fail; } if (var) free_segment_list(var); c->finished = 0; while (!url_feof(in)) { read_chomp_line(in, line, sizeof(line)); if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) { struct variant_info info = {{0}}; is_variant = 1; ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args, &info); bandwidth = atoi(info.bandwidth); } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) { c->target_duration = atoi(ptr); } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) { if (!var) { var = new_variant(c, 0, url, NULL); if (!var) { ret = AVERROR(ENOMEM); goto fail; } } var->start_seq_no = atoi(ptr); } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) { c->finished = 1; } else if (av_strstart(line, "#EXTINF:", &ptr)) { is_segment = 1; duration = atoi(ptr); } else if (av_strstart(line, "#", NULL)) { continue; } else if (line[0]) { if (is_variant) { if (!new_variant(c, bandwidth, line, url)) { ret = AVERROR(ENOMEM); goto fail; } is_variant = 0; bandwidth = 0; } if (is_segment) { struct segment *seg; if (!var) { var = new_variant(c, 0, url, NULL); if (!var) { ret = AVERROR(ENOMEM); goto fail; } } seg = av_malloc(sizeof(struct segment)); if (!seg) { ret = AVERROR(ENOMEM); goto fail; } seg->duration = duration; make_absolute_url(seg->url, sizeof(seg->url), url, line); dynarray_add(&var->segments, &var->n_segments, seg); is_segment = 0; } } } c->last_load_time = av_gettime(); fail: if (close_in) url_fclose(in); return ret; }
static gboolean git_extract_submodule (const char *repo_url, GFile *checkout_dir, BuilderContext *context, GError **error) { g_autofree char *submodule_status = NULL; if (!git (checkout_dir, &submodule_status, error, "submodule", "status", NULL)) return FALSE; if (submodule_status) { int i; g_auto(GStrv) lines = g_strsplit (submodule_status, "\n", -1); for (i = 0; lines[i] != NULL; i++) { g_autoptr(GFile) mirror_dir = NULL; g_autoptr(GFile) child_dir = NULL; g_autofree char *child_url = NULL; g_autofree char *option = NULL; g_autofree char *child_relative_url = NULL; g_autofree char *mirror_dir_as_url = NULL; g_auto(GStrv) words = NULL; if (*lines[i] == 0) continue; words = g_strsplit (lines[i] + 1, " ", 3); option = g_strdup_printf ("submodule.%s.url", words[1]); if (!git (checkout_dir, &child_relative_url, error, "config", "-f", ".gitmodules", option, NULL)) return FALSE; /* Trim trailing whitespace */ g_strchomp (child_relative_url); g_print ("processing submodule %s\n", words[1]); child_url = make_absolute_url (repo_url, child_relative_url, error); if (child_url == NULL) return FALSE; mirror_dir = git_get_mirror_dir (child_url, context); mirror_dir_as_url = g_file_get_uri (mirror_dir); if (!git (checkout_dir, NULL, error, "config", option, mirror_dir_as_url, NULL)) return FALSE; if (!git (checkout_dir, NULL, error, "submodule", "update", "--init", words[1], NULL)) return FALSE; child_dir = g_file_resolve_relative_path (checkout_dir, words[1]); if (!git_extract_submodule (child_url, child_dir, context, error)) return FALSE; } } return TRUE; }
static gboolean git_mirror_submodules (const char *repo_url, gboolean update, GFile *mirror_dir, const char *revision, BuilderContext *context, GError **error) { g_autofree char *mirror_dir_path = NULL; g_autoptr(GFile) checkout_dir_template = NULL; g_autoptr(GFile) checkout_dir = NULL; g_autofree char *checkout_dir_path = NULL; g_autofree char *submodule_status = NULL; mirror_dir_path = g_file_get_path (mirror_dir); checkout_dir_template = g_file_get_child (builder_context_get_state_dir (context), "tmp-checkout-XXXXXX"); checkout_dir_path = g_file_get_path (checkout_dir_template); if (g_mkdtemp (checkout_dir_path) == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Can't create temporary checkout directory"); return FALSE; } checkout_dir = g_file_new_for_path (checkout_dir_path); if (!git (NULL, NULL, error, "clone", "-q", "--no-checkout", mirror_dir_path, checkout_dir_path, NULL)) return FALSE; if (!git (checkout_dir, NULL, error, "checkout", "-q", "-f", revision, NULL)) return FALSE; if (!git (checkout_dir, &submodule_status, error, "submodule", "status", NULL)) return FALSE; if (submodule_status) { int i; g_auto(GStrv) lines = g_strsplit (submodule_status, "\n", -1); for (i = 0; lines[i] != NULL; i++) { g_autofree char *url = NULL; g_autofree char *option = NULL; g_autofree char *old = NULL; g_auto(GStrv) words = NULL; if (*lines[i] == 0) continue; words = g_strsplit (lines[i] + 1, " ", 3); option = g_strdup_printf ("submodule.%s.url", words[1]); if (!git (checkout_dir, &url, error, "config", "-f", ".gitmodules", option, NULL)) return FALSE; /* Trim trailing whitespace */ g_strchomp (url); old = url; url = make_absolute_url (repo_url, old, error); if (url == NULL) return FALSE; if (!git_mirror_repo (url, update, words[0], context, error)) return FALSE; } } if (!gs_shutil_rm_rf (checkout_dir, NULL, error)) return FALSE; return TRUE; }