Example #1
0
/*
 * emoticon_read()
 *
 * ³aduje do listy wszystkie makra z pliku ~/.gg/emoticons
 * format tego pliku w dokumentacji.
 *
 * 0/-1
 */
int emoticon_read()
{
	const char *filename;
	char *buf, **emot;
	FILE *f;

	if (!(filename = prepare_path("emoticons", 0)))
		return -1;
	
	if (!(f = fopen(filename, "r")))
		return -1;

	while ((buf = read_file(f))) {
	
		if (buf[0] == '#') {
			xfree(buf);
			continue;
		}

		emot = array_make(buf, "\t", 2, 1, 1);
	
		if (array_count(emot) == 2)
			emoticon_add(emot[0], emot[1]);

		array_free(emot);
		xfree(buf);
	}
	
	fclose(f);
	
	return 0;
}
Example #2
0
char *jabber_sasl_digest_md5_response(session_t *s, char *challenge, const char *username, const char *password) {
	jabber_private_t *j =  s->priv;
	char **arr;
	char *retval, *nonce = NULL, *realm = NULL;
// XXX	char *rspauth	= NULL;
	int i;

	/* maybe we need to change/create another one parser... i'm not sure. please notify me, I'm lazy, sorry */
	/* for chrome.pl and jabber.autocom.pl it works */

	arr = array_make(challenge, "=,", 0, 1, 1);

	/* check data */
	if (g_strv_length(arr) & 1) {
		debug_error("Parsing var<=>value failed, NULL....\n");
		jabber_handle_disconnect(s, "IE, Current SASL support for ekg2 cannot handle with this data, sorry.", EKG_DISCONNECT_FAILURE);
		g_strfreev(arr);
		j->parser = NULL;
		return NULL;
	}

	/* parse data */
	i = 0;
	while (arr[i]) {
		char *tmp = strip_spaces(arr[i]);
		debug("md5_digest [%d] %s: %s\n", i / 2, arr[i], __(arr[i+1]));
		if (!xstrcmp(tmp, "realm"))		realm	= arr[i+1];
// XXX		else if (!xstrcmp(tmp, "rspauth"))	rspauth	= arr[i+1];
		else if (!xstrcmp(tmp, "nonce"))	nonce	= arr[i+1];
		i++;
		if (arr[i]) i++;
	}

	retval = sasl_auth_digest_md5(s, username, password, nonce, realm);

	g_strfreev(arr);

	return retval;
}
Example #3
0
/*
 * ncurses_contacts_update()
 *
 * updates contacts window 
 * 
 * it switches also groups, metacontacts, all together
 * details in documentation
 * 
 */
