~ppsspp/ppsspp/ffmpeg-upstream

1 by Sérgio Benjamim
FFmpeg 2.7.1 source for ppsspp.
1
/*
2
 * URL utility functions
3
 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
23
#include "avformat.h"
24
#include "config.h"
25
#include "url.h"
26
#if CONFIG_NETWORK
27
#include "network.h"
28
#endif
29
#include "libavutil/avstring.h"
30
31
/**
32
 * @file
33
 * URL utility functions.
34
 */
35
36
int ff_url_join(char *str, int size, const char *proto,
37
                const char *authorization, const char *hostname,
38
                int port, const char *fmt, ...)
39
{
40
#if CONFIG_NETWORK
41
    struct addrinfo hints = { 0 }, *ai;
42
#endif
43
44
    str[0] = '\0';
45
    if (proto)
46
        av_strlcatf(str, size, "%s://", proto);
47
    if (authorization && authorization[0])
48
        av_strlcatf(str, size, "%s@", authorization);
49
#if CONFIG_NETWORK && defined(AF_INET6)
50
    /* Determine if hostname is a numerical IPv6 address,
51
     * properly escape it within [] in that case. */
52
    hints.ai_flags = AI_NUMERICHOST;
53
    if (!getaddrinfo(hostname, NULL, &hints, &ai)) {
54
        if (ai->ai_family == AF_INET6) {
55
            av_strlcat(str, "[", size);
56
            av_strlcat(str, hostname, size);
57
            av_strlcat(str, "]", size);
58
        } else {
59
            av_strlcat(str, hostname, size);
60
        }
61
        freeaddrinfo(ai);
62
    } else
63
#endif
64
        /* Not an IPv6 address, just output the plain string. */
65
        av_strlcat(str, hostname, size);
66
67
    if (port >= 0)
68
        av_strlcatf(str, size, ":%d", port);
69
    if (fmt) {
70
        va_list vl;
71
        size_t len = strlen(str);
72
73
        va_start(vl, fmt);
74
        vsnprintf(str + len, size > len ? size - len : 0, fmt, vl);
75
        va_end(vl);
76
    }
77
    return strlen(str);
78
}
79
80
void ff_make_absolute_url(char *buf, int size, const char *base,
81
                          const char *rel)
82
{
83
    char *sep, *path_query;
84
    /* Absolute path, relative to the current server */
85
    if (base && strstr(base, "://") && rel[0] == '/') {
86
        if (base != buf)
87
            av_strlcpy(buf, base, size);
88
        sep = strstr(buf, "://");
89
        if (sep) {
90
            /* Take scheme from base url */
91
            if (rel[1] == '/') {
92
                sep[1] = '\0';
93
            } else {
94
                /* Take scheme and host from base url */
95
                sep += 3;
96
                sep = strchr(sep, '/');
97
                if (sep)
98
                    *sep = '\0';
99
            }
100
        }
101
        av_strlcat(buf, rel, size);
102
        return;
103
    }
104
    /* If rel actually is an absolute url, just copy it */
105
    if (!base || strstr(rel, "://") || rel[0] == '/') {
106
        av_strlcpy(buf, rel, size);
107
        return;
108
    }
109
    if (base != buf)
110
        av_strlcpy(buf, base, size);
111
112
    /* Strip off any query string from base */
113
    path_query = strchr(buf, '?');
114
    if (path_query)
115
        *path_query = '\0';
116
117
    /* Is relative path just a new query part? */
118
    if (rel[0] == '?') {
119
        av_strlcat(buf, rel, size);
120
        return;
121
    }
122
123
    /* Remove the file name from the base url */
124
    sep = strrchr(buf, '/');
125
    if (sep)
126
        sep[1] = '\0';
127
    else
128
        buf[0] = '\0';
129
    while (av_strstart(rel, "../", NULL) && sep) {
130
        /* Remove the path delimiter at the end */
131
        sep[0] = '\0';
132
        sep = strrchr(buf, '/');
133
        /* If the next directory name to pop off is "..", break here */
134
        if (!strcmp(sep ? &sep[1] : buf, "..")) {
135
            /* Readd the slash we just removed */
136
            av_strlcat(buf, "/", size);
137
            break;
138
        }
139
        /* Cut off the directory name */
140
        if (sep)
141
            sep[1] = '\0';
142
        else
143
            buf[0] = '\0';
144
        rel += 3;
145
    }
146
    av_strlcat(buf, rel, size);
147
}
148
149
AVIODirEntry *ff_alloc_dir_entry(void)
150
{
151
    AVIODirEntry *entry = av_mallocz(sizeof(AVIODirEntry));
152
    if (entry) {
153
        entry->type = AVIO_ENTRY_UNKNOWN;
154
        entry->size = -1;
155
        entry->modification_timestamp = -1;
156
        entry->access_timestamp = -1;
157
        entry->status_change_timestamp = -1;
158
        entry->user_id = -1;
159
        entry->group_id = -1;
160
        entry->filemode = -1;
161
    }
162
    return entry;
163
}