import-gpt.c revision 901992209e3c87a4cf06b530d7b26ae2d35680ef
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/***
This file is part of systemd.
Copyright 2014 Lennart Poettering
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "hashmap.h"
#include "utf8.h"
#include "curl-util.h"
#include "import-gpt.h"
typedef struct GptImportFile GptImportFile;
struct GptImportFile {
char *url;
char *local;
struct curl_slist *request_header;
char *temp_path;
char *final_path;
char *etag;
char *old_etag;
bool force_local;
bool done;
int disk_fd;
};
struct GptImport {
void *userdata;
bool finished;
};
if (!f)
return NULL;
if (f->import)
safe_close(f->disk_fd);
free(f->final_path);
if (f->temp_path) {
}
free(f);
return NULL;
}
return;
if (import->on_finished)
else
}
GptImportFile *f = NULL;
long status;
int r;
return;
if (!f)
return;
f->done = true;
r = -EIO;
goto fail;
}
r = -EIO;
goto fail;
} else if (status == 304) {
log_info("File unmodified.");
r = 0;
goto fail;
} else if (status >= 300) {
r = -EIO;
goto fail;
} else if (status < 200) {
r = -EIO;
goto fail;
}
if (f->disk_fd < 0) {
log_error("No data received.");
r = -EIO;
goto fail;
}
f->content_length != f->written) {
log_error("Download truncated.");
r = -EIO;
goto fail;
}
if (f->etag)
if (f->mtime != 0) {
}
goto fail;
}
/* Mark read-only */
assert(f->final_path);
if (r < 0) {
goto fail;
}
r = 0;
fail:
gpt_import_finish(f->import, r);
}
static int gpt_import_file_open_disk(GptImportFile *f) {
int r;
assert(f);
if (f->disk_fd >= 0)
return 0;
assert(f->final_path);
if (!f->temp_path) {
if (r < 0)
return log_oom();
}
if (f->disk_fd < 0)
return 0;
}
static size_t gpt_import_file_write_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
GptImportFile *f = userdata;
ssize_t n;
int r;
assert(f);
r = gpt_import_file_open_disk(f);
if (r < 0)
goto fail;
log_error("File too large, overflow");
r = -EOVERFLOW;
goto fail;
}
log_error("Content length incorrect.");
r = -EFBIG;
goto fail;
}
if (n < 0) {
goto fail;
}
log_error("Short write");
r = -EIO;
goto fail;
}
return sz;
fail:
gpt_import_finish(f->import, r);
return 0;
}
static size_t gpt_import_file_header_callback(void *contents, size_t size, size_t nmemb, void *userdata) {
GptImportFile *f = userdata;
char *etag;
int r;
assert(f);
if (r < 0) {
log_oom();
goto fail;
}
if (r > 0) {
log_info("Image already up to date. Finishing.");
gpt_import_finish(f->import, 0);
return sz;
}
return sz;
}
if (r < 0) {
log_oom();
goto fail;
}
if (r > 0) {
return sz;
}
if (r < 0) {
log_oom();
goto fail;
}
if (r > 0) {
return sz;
}
return sz;
fail:
gpt_import_finish(f->import, r);
return 0;
}
static int gpt_import_file_begin(GptImportFile *f) {
int r;
assert(f);
if (r < 0)
return r;
if (f->old_etag) {
const char *hdr;
if (!f->request_header)
return -ENOMEM;
return -EIO;
}
return -EIO;
return -EIO;
return -EIO;
return -EIO;
if (r < 0)
return r;
return 0;
}
int gpt_import_new(GptImport **import, sd_event *event, gpt_import_on_finished on_finished, void *userdata) {
int r;
if (!i)
return -ENOMEM;
i->on_finished = on_finished;
if (event)
else {
r = sd_event_default(&i->event);
if (r < 0)
return r;
}
if (r < 0)
return r;
*import = i;
i = NULL;
return 0;
}
GptImportFile *f;
if (!import)
return NULL;
return NULL;
}
GptImportFile *f;
if (!f)
return 0;
return 1;
}
ssize_t n;
int r;
return -EEXIST;
if (r < 0)
return r;
if (!f)
return -ENOMEM;
f->disk_fd = -1;
if (!f->url)
return -ENOMEM;
if (!f->local)
return -ENOMEM;
if (!f->final_path)
return -ENOMEM;
if (n > 0) {
if (!f->old_etag)
return -ENOMEM;
}
if (r < 0)
return r;
r = gpt_import_file_begin(f);
if (r < 0) {
f = NULL;
return r;
}
f = NULL;
return 0;
}
bool gpt_url_is_valid(const char *url) {
return false;
return false;
return ascii_is_valid(url);
}