int ncurses_contacts_update(window_t *w, int save_pos) {
	int old_start;

	const char *header = NULL, *footer = NULL;
	char *group = NULL;
	int j;
	int all = 0; /* 1 - all, 2 - metacontacts */
	ncurses_window_t *n;
	newconference_t *c	= NULL;
	userlist_t *sorted_all	= NULL;
	int (*comp)(void *, void *) = NULL;		/* coz userlist's list are sorted we don't need to sort it again... 
								unfortunetly if we create list from serveral userlists (for instance: session && window)
								we must resort... --- in ekg2 we do 
									list_add_sorted(...., NULL) on session userlist &&
									list_add_sorted(...., contacts_compare) on window userlist
							*/

	
	if (!w) w = window_find_sa(NULL, "__contacts", 1);
	if (!w)
		return -1;

	n = w->priv_data;
	
	if (save_pos) 
		old_start = n->start;
	else
		old_start = 0;
	
	ncurses_clear(w, 1);

	if (!session_current)
		goto kon;

	if (config_contacts_groups) {
		char **groups = array_make(config_contacts_groups, ", ", 0, 1, 0);
		int count = array_count(groups);

		if (contacts_group_index > count + 2) {
			contacts_group_index = 0;
		} else if (contacts_group_index > count + 1) {
			if (metacontacts)
				all = 2;
			else
				contacts_group_index = 0;
		} else if (contacts_group_index > count) {
			all = 1;
		} else if (contacts_group_index > 0) {
			all = config_contacts_groups_all_sessions ? 1 : 0;
			group = groups[contacts_group_index - 1];
			if (*group == '@')
				group++;
			group = xstrdup(group);
			header = format_find("contacts_header_group");
			footer = format_find("contacts_footer_group");
		}
		array_free(groups);
	} else if (contacts_group_index) {
		if (contacts_group_index > ((metacontacts) ? 2 :1) )
			contacts_group_index = 0;
		else
			all = contacts_group_index;
	}

	if (all == 2) {
		header = format_find("contacts_metacontacts_header");
		footer = format_find("contacts_metacontacts_footer");
	}

	c = newconference_find(window_current->session, window_current->target);
	if (!session_current->userlist && !window_current->userlist && (!c || !c->participants) && !all && contacts_group_index == 0)
		goto kon;

	if (!header || !footer) {
		header = format_find("contacts_header");
		footer = format_find("contacts_footer");
	}

	if (format_ok(header))
		ncurses_backlog_add(w, fstring_new_format(header, group));

	if (all == 1) {
		userlist_t *l;
		session_t *s;

		for (s = sessions; s; s = s->next) {
			userlist_t *lp;

			if (!s->userlist)
				continue;

			for (lp = s->userlist; lp; lp = lp->next) {
				userlist_t *u = lp;

				if (!u->nickname)	/* don't add users without nickname.. */
					continue;

				LIST_ADD_SORTED2(&sorted_all, userlist_dup(u, u->uid, u->nickname, s), comp);
			}

			comp = contacts_compare;		/* turn on sorting */
		}

		for (l = c ? c->participants : window_current->userlist; l; l = l->next) {
			userlist_t *u = l;

			if (!u->nickname)	/* don't add users without nickname.. */
				continue;

			LIST_ADD_SORTED2(&sorted_all, userlist_dup(u, u->uid, u->nickname, w->session), comp);
		}

		if (sorted_all) comp = contacts_compare;	/* like above */
	}

	if (all == 1 || all == 2) {
		metacontact_t *m;

		/* Remove contacts contained in metacontacts. */
		if (all == 1 && config_contacts_metacontacts_swallow) {
			for (m = metacontacts; m; m = m->next) {
				metacontact_item_t *i;

				/* metacontact_find_prio() should always success [for current API] */
/*
				if (!metacontact_find_prio(m)) 
					continue;
*/
				for (i = m->metacontact_items; i; i = i->next) {
					userlist_t *u;
					userlist_t *sl;

					if (!(u = userlist_find_n(i->s_uid, i->name)))
						continue;

					for (sl = sorted_all; sl;) {
						userlist_t *up = sl;
						userlist_t *next = sl->next;;

			/* up->uid == u->uid (?) */
						if (up->uid && !xstrcmp(up->uid, u->uid))
							LIST_REMOVE2(&sorted_all, up, NULL);

						sl = next;
					}
				}
			}
		}

		for (m = metacontacts; m; m = m->next) {
			metacontact_item_t *i;
			userlist_t *u;

			if (!(i = metacontact_find_prio(m)))
				continue;

			if (!(u = userlist_find_n(i->s_uid, i->name)))
				continue;

			if (!m->name)	/* don't add metacontacts without name.. */
				continue;

			LIST_ADD_SORTED2(&sorted_all, userlist_dup(u, NULL, m->name, (void *) 2), comp);
		}
	}

	if (!all) {
		sorted_all = session_current->userlist;

		if (c && c->participants) 
			sorted_all = c->participants;
		else if (window_current->userlist)
			sorted_all = window_current->userlist;
	}

	if (!sorted_all)
		goto after_loop;	/* it skips this loop below */

	for (j = 0; j < corderlen; /* xstrlen(contacts_order); */ j += 2) {
		const char *footer_status = NULL;
		int count = 0;
		char tmp[100];
		userlist_t *ul;

		for (ul = sorted_all; ul; ul = ul->next) {
			userlist_t *u = ul;

			const char *status_t;
			const char *format;
			fstring_t *string;

			if (!u->nickname || !u->status) 
				continue;

			status_t = ekg_status_string(u->status, 0);

			if (config_contacts_orderbystate ?
				xstrncmp(contacts_order + j, status_t, 2) :		/* when config_contacts_orderbystate, we need to have got this status in contacts_order now. */
				!xstrstr(contacts_order, get_short_status(status_t)))	/* when !config_contacts_orderbystate, we need to have got this status in contacts_order anywhere. */
					continue;

			if (group && (!u->priv_data || (void *) 2 != u->priv_data)) {
				userlist_t *tmp = userlist_find(u->priv_data ? u->priv_data : session_current, u->uid);
				if ((group[0]=='!' && ekg_group_member(tmp, group+1)) ||
						(group[0]!='!' && !ekg_group_member(tmp, group)))
					continue;
			}

			if (!count) {
				snprintf(tmp, sizeof(tmp), "contacts_%s_header", status_t);
				format = format_find(tmp);
				if (format_ok(format))
					ncurses_backlog_add(w, fstring_new_format(format));
				footer_status = status_t;
			}

			if (u->descr && config_contacts_descr)
				snprintf(tmp, sizeof(tmp), "contacts_%s_descr_full", status_t);
			else if (u->descr && !config_contacts_descr)
				snprintf(tmp, sizeof(tmp), "contacts_%s_descr", status_t);
			else
				snprintf(tmp, sizeof(tmp), "contacts_%s", status_t);

			if (u->blink)
				xstrcat(tmp, "_blink");
			if (u->typing)
				xstrcat(tmp, "_typing");

			string = fstring_new_format(format_find(tmp), u->nickname, u->descr);

			if (u->priv_data == (void *) 2)
				string->priv_data = (void *) xstrdup(u->nickname);
			else 
				string->priv_data = (void *) saprintf("%s/%s", (u->priv_data) ? ((session_t *) u->priv_data)->uid : session_current->uid, u->nickname);

			ncurses_backlog_add(w, string);

			count++;
		}

		if (count) {
			const char *format;

			snprintf(tmp, sizeof(tmp), "contacts_%s_footer", footer_status);
			format = format_find(tmp);

			if (format_ok(format))
				ncurses_backlog_add(w, fstring_new_format(format));
		}

		if (!config_contacts_orderbystate)
			break;
	}

after_loop:
	if (format_ok(footer))
		ncurses_backlog_add(w, fstring_new_format(footer, group));
	if (all)
		LIST_DESTROY2(sorted_all, NULL);

	xfree(group);

kon:
/* restore old index */
	n->start = old_start;
	
	if (n->start > n->lines_count - w->height + n->overflow)
		n->start = n->lines_count - w->height + n->overflow;

	if (n->start < 0)
		n->start = 0;

/* redraw */
	n->redraw = 1;
	ncurses_redraw(w);

	return -1;
}
Example #4
0
/*
 * binding_parse()
 *
 * analizuje dan± akcjê i wype³nia pola struct binding odpowiedzialne
 * za dzia³anie.
 *
 *  - b - wska¼nik wype³nianej skruktury,
 *  - action - akcja,
 */
