Пример #1
0
/*
 * variable_add()
 *
 * dodaje zmienn± do listy zmiennych.
 *
 *  - name - nazwa,
 *  - short_name - krótka nazwa,
 *  - type - typ zmiennej,
 *  - display - czy i jak ma wy¶wietlaæ,
 *  - ptr - wska¼nik do zmiennej,
 *  - notify - funkcja powiadomienia,
 *  - map - mapa warto¶ci,
 *  - dyndisplay - funkcja sprawdzaj±ca czy wy¶wietliæ zmienn±.
 *
 * zwraca 0 je¶li siê uda³o, je¶li nie to -1.
 */
int variable_add(const char *name, const char *short_name, int type, int display, void *ptr, void (*notify)(const char*), struct value_map *map, int (*dyndisplay)(const char *name))
{
	struct variable v;
	list_t l;

	if (!name || (type != VAR_FOREIGN && !short_name))
		return -1;

	if (type != VAR_FOREIGN) {
		for (l = variables; l; l = l->next) {
			struct variable *v = l->data;

			if (!strcmp(v->short_name, short_name)) {
				fprintf(stderr, "Error! Variable short name conflict:\n- short name: \"%s\"\n- existing variable: \"%s\"\n- conflicting variable: \"%s\"\n\nPress any key to continue...", short_name, v->name, name);
				getchar();
			}
		}
	}

	memset(&v, 0, sizeof(v));

	v.name = xstrdup(name);
	v.name_hash = ekg_hash(name);
	v.type = type;
	if (short_name)
		strlcpy(v.short_name, short_name, sizeof(v.short_name));
	v.display = display;
	v.ptr = ptr;
	v.notify = notify;
	v.map = map;
	v.dyndisplay = dyndisplay;

	return (list_add(&variables, &v, sizeof(v)) ? 0 : -1);
}
Пример #2
0
/*
 * variable_remove()
 *
 * usuwa zmienn±.
 */
int variable_remove(plugin_t *plugin, const char *name) {
	int hash;
	GSList *vl;

	if (!name)
		return -1;

	hash = ekg_hash(name);

	for (vl = variables; vl; vl = vl->next) {
		variable_t *v = vl->data;
		if (!v->name)
			continue;
		
		if (hash == v->name_hash && plugin == v->plugin && !xstrcasecmp(name, v->name)) {
			variables_remove(v);
			return 0;
		}
	}
	return -1;
}
Пример #3
0
/*
 * variable_find()
 *
 * znajduje strukturê `variable' opisuj±c± zmienn± o podanej nazwie.
 *
 * - name.
 */
struct variable *variable_find(const char *name)
{
	list_t l;
	int hash;

	if (!name)
		return NULL;

	hash = ekg_hash(name);

	for (l = variables; l; l = l->next) {
		struct variable *v = l->data;

		if (!v->ptr)
			continue;

		if (v->name_hash == hash && !strcasecmp(v->name, name))
			return v;
	}

	return NULL;
}
Пример #4
0
/**
 * jogger_checkoutfile()
 *
 * Tries to open given file (check), and reads it, if expected (checkout).
 * It is designed to be proof to special file problems (especially named pipe ones).
 *
 * @param	file	- filename to open.
 * @param	data	- pointer to store file contents or NULL, if don't want to read it.
 * @param	len	- pointer to store filelength or NULL, if not needed.
 * @param	hash	- pointer to store filehash or NULL, if not needed.
 * @param	maxlen	- maximum filesize to accept (not counting additional NUL) or 0, if n/a.
 * @param	quiet	- if set, don't output anything to __status.
 *
 * @return	0 on success, errno on failure.
 */
static int jogger_checkoutfile(const char *file, char **data, int *len, char **hash, const int maxlen, const int quiet) {
	static char jogger_hash[sizeof(int)*2+3];
	int mylen, fs, fd;

	const char *fn	= prepare_path_user(file);

	if (!fn)
		return EINVAL;

	if ((fd = open(fn, O_RDONLY|O_NONBLOCK)) == -1) { /* we use O_NONBLOCK to get rid of FIFO problems */
		const int err = errno;
		if (err == ENXIO)
			printq("io_nonfile", file);
		else
			printq("io_cantopen", file, strerror(err));
		return err;
	}

	{
		struct stat st;

		if ((fstat(fd, &st) == -1) || !S_ISREG(st.st_mode)) {
			close(fd);
			printq("io_nonfile", file);
			return EISDIR; /* nearest, I think */
		}

		fs = st.st_size;
	}

	int bufsize	= (fs ? (maxlen && fs > maxlen ? maxlen+1 : fs+1) : 0x4000); /* we leave 1 byte for additional NUL */
	char *out	= xmalloc(bufsize);
	void *p		= out;
	int _read = 0, res;

	{
		int cf	= fcntl(fd, F_GETFL);

		if (cf == -1) /* evil thing */
			cf = 0;
		else
			cf &= ~O_NONBLOCK;
		fcntl(fd, F_SETFL, cf);
	}

	while ((res = read(fd, p, bufsize-_read))) {
		if (res == -1) {
			const int err = errno;
			if (err != EINTR && err != EAGAIN) {
				close(fd);
				printq("io_cantread", file, strerror(errno));
				return err;
			}
		} else {
			_read += res;
			if (maxlen && _read > maxlen) {
				xfree(out);
				printq("io_toobig", file, ekg_itoa(_read > fs ? _read : fs), ekg_itoa(maxlen));
				return EFBIG;
			} else if (_read == bufsize) { /* fs sucks? */
				bufsize += 0x4000;
				out	= xrealloc(out, bufsize);
				p	= out+_read;
			} else
				p	+= res;
		}
	}
	close(fd);

	if (_read == 0) {
		xfree(out);
		printq("io_emptyfile", file);
		return EINVAL; /* like mmap() */
	} else if (_read+1 != bufsize) {
		out		= xrealloc(out, _read+1);
		out[_read]	= 0; /* add NUL */
	}

	mylen = xstrlen(out);
	if (fs && _read > fs)
		printq("io_expanded", file, ekg_itoa(_read), ekg_itoa(fs));
	else if (_read < fs)
		printq("io_truncated", file, ekg_itoa(_read), ekg_itoa(fs));
	if (_read > mylen)
		printq("io_binaryfile", file, ekg_itoa(mylen), ekg_itoa(_read));
	if (len)
		*len = _read;

		/* I don't want to write my own hashing function, so using EKG2 one
		 * it will fail to hash data after any \0 in file, if there're any
		 * but we also aren't prepared to handle them */
	if (hash) {
		char sizecont[8];

		snprintf(sizecont, 8, "0x%%0%lux", sizeof(int)*2);
		snprintf(jogger_hash, sizeof(int)*2+3, sizecont, ekg_hash(out));
		*hash = jogger_hash;
	}

	if (data)
		*data = out;
	else
		xfree(out);

	return 0;
}