Example #1
0
static void parse_dc_event(char *line, struct membuffer *str, void *_dc)
{
	int m, s = 0;
	const char *name;
	struct divecomputer *dc = _dc;
	struct event event = { 0 };

	m = strtol(line, &line, 10);
	if (*line == ':')
		s = strtol(line+1, &line, 10);
	event.time.seconds = m*60+s;

	for (;;) {
		char c;
		while (isspace(c = *line))
			line++;
		if (!c)
			break;
		line = parse_keyvalue_entry(parse_event_keyvalue, &event, line);
	}

	name = "";
	if (str->len)
		name = mb_cstring(str);
	add_event(dc, event.time.seconds, event.type, event.flags, event.value, name);
}
Example #2
0
/*
 * Note that the act of "getting" the error string
 * buffer doesn't de-allocate the buffer, but it does
 * set the buffer length to zero, so that any future
 * error reports will overwrite the string rather than
 * append to it.
 */
const char *get_error_string(void)
{
	const char *str;

	if (!error_string_buffer.len)
		return "";
	str = mb_cstring(&error_string_buffer);
	error_string_buffer.len = 0;
	return str;
}
Example #3
0
int report_error(const char *fmt, ...)
{
	struct membuffer *buf = &error_string_buffer;

	/* Previous unprinted errors? Add a newline in between */
	if (buf->len)
		put_bytes(buf, "\n", 1);
	VA_BUF(buf, fmt);
	mb_cstring(buf);
	return -1;
}
Example #4
0
static void parse_site_geo(char *line, struct membuffer *str, void *_ds)
{
	struct dive_site *ds = _ds;
	if (ds->taxonomy.category == NULL)
		ds->taxonomy.category = alloc_taxonomy();
	int nr = ds->taxonomy.nr;
	if (nr < TC_NR_CATEGORIES) {
		struct taxonomy *t = &ds->taxonomy.category[nr];
		t->value = strdup(mb_cstring(str));
		sscanf(line, "cat %d origin %d \"", &t->category, (int *)&t->origin);
		ds->taxonomy.nr++;
	}
}
Example #5
0
int report_error(const char *fmt, ...)
{
	struct membuffer buf = { 0 };

	/* if there is no error callback registered, don't produce errors */
	if (!error_cb)
		return -1;

	VA_BUF(&buf, fmt);
	mb_cstring(&buf);
	error_cb(detach_buffer(&buf));

	return -1;
}
Example #6
0
static int tree_insert(git_treebuilder *dir, const char *name, int mkunique, git_oid *id, unsigned mode)
{
	int ret;
	struct membuffer uniquename = { 0 };

	if (mkunique && git_treebuilder_get(dir, name)) {
		char hex[8];
		git_oid_nfmt(hex, 7, id);
		hex[7] = 0;
		put_format(&uniquename, "%s~%s", name, hex);
		name = mb_cstring(&uniquename);
	}
	ret = git_treebuilder_insert(NULL, dir, name, id, mode);
	free_buffer(&uniquename);
	return ret;
}
Example #7
0
/*
 * Write a membuffer to the git repo, and free it
 */