static void binding_parse(struct binding *b, const char *action)
{
    char **args;

    if (!b || !action)
        return;

    b->action = xstrdup(action);

    args = array_make(action, (" \t"), 1, 1, 1);

    if (!args[0]) {
        array_free(args);
        return;
    }

#define __action(x,y) \
	if (!xstrcmp(args[0], (x))) { \
		b->function = y; \
		b->arg = xstrdup(args[1]); \
	} else

    __action("backward-word", binding_backward_word)
    __action("forward-word", binding_forward_word)
    __action("kill-word", binding_kill_word)
    __action("toggle-input", binding_toggle_input)
    __action("cancel-input", binding_cancel_input)
    __action("backward-delete-char", binding_backward_delete_char)
    __action("beginning-of-line", binding_beginning_of_line)
    __action("end-of-line", binding_end_of_line)
    __action("delete-char", binding_delete_char)
    __action("backward-page", binding_backward_page)
    __action("forward-page", binding_forward_page)
    __action("kill-line", binding_kill_line)
    __action("window-kill", binding_window_kill)
    __action("yank", binding_yank)
    __action("accept-line", binding_accept_line)
    __action("line-discard", binding_line_discard)
    __action("quoted-insert", binding_quoted_insert)
    __action("word-rubout", binding_word_rubout)
    __action("backward-char", binding_backward_char)
    __action("forward-char", binding_forward_char)
    __action("previous-history", binding_previous_history)
    __action("previous-only-history", binding_previous_only_history)
    __action("next-history", binding_next_history)
    __action("next-only-history", binding_next_only_history)
    __action("complete", binding_complete)
    __action("quick-list", binding_quick_list_wrapper)
    __action("toggle-contacts", binding_toggle_contacts_wrapper)
    __action("next-contacts-group", binding_next_contacts_group)
    __action("ignore-query", binding_ignore_query)
    __action("ui-ncurses-debug-toggle", binding_ui_ncurses_debug_toggle)
    __action("cycle-sessions", binding_cycle_sessions)
    __action("forward-contacts-page", binding_forward_contacts_page)
    __action("backward-contacts-page", binding_backward_contacts_page)
    __action("forward-contacts-line", binding_forward_contacts_line)
    __action("backward-contacts-line", binding_backward_contacts_line)
    __action("forward-lastlog-page", binding_forward_lastlog_page)
    __action("backward-lastlog-page", binding_backward_lastlog_page)
    ; /* no/unknown action */


#undef __action

    array_free(args);
}
Example #5
0
File: misc.c Project: hiciu/ekg2
static void irc_access_parse(session_t *s, channel_t *chan, people_t *p, int flags) {
	userlist_t *ul;

	if (!s || !chan || !p)
		return;

#define dchar(x) debug("%c", x);

	for (ul = s->userlist; ul; ul = ul->next) {
		userlist_t *u = ul;
		ekg_resource_t *r = NULL, *rl;

		int i, j;

		if (!p->ident || !p->host) continue;

		if (xstrncmp(u->uid, "irc:", 4)) continue;	/* check for irc: */

		for (rl = u->resources; rl; rl = rl->next) {
			r = rl;

			if (r->priv_data == p) {
				const char *tmp = &(u->uid[4]);

				/* fast forward move.. */
				if (!(tmp = xstrchr(tmp, '!')) || !(tmp = xstrchr(tmp, '@')) || !(tmp = xstrchr(tmp, ':'))) {
					debug_error("%s:%d INTERNAL ERROR\n", __FILE__, __LINE__);
					goto next3;
				}
				tmp++;
				i = (tmp - u->uid);
				debug("irc, checkchan: %s\n", tmp);
				goto skip_identhost_check;
				break;	/* never here */
			}
		}
		r = NULL;
/* parse nick! */
		for (i = 4, j = 0; (u->uid[i] != '\0' && u->uid[i] != '!'); i++, j++) {
			dchar(u->uid[i]);

			if (u->uid[i] != p->ident[j]) {
				if (u->uid[i] == '*') j += do_sample_wildcard_match(&u->uid[i+1], &p->ident[j], '!');
				else if (u->uid[i] == '?') continue;
				else goto next;
			}
		} if (!u->uid[i]) goto next;
		dchar('!');
		i++;

/* parse ident@ */
		for (j = 0; (u->uid[i] != '\0' && u->uid[i] != '@'); i++, j++) {
			dchar(u->uid[i]);

			if (u->uid[i] != p->nick[j]) {
				if (u->uid[i] == '*') j += do_sample_wildcard_match(&u->uid[i+1], &p->ident[j], '@');
				else if (u->uid[i] == '?') continue;
				else goto next;
			}
		} if (!u->uid[i]) goto next;
		dchar('@');
		i++;

/* parse host: */
		for (j = 0; (u->uid[i] != '\0' && u->uid[i] != ':'); i++, j++) {
			dchar(u->uid[i]);

			if (u->uid[i] != p->host[j]) {
				if (u->uid[i] == '*') j += do_sample_wildcard_match(&u->uid[i+1], &p->ident[j], ':');
				else if (u->uid[i] == '?') continue;
				else goto next;
			}
		} if (!u->uid[i]) goto next;
		dchar('\n');
		i++;

		debug_error("irc_access_parse() %s!%s@%s MATCH with %s\n", p->ident, p->nick, p->host, u->uid+4);

skip_identhost_check:
/* let's rock with channels */
		{
			char **arr = array_make(&u->uid[i], ",", 0, 1, 0);

			int ismatch = 0;


			for (i=0; arr[i]; i++) {
				int k;
				debug_error("CHAN%d: %s: ", i, arr[i]);

				for (j = 0, k = 4 /* skip irc: */; arr[i][j]; j++, k++) {
					if (arr[i][j] != chan->name[k]) {
						if (arr[i][j] == '*') k += do_sample_wildcard_match(&arr[i][j+1], &chan->name[k], '\0');
						else if (arr[i][j] == '?') continue;
						else goto next2;
					}
				}
				if (chan->name[k] != '\0')
					goto next2;

				ismatch = 1;
				debug_error("MATCH\n");
				break;
next2:
				debug_error("NOT MATCH\n");
				continue;

			}
			g_strfreev(arr);

			if (!ismatch) continue;
		}
		if (!r) {
			char *tmp = irc_uid(p->nick);
			r = userlist_resource_add(u, tmp, 0);
			g_free(tmp);

			r->status	= EKG_STATUS_AVAIL;
			r->descr	= xstrdup(chan->name+4);
			r->priv_data	= p;

			if (u->status != EKG_STATUS_AVAIL) {
				xfree(u->descr);
				u->status	= EKG_STATUS_AVAIL;
				u->descr	= xstrdup("description... ?");
				query_emit(NULL, "userlist-changed", &(s->uid), &(u->uid));
			}
		} else {
			string_t str = string_init(r->descr);

			string_append_c(str, ',');
			string_append(str, chan->name+4);

			xfree(r->descr); r->descr = string_free(str, 0);
		}

		/* tutaj ladnie by wygladalo jakbysmy wywolali protocol-status.. ale jednak to jest b. kiepski pomysl */
		debug_error("USER: 0x%x PERMISION GRANTED ON CHAN: 0x%x\n", u, chan);
		continue;

next:
		dchar('\n');
		debug_error("irc_access_parse() %s!%s@%s NOT MATCH with %s\n", p->ident, p->nick, p->host, u->uid+4);
next3:
		continue;
	}
#undef dchar
}
Example #6
0
File: misc.c Project: hiciu/ekg2
int irc_parse_line(session_t *s, const char *l)
{
	static GString *strbuf = NULL;
	irc_private_t *j = s->priv;
	int	i, c=0, ecode, n_params;
	char	*p, *cmd, *colon2, **args = NULL, **pfxcmd = NULL;

	gchar *buf;
	int	len;

	if (G_UNLIKELY(!strbuf))
		strbuf = g_string_new(l);
	else
		g_string_assign(strbuf, l);

	irc_convert_in(j, strbuf);
	buf = strbuf->str;
	len = strbuf->len;

	query_emit(NULL, "irc-parse-line", &s->uid, &buf);

	p=buf;
	if(!p)
		return -1;
/*
Each IRC message may consist of up to three main parts: the prefix
(optional), the command, and the command parameters (of which there
may be up to 15).  The prefix, command, and all parameters are
separated by one (or more) ASCII space character(s) (0x20).

The presence of a prefix is indicated with a single leading ASCII
colon character (':', 0x3b), which must be the first character of the
message itself.  There must be no gap (whitespace) between the colon
and the prefix.
*/
	/* GiM: In fact this is probably not needed, but just in case...  */
	for (i=0; i<len; i++) if (buf[i]=='\n' || buf[i]=='\r') buf[i]='\0';

	if ((colon2=xstrstr(p, " :")))
		*colon2 = '\0';

	args = array_make(OMITCOLON(p), " ", 0, 1, 0);

	if (colon2) {
		*colon2 = ' ';
		array_add(&args, xstrdup(colon2+2));
	}

#define prefix pfxcmd[0]
#define pfx_nick pfxcmd[1]
#define pfx_ihost pfxcmd[2]
#define cmdname pfxcmd[3]

	/* prefix is optional... */
	if (':' != *buf) {
		array_add(&pfxcmd, g_strdup(""));	// prefix
		array_add(&pfxcmd, g_strdup(""));	// pfx_nick
		array_add(&pfxcmd, g_strdup(""));	// pfx_ihost
	} else {
		array_add(&pfxcmd, array_shift(&args));						// prefix
		p = xstrchr(pfxcmd[0], '!');
		array_add(&pfxcmd, p ? g_strndup(pfxcmd[0], p-pfxcmd[0]) : g_strdup(""));	// pfx_nick
		array_add(&pfxcmd, p ? g_strdup(p+1) : g_strdup(""));				// pfx_ihost
	}

	cmd = array_shift(&args);
	array_add(&pfxcmd, cmd);		// cmdname

	/* debug only nasty hack ;> */
#ifdef GDEBUG
	/* mg: well, it's not the exact data sent, but color is needed indeed */
	i=0;
	if (*pfxcmd[0]) debug_iorecv("[%s]", pfxcmd[0]);
	debug_iorecv("[%s]", cmd);
	while (args[i] != NULL) debug_iorecv("[%s]",args[i++]);
	debug_iorecv("\n");
#endif

	n_params = g_strv_length(args);
	if (xstrlen(cmd) > 1) {
		if(!gatoi(cmd, &ecode)) {
			/* for scripts */
			char *emitname = saprintf("irc-protocol-numeric %s", cmd);
			if ((query_emit(NULL, "irc-protocol-numeric", &s->uid, &ecode, &args) == -1) ||
			    (query_emit(NULL, emitname, &s->uid, &args) == -1))
			{
				xfree(emitname);
				g_strfreev(pfxcmd);
				g_strfreev(args);
				return -1;
			}
			xfree(emitname);

			c=0;
			while(irccommands[c].type != -1) {
				if (irccommands[c].type == 1 && irccommands[c].num == ecode) {
					if (irccommands[c].min_params > n_params) {
						debug_error("[irc] parse_line() Not enough parameters! cmd=%s, n=%d, min=%d\n",
								cmd, n_params, irccommands[c].min_params);
					} else
					/* I'm sending c not ecode!!!! */
					if ((*(irccommands[c].handler))(s, j, c, pfxcmd, args) == -1 ) {
						debug_error("[irc] parse_line() error while executing handler!\n");
					}
					/* GiM: XXX I don't expect more,
					 * then one handler on list... */
					break;
				}
				c++;
			}
#ifdef GDEBUG
			if (irccommands[c].type == -1) {
				debug("trying default handler\n");
				if ((*(irccommands[0].handler))(s, j, 0, pfxcmd, args) == -1 ) {
					debug("[irc] parse_line() error while executing handler!\n");
				}

			}
#endif
		} else {
			c=0;
			while(irccommands[c].type != -1) {
				if (irccommands[c].type == 0 && !xstrcmp(irccommands[c].comm, cmd)) {
					if (irccommands[c].min_params > n_params) {
						debug_error("[irc] parse_line() Not enough parameters! cmd=%s, n=%d, min=%d\n",
								cmd, n_params, irccommands[c].min_params);
					} else
					/* dj: instead of  ecode,    c; */
					if ((*(irccommands[c].handler))(s, j, c, pfxcmd, args) == -1 ) {
						debug_error("[irc] parse_line() error while executing handler!\n");
					}
					break;
				}
				c++;
			}
		}
	}

	g_strfreev(pfxcmd);
	g_strfreev(args);
	return 0;
}
Example #7
0
File: vars.c Project: porridge/ekg
/*
 * variable_set()
 *
 * ustawia warto¶æ podanej zmiennej. je¶li to zmienna liczbowa lub boolowska,
 * zmienia ci±g na liczbê. w przypadku boolowskich, rozumie zwroty typu `on',
 * `off', `yes', `no' itp. je¶li dana zmienna jest bitmap±, akceptuje warto¶æ
 * w postaci listy flag oraz konstrukcje `+flaga' i `-flaga'.
 *
 *  - name - nazwa zmiennej,
 *  - value - nowa warto¶æ,
 *  - allow_foreign - czy ma pozwalaæ dopisywaæ obce zmienne.
 */
