~ubuntu-branches/ubuntu/utopic/cmake/utopic

« back to all changes in this revision

Viewing changes to Utilities/cmlibarchive/libarchive/archive_cmdline.c

  • Committer: Package Import Robot
  • Author(s): Harald Sitter
  • Date: 2013-10-10 12:54:39 UTC
  • mfrom: (1.14.7)
  • Revision ID: package-import@ubuntu.com-20131010125439-h0ahaj004on6oj92
Tags: 2.8.12-0ubuntu1
New upstream release LP: #1246701

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
2
 * Copyright (c) 2012 Michihiro NAKAJIMA 
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 * 1. Redistributions of source code must retain the above copyright
 
9
 *    notice, this list of conditions and the following disclaimer.
 
10
 * 2. Redistributions in binary form must reproduce the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer in the
 
12
 *    documentation and/or other materials provided with the distribution.
 
13
 *
 
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 
15
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
16
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
17
 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 
18
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
19
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
20
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
21
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
23
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
 
 
26
#include "archive_platform.h"
 
27
 
 
28
__FBSDID("$FreeBSD$");
 
29
 
 
30
#ifdef HAVE_STRING_H
 
31
#  include <string.h>
 
32
#endif
 
33
#ifdef HAVE_STDLIB_H
 
34
#  include <stdlib.h>
 
35
#endif
 
36
 
 
37
#include "archive.h"
 
38
#include "archive_cmdline_private.h"
 
39
#include "archive_string.h"
 
40
 
 
41
static int cmdline_set_path(struct archive_cmdline *, const char *);
 
42
static int cmdline_add_arg(struct archive_cmdline *, const char *);
 
43
 
 
44
static ssize_t
 
45
extract_quotation(struct archive_string *as, const char *p)
 
46
{
 
47
        const char *s;
 
48
 
 
49
        for (s = p + 1; *s;) {
 
50
                if (*s == '\\') {
 
51
                        if (s[1] != '\0') {
 
52
                                archive_strappend_char(as, s[1]);
 
53
                                s += 2;
 
54
                        } else
 
55
                                s++;
 
56
                } else if (*s == '"')
 
57
                        break;
 
58
                else {
 
59
                        archive_strappend_char(as, s[0]);
 
60
                        s++;
 
61
                }
 
62
        }
 
63
        if (*s != '"')
 
64
                return (ARCHIVE_FAILED);/* Invalid sequence. */
 
65
        return ((ssize_t)(s + 1 - p));
 
66
}
 
67
 
 
68
static ssize_t
 
69
get_argument(struct archive_string *as, const char *p)
 
70
{
 
71
        const char *s = p;
 
72
 
 
73
        archive_string_empty(as);
 
74
 
 
75
        /* Skip beginning space characters. */
 
76
        while (*s != '\0' && *s == ' ')
 
77
                s++;
 
78
        /* Copy non-space characters. */
 
79
        while (*s != '\0' && *s != ' ') {
 
80
                if (*s == '\\') {
 
81
                        if (s[1] != '\0') {
 
82
                                archive_strappend_char(as, s[1]);
 
83
                                s += 2;
 
84
                        } else {
 
85
                                s++;/* Ignore this character.*/
 
86
                                break;
 
87
                        }
 
88
                } else if (*s == '"') {
 
89
                        ssize_t q = extract_quotation(as, s);
 
90
                        if (q < 0)
 
91
                                return (ARCHIVE_FAILED);/* Invalid sequence. */
 
92
                        s += q;
 
93
                } else {
 
94
                        archive_strappend_char(as, s[0]);
 
95
                        s++;
 
96
                }
 
97
        }
 
98
        return ((ssize_t)(s - p));
 
99
}
 
100
 
 
101
/*
 
102
 * Set up command line arguments.
 
103
 * Returns ARChIVE_OK if everything okey.
 
104
 * Returns ARChIVE_FAILED if there is a lack of the `"' terminator or an
 
105
 * empty command line.
 
106
 * Returns ARChIVE_FATAL if no memory.
 
107
 */
 
108
int
 
109
__archive_cmdline_parse(struct archive_cmdline *data, const char *cmd)
 