static int blob_insert(git_repository *repo, struct dir *tree, struct membuffer *b, const char *fmt, ...)
{
	int ret;
	git_oid blob_id;
	struct membuffer name = { 0 };

	ret = git_blob_create_frombuffer(&blob_id, repo, b->buffer, b->len);
	free_buffer(b);
	if (ret)
		return ret;

	VA_BUF(&name, fmt);
	ret = tree_insert(tree->files, mb_cstring(&name), 1, &blob_id, GIT_FILEMODE_BLOB);
	free_buffer(&name);
	return ret;
}
Example #8
0
static void parse_dc_event(char *line, struct membuffer *str, void *_dc)
{
	int m, s = 0;
	const char *name;
	struct divecomputer *dc = _dc;
	struct event event = { 0 }, *ev;

	m = strtol(line, &line, 10);
	if (*line == ':')
		s = strtol(line+1, &line, 10);
	event.time.seconds = m*60+s;

	for (;;) {
		char c;
		while (isspace(c = *line))
			line++;
		if (!c)
			break;
		line = parse_keyvalue_entry(parse_event_keyvalue, &event, line);
	}

	name = "";
	if (str->len)
		name = mb_cstring(str);
	ev = add_event(dc, event.time.seconds, event.type, event.flags, event.value, name);

	/*
	 * Older logs might mark the dive to be CCR by having an "SP change" event at time 0:00.
	 * Better to mark them being CCR on import so no need for special treatments elsewhere on
	 * the code.
	 */
	if (ev && event.time.seconds == 0 && event.type == SAMPLE_EVENT_PO2 && dc->divemode==OC) {
		dc->divemode = CCR;
	}

	if (ev && event_is_gaschange(ev)) {
		/*
		 * We subtract one here because "0" is "no index",
		 * and the parsing will add one for actual cylinder
		 * index data (see parse_event_keyvalue)
		 */
		ev->gas.index = event.gas.index-1;
		if (event.gas.mix.o2.permille || event.gas.mix.he.permille)
			ev->gas.mix = event.gas.mix;
	}
}
Example #9
0
void subsurface_user_info(struct user_info *user)
{
	struct passwd *pwd = getpwuid(getuid());
	const char *username = getenv("USER");

	if (pwd) {
		if (pwd->pw_gecos && *pwd->pw_gecos)
			user->name = pwd->pw_gecos;
		if (!username)
			username = pwd->pw_name;
	}
	if (username && *username) {
		char hostname[64];
		struct membuffer mb = { 0 };
		gethostname(hostname, sizeof(hostname));
		put_format(&mb, "%s@%s", username, hostname);
		user->email = mb_cstring(&mb);
	}
}
Example #10
0
/*
 * The 'divecomputerid' is a bit harder to parse than some other things, because
 * it can have multiple strings (but see the tag parsing for another example of
 * that) in addition to the non-string entries.
 *
 * We keep the "next" string in "id.cstr" and update it as we use it.
 */
static void parse_settings_divecomputerid(char *line, struct membuffer *str, void *_unused)
{
	struct divecomputerid id = { mb_cstring(str) };

	id.cstr = id.model + strlen(id.model) + 1;

	/* Skip the '"' that stood for the model string */
	line++;

	for (;;) {
		char c;
		while (isspace(c = *line))
			line++;
		if (!c)
			break;
		line = parse_keyvalue_entry(parse_divecomputerid_keyvalue, &id, line);
	}
	create_device_node(id.model, id.deviceid, id.serial, id.firmware, id.nickname);
}
Example #11
0
/*
 * We can have multiple tags in the membuffer. They are separated by
 * NUL bytes.
 */
static void parse_dive_tags(char *line, struct membuffer *str, void *_dive)
{
	struct dive *dive = _dive;
	const char *tag;
	int len = str->len;

	if (!len)
		return;

	/* Make sure there is a NUL at the end too */
	tag = mb_cstring(str);
	for (;;) {
		int taglen = strlen(tag);
		if (taglen)
			taglist_add_tag(&dive->tag_list, tag);
		len -= taglen;
		if (!len)
			return;
		tag += taglen+1;
		len--;
	}
}
Example #12
0
/* keyvalue "key" "value"
 * so we have two strings (possibly empty) in the membuffer, separated by a '\0' */
static void parse_dc_keyvalue(char *line, struct membuffer *str, void *_dc)
{
	const char *key, *value;
	struct divecomputer *dc = _dc;

	// Let's make sure we have two strings...
	int string_counter = 0;
	while(*line) {
		if (*line == '"')
			string_counter++;
		line++;
	}
	if (string_counter != 2)
		return;

	// stupidly the second string in the membuffer isn't NUL terminated;
	// asking for a cstring fixes that; interestingly enough, given that there are two
	// strings in the mb, the next command at the same time assigns a pointer to the
	// first string to 'key' and NUL terminates the second string (which then goes to 'value')
	key = mb_cstring(str);
	value = key + strlen(key) + 1;
	add_extra_data(dc, key, value);
}
Example #13
0
/*
 * This does *not* make sure the new subdirectory doesn't
 * alias some existing name. That is actually useful: you
 * can create multiple directories with the same name, and
 * set the "unique" flag, which will then append the SHA1
 * of the directory to the name when it is written.
 */
static struct dir *new_directory(struct dir *parent, struct membuffer *namebuf)
{
	struct dir *subdir;
	const char *name = mb_cstring(namebuf);
	int len = namebuf->len;

	subdir = malloc(sizeof(*subdir)+len);

	/*
	 * It starts out empty: no subdirectories of its own,
	 * and an empty treebuilder list of files.
	 */
	subdir->subdirs = NULL;
	git_treebuilder_create(&subdir->files, NULL);
	memcpy(subdir->name, name, len);
	subdir->unique = 0;
	subdir->name[len] = 0;

	/* Add it to the list of subdirs of the parent */
	subdir->sibling = parent->subdirs;
	parent->subdirs = subdir;