int variable_set(const char *name, const char *value, int allow_foreign)
{
	struct variable *v = variable_find(name);

	if (!v && allow_foreign) {
		variable_add(name, "##", VAR_FOREIGN, 2, xstrdup(value), NULL, NULL, NULL);
		return -1;
	}

	if (!v && !allow_foreign)
		return -1;

	switch (v->type) {
		case VAR_INT:
		case VAR_MAP:
		{
			const char *p = value;
			int hex, tmp;

			if (!value)
				return -2;

			if (v->map && v->type == VAR_INT && !xisdigit(*p)) {
				int i;

				for (i = 0; v->map[i].label; i++)
					if (!strcasecmp(v->map[i].label, value))
						value = itoa(v->map[i].value);
			}

			if (v->map && v->type == VAR_MAP && !xisdigit(*p)) {
				int i, k = *(int*)(v->ptr);
				int mode = 0; /* 0 set, 1 add, 2 remove */
				char **args;

				if (*p == '+') {
					mode = 1;
					p++;
				} else if (*p == '-') {
					mode = 2;
					p++;
				}

				if (!mode)
					k = 0;

				args = array_make(p, ",", 0, 1, 0);

				for (i = 0; args[i]; i++) {
					int j, found = 0;

					for (j = 0; v->map[j].label; j++) {
						if (!strcasecmp(args[i], v->map[j].label)) {
							found = 1;

							if (mode == 2)
								k &= ~(v->map[j].value);
							if (mode == 1)
								k &= ~(v->map[j].conflicts);
							if (mode == 1 || !mode)
								k |= v->map[j].value;
						}
					}

					if (!found) {
						array_free(args);
						return -2;
					}
				}

				array_free(args);

				value = itoa(k);
			}

			p = value;
				
			if ((hex = !strncasecmp(p, "0x", 2)))
				p += 2;

			while (*p && *p != ' ') {
				if (hex && !xisxdigit(*p))
					return -2;
				
				if (!hex && !xisdigit(*p))
					return -2;
				p++;
			}

			tmp = strtol(value, NULL, 0);

			if (v->map) {
				int i;

				for (i = 0; v->map[i].label; i++) {
					if ((tmp & v->map[i].value) && (tmp & v->map[i].conflicts))
						return -2;
				}
			}

			*(int*)(v->ptr) = tmp;

			if (v->notify)
				(v->notify)(v->name);

			if (ui_event)
				ui_event("variable_changed", v->name);
			
			return 0;
		}

		case VAR_BOOL:
		{
			int tmp;
		
			if (!value)
				return -2;
		
			if ((tmp = on_off(value)) == -1)
				return -2;

			*(int*)(v->ptr) = tmp;

			if (v->notify)
				(v->notify)(v->name);

			if (ui_event)
				ui_event("variable_changed", v->name);
		
			return 0;
		}

		case VAR_STR:
		{
			char **tmp = (char**)(v->ptr);
			
			xfree(*tmp);
			
			if (value) {
				if (*value == 1)
					*tmp = base64_decode(value + 1);
				else
					*tmp = xstrdup(value);
			} else
				*tmp = NULL;
	
			if (v->notify)
				(v->notify)(v->name);

			if (ui_event)
				ui_event("variable_changed", v->name);

			return 0;
		}
	}

	return -1;
}
Example #8
0
/*
 * variable_set()
 *
 * ustawia warto¶æ podanej zmiennej. je¶li to zmienna liczbowa lub boolowska,
 * zmienia ci±g na liczbê. w przypadku boolowskich, rozumie zwroty typu `on',
 * `off', `yes', `no' itp. je¶li dana zmienna jest bitmap±, akceptuje warto¶æ
 * w postaci listy flag oraz konstrukcje `+flaga' i `-flaga'.
 *
 *  - name - nazwa zmiennej,
 *  - value - nowa warto¶æ,
 */