110
{
 
111
        struct archive_string as;
 
112
        const char *p;
 
113
        ssize_t al;
 
114
        int r;
 
115
 
 
116
        archive_string_init(&as);
 
117
 
 
118
        /* Get first argument as a command path. */
 
119
        al = get_argument(&as, cmd);
 
120
        if (al < 0) {
 
121
                r = ARCHIVE_FAILED;/* Invalid sequence. */
 
122
                goto exit_function;
 
123
        }
 
124
        if (archive_strlen(&as) == 0) {
 
125
                r = ARCHIVE_FAILED;/* An empty command path. */
 
126
                goto exit_function;
 
127
        }
 
128
        r = cmdline_set_path(data, as.s);
 
129
        if (r != ARCHIVE_OK)
 
130
                goto exit_function;
 
131
        p = strrchr(as.s, '/');
 
132
        if (p == NULL)
 
133
                p = as.s;
 
134
        else
 
135
                p++;
 
136
        r = cmdline_add_arg(data, p);
 
137
        if (r != ARCHIVE_OK)
 
138
                goto exit_function;
 
139
        cmd += al;
 
140
 
 
141
        for (;;) {
 
142
                al = get_argument(&as, cmd);
 
143
                if (al < 0) {
 
144
                        r = ARCHIVE_FAILED;/* Invalid sequence. */
 
145
                        goto exit_function;
 
146
                }
 
147
                if (al == 0)
 
148
                        break;
 
149
                cmd += al;
 
150
                if (archive_strlen(&as) == 0 && *cmd == '\0')
 
151
                        break;
 
152
                r = cmdline_add_arg(data, as.s);
 
153
                if (r != ARCHIVE_OK)
 
154
                        goto exit_function;
 
155
        }
 
156
        r = ARCHIVE_OK;
 
157
exit_function:
 
158
        archive_string_free(&as);
 
159
        return (r);
 
160
}
 
161
 
 
162
/*
 
163
 * Set the program path.
 
164
 */
 
165
static int
 
166
cmdline_set_path(struct archive_cmdline *data, const char *path)
 
167
{
 
168
        char *newptr;
 
169
 
 
170
        newptr = realloc(data->path, strlen(path) + 1);
 
171
        if (newptr == NULL)
 
172
                return (ARCHIVE_FATAL);
 
173
        data->path = newptr;
 
174
        strcpy(data->path, path);
 
175
        return (ARCHIVE_OK);
 
176
}
 
177
 
 
178
/*
 
179
 * Add a argument for the program.
 
180
 */
 
181
static int
 
182
cmdline_add_arg(struct archive_cmdline *data, const char *arg)
 
183
{
 
184
        char **newargv;
 
185
 
 
186
        if (data->path == NULL)
 
187
                return (ARCHIVE_FAILED);
 
188
 
 
189
        newargv = realloc(data->argv, (data->argc + 2) * sizeof(char *));
 
190
        if (newargv == NULL)
 
191
                return (ARCHIVE_FATAL);
 
192
        data->argv = newargv;
 
193
        data->argv[data->argc] = strdup(arg);
 
194
        if (data->argv[data->argc] == NULL)
 
195
                return (ARCHIVE_FATAL);
 
196
        /* Set the terminator of argv. */
 
197
        data->argv[++data->argc] = NULL;
 
198
        return (ARCHIVE_OK);
 
199
}
 
200
 
 
201
struct archive_cmdline *
 
202
__archive_cmdline_allocate(void)
 
203
{
 
204
        return (struct archive_cmdline *)
 
205
                calloc(1, sizeof(struct archive_cmdline));
 
206
}
 
207
 
 
208
/*
 
209
 * Release the resources.
 
210
 */
 
211
int
 
212
__archive_cmdline_free(struct archive_cmdline *data)
 
213
{
 
214
 
 
215
        if (data) {
 
216
                free(data->path);
 
217
                if (data->argv != NULL) {
 
218
                        int i;
 
219
                        for (i = 0; data->argv[i] != NULL; i++)
 
220
                                free(data->argv[i]);
 
221
                        free(data->argv);
 
222
                }
 
223
                free(data);
 
224
        }
 
225
        return (ARCHIVE_OK);
 
226
}
 
227