	return subdir;
}
Example #14
0
static void parse_dc_event(char *line, struct membuffer *str, void *_dc)
{
	int m, s = 0;
	const char *name;
	struct divecomputer *dc = _dc;
	struct event event = { 0 }, *ev;

	m = strtol(line, &line, 10);
	if (*line == ':')
		s = strtol(line+1, &line, 10);
	event.time.seconds = m*60+s;

	for (;;) {
		char c;
		while (isspace(c = *line))
			line++;
		if (!c)
			break;
		line = parse_keyvalue_entry(parse_event_keyvalue, &event, line);
	}

	name = "";
	if (str->len)
		name = mb_cstring(str);
	ev = add_event(dc, event.time.seconds, event.type, event.flags, event.value, name);
	if (ev && event_is_gaschange(ev)) {
		/*
		 * We subtract one here because "0" is "no index",
		 * and the parsing will add one for actual cylinder
		 * index data (see parse_event_keyvalue)
		 */
		ev->gas.index = event.gas.index-1;
		if (event.gas.mix.o2.permille || event.gas.mix.he.permille)
			ev->gas.mix = event.gas.mix;
	}
}
Example #15
0
static void parse_site_name(char *line, struct membuffer *str, void *_ds)
{ (void) line; struct dive_site *ds = _ds; ds->name = strdup(mb_cstring(str)); }
Example #16
0
static void parse_site_description(char *line, struct membuffer *str, void *_ds)
{ struct dive_site *ds = _ds; ds->description = strdup(mb_cstring(str)); }
Example #17
0
static void parse_site_notes(char *line, struct membuffer *str, void *_ds)
{ struct dive_site *ds = _ds; ds->notes = strdup(mb_cstring(str)); }
// TODO: This looks like should be ported to C code. or a big part of it.
bool DivelogsDeWebServices::prepare_dives_for_divelogs(const QString &tempfile, const bool selected)
{
	static const char errPrefix[] = "divelog.de-upload:";
	if (!amount_selected) {
		report_error(tr("no dives were selected").toUtf8());
		return false;
	}

	xsltStylesheetPtr xslt = NULL;
	struct zip *zip;

	xslt = get_stylesheet("divelogs-export.xslt");
	if (!xslt) {
		qDebug() << errPrefix << "missing stylesheet";
		return false;
	}


	int error_code;
	zip = zip_open(QFile::encodeName(QDir::toNativeSeparators(tempfile)), ZIP_CREATE, &error_code);
	if (!zip) {
		char buffer[1024];
		zip_error_to_str(buffer, sizeof buffer, error_code, errno);
		report_error(tr("failed to create zip file for upload: %s").toUtf8(), buffer);
		return false;
	}

	/* walk the dive list in chronological order */
	int i;
	struct dive *dive;
	struct membuffer mb = { 0 };
	for_each_dive (i, dive) {
		FILE *f;
		char filename[PATH_MAX];
		int streamsize;
		const char *membuf;
		xmlDoc *transformed;
		struct zip_source *s;

		/*
		 * Get the i'th dive in XML format so we can process it.
		 * We need to save to a file before we can reload it back into memory...
		 */
		if (selected && !dive->selected)
			continue;
		/* make sure the buffer is empty and add the dive */
		mb.len = 0;
		save_one_dive_to_mb(&mb, dive);
		membuf = mb_cstring(&mb);
		streamsize = strlen(membuf);
		/*
		 * Parse the memory buffer into XML document and
		 * transform it to divelogs.de format, finally dumping
		 * the XML into a character buffer.
		 */
		xmlDoc *doc = xmlReadMemory(membuf, streamsize, "divelog", NULL, 0);
		if (!doc) {
			qWarning() << errPrefix << "could not parse back into memory the XML file we've just created!";
			report_error(tr("internal error").toUtf8());
			goto error_close_zip;
		}
		free((void *)membuf);

		transformed = xsltApplyStylesheet(xslt, doc, NULL);
		xmlDocDumpMemory(transformed, (xmlChar **)&membuf, &streamsize);
		xmlFreeDoc(doc);
		xmlFreeDoc(transformed);

		/*
		 * Save the XML document into a zip file.
		 */
		snprintf(filename, PATH_MAX, "%d.xml", i + 1);
		s = zip_source_buffer(zip, membuf, streamsize, 1);
		if (s) {
			int64_t ret = zip_add(zip, filename, s);
			if (ret == -1)
				qDebug() << errPrefix << "failed to include dive:" << i;
		}
	}