int variable_set(const char *name, const char *value) {
	variable_t *v = variable_find(name);
	char *tmpname;
	int changed = 0;

	if (!v)
		return -1;

	switch (v->type) {
		case VAR_INT:
		case VAR_MAP:
		{
			const char *p = value;
			int hex, tmp;

			if (!value)
				return -2;

			if (v->map && v->type == VAR_INT && !xisdigit(*p)) {
				int i;

				for (i = 0; v->map[i].label; i++)
					if (!xstrcasecmp(v->map[i].label, value))
						value = ekg_itoa(v->map[i].value);
			}

			if (v->map && v->type == VAR_MAP && !xisdigit(*p)) {
				int i, k = *(int*)(v->ptr);
				int mode = 0; /* 0 set, 1 add, 2 remove */
				char **args;

				if (*p == '+') {
					mode = 1;
					p++;
				} else if (*p == '-') {
					mode = 2;
					p++;
				}

				if (!mode)
					k = 0;

				args = array_make(p, ",", 0, 1, 0);

				for (i = 0; args[i]; i++) {
					int j, found = 0;

					for (j = 0; v->map[j].label; j++) {
						if (!xstrcasecmp(args[i], v->map[j].label)) {
							found = 1;

							if (mode == 2)
								k &= ~(v->map[j].value);
							if (mode == 1)
								k &= ~(v->map[j].conflicts);
							if (mode == 1 || !mode)
								k |= v->map[j].value;
						}
					}

					if (!found) {
						g_strfreev(args);
						return -2;
					}
				}

				g_strfreev(args);

				value = ekg_itoa(k);
			}

			p = value;
				
			if ((hex = !xstrncasecmp(p, "0x", 2)))
				p += 2;

			while (*p && *p != ' ') {
				if (hex && !xisxdigit(*p))
					return -2;
				
				if (!hex && !xisdigit(*p))
					return -2;
				p++;
			}

			tmp = strtol(value, NULL, 0);

			if (v->map) {
				int i;

				for (i = 0; v->map[i].label; i++) {
					if ((tmp & v->map[i].value) && (tmp & v->map[i].conflicts))
						return -2;
				}
			}

			changed = (*(int*)(v->ptr) != tmp);
			*(int*)(v->ptr) = tmp;

			break;
		}

		case VAR_BOOL:
		{
			int tmp;
		
			if (!value)
				return -2;
		
			if ((tmp = on_off(value)) == -1)
				return -2;

			changed = (*(int*)(v->ptr) != tmp);
			*(int*)(v->ptr) = tmp;

			break;
		}
		case VAR_THEME:
		case VAR_FILE:
		case VAR_DIR:
		case VAR_STR:
		{
			char **tmp = (char**)(v->ptr);

			char *oldval = *tmp;

			if (value) {
				if (*value == 1)
					*tmp = base64_decode(value + 1);
				else
					*tmp = xstrdup(value);
			} else
				*tmp = NULL;
	
			changed = xstrcmp(oldval, *tmp);
			xfree(oldval);
			break;
		}
		default:
			return -1;
	}

	if (v->notify)
		(v->notify)(v->name);

	if (!changed)
		return 1;

	tmpname = xstrdup(v->name);
	query_emit(NULL, "variable-changed", &tmpname);
	xfree(tmpname);
			
	return 0;
}