From c8d71fa5538003a48d367fea5a1d8b463b98ede3 Mon Sep 17 00:00:00 2001 From: keis Date: Mon, 19 Oct 2009 02:13:15 +0200 Subject: Add simple commandline history plugin to EM. --- examples/data/uzbl/plugins/history.py | 124 ++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 examples/data/uzbl/plugins/history.py diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py new file mode 100644 index 0000000..5ea2794 --- /dev/null +++ b/examples/data/uzbl/plugins/history.py @@ -0,0 +1,124 @@ +__export__ = ['get_history'] +UZBLS = {} + +import random + +class History(object): + def __init__(self): + self._commands = [] + self.cursor = None + self.__temp_tail = False + self.search_key = None + + def prev(self): + if self.cursor is None: + self.cursor = len(self._commands) - 1 + else: + self.cursor -= 1 + + if self.search_key: + while self.cursor >= 0 and self.search_key not in self._commands[self.cursor]: + self.cursor -= 1 + + if self.cursor < 0 or len(self._commands) == 0: + self.cursor = -1 + return random.choice(end_messages) + + return self._commands[self.cursor] + + def next(self): + if self.cursor is None: + return '' + + self.cursor += 1 + + if self.search_key: + while self.cursor < len(self._commands) and self.search_key not in self._commands[self.cursor]: + self.cursor += 1 + + if self.cursor >= len(self._commands) - (1 if self.__temp_tail else 0): + self.cursor = None + self.search_key = None + + if self.__temp_tail: + print 'popping temporary' + self.__temp_tail = False + return self._commands.pop() + return '' + + return self._commands[self.cursor] + + def search(self, key): + self.search_key = key + return self.prev() + + def add(self, cmd): + if self.__temp_tail: + self._commands.pop() + self.__temp_tail = False + + self._commands.append(cmd) + self.cursor = None + self.search_key = None + + def add_temporary(self, cmd): + assert not self.__temp_tail + + self._commands.append(cmd) + self.__temp_tail = True + self.cursor = len(self._commands) - 1 + + print 'adding temporary', self + + def __str__(self): + return "(History %s, %s)" % (self.cursor, str(self._commands)) + +def get_history(uzbl): + return UZBLS[uzbl] + +def add_instance(uzbl, *args): + UZBLS[uzbl] = History() + +def del_instance(uzbl, *args): + if uzbl in UZBLS: + del UZBLS[uzbl] + +def keycmd_exec(uzbl, keylet): + history = get_history(uzbl) + cmd = keylet.key_cmd() + if cmd: + history.add(cmd) + +def history_prev(uzbl, _x): + history = get_history(uzbl) + cmd = uzbl.get_keylet().key_cmd() + if history.cursor is None and cmd: + history.add_temporary(cmd) + + uzbl.set_keycmd(history.prev()) + print 'PREV', history + +def history_next(uzbl, _x): + history = get_history(uzbl) + cmd = uzbl.get_keylet().key_cmd() + + uzbl.set_keycmd(history.next()) + print 'NEXT', history + +def history_search(uzbl, key): + history = get_history(uzbl) + uzbl.set_keycmd(history.search(key)) + print 'SEARCH', history + +end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') + +def init(uzbl): + connects = {'INSTANCE_START': add_instance, + 'INSTANCE_EXIT': del_instance, + 'KEYCMD_EXEC': keycmd_exec, + 'HISTORY_PREV': history_prev, + 'HISTORY_NEXT': history_next, + 'HISTORY_SEARCH': history_search + } + + uzbl.connect_dict(connects) -- cgit v1.2.3 From 830e075e51528c03db3fb9e0206c2934fe012c8e Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sun, 25 Oct 2009 17:47:28 +0100 Subject: update history plugin to work with latest EM. --- examples/data/uzbl/plugins/history.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py index 5ea2794..595600e 100644 --- a/examples/data/uzbl/plugins/history.py +++ b/examples/data/uzbl/plugins/history.py @@ -85,13 +85,13 @@ def del_instance(uzbl, *args): def keycmd_exec(uzbl, keylet): history = get_history(uzbl) - cmd = keylet.key_cmd() + cmd = keylet.get_keycmd() if cmd: history.add(cmd) def history_prev(uzbl, _x): history = get_history(uzbl) - cmd = uzbl.get_keylet().key_cmd() + cmd = uzbl.get_keylet().get_keycmd() if history.cursor is None and cmd: history.add_temporary(cmd) @@ -100,7 +100,7 @@ def history_prev(uzbl, _x): def history_next(uzbl, _x): history = get_history(uzbl) - cmd = uzbl.get_keylet().key_cmd() + cmd = uzbl.get_keylet().get_keycmd() uzbl.set_keycmd(history.next()) print 'NEXT', history -- cgit v1.2.3 From 4f70b20a578d2618ca066f200f5b97d9a3f61220 Mon Sep 17 00:00:00 2001 From: keis Date: Thu, 5 Nov 2009 20:11:10 +0100 Subject: share history among instances. --- examples/data/uzbl/plugins/history.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py index 595600e..7855014 100644 --- a/examples/data/uzbl/plugins/history.py +++ b/examples/data/uzbl/plugins/history.py @@ -3,50 +3,54 @@ UZBLS = {} import random +shared_history = [] + class History(object): def __init__(self): - self._commands = [] + self._temporary = [] self.cursor = None self.__temp_tail = False self.search_key = None def prev(self): + commands = shared_history + self._temporary if self.cursor is None: - self.cursor = len(self._commands) - 1 + self.cursor = len(commands) - 1 else: self.cursor -= 1 if self.search_key: - while self.cursor >= 0 and self.search_key not in self._commands[self.cursor]: + while self.cursor >= 0 and self.search_key not in commands[self.cursor]: self.cursor -= 1 - if self.cursor < 0 or len(self._commands) == 0: + if self.cursor < 0 or len(commands) == 0: self.cursor = -1 return random.choice(end_messages) - return self._commands[self.cursor] + return commands[self.cursor] def next(self): + commands = shared_history + self._temporary if self.cursor is None: return '' self.cursor += 1 if self.search_key: - while self.cursor < len(self._commands) and self.search_key not in self._commands[self.cursor]: + while self.cursor < len(commands) and self.search_key not in commands[self.cursor]: self.cursor += 1 - if self.cursor >= len(self._commands) - (1 if self.__temp_tail else 0): + if self.cursor >= len(commands) - (1 if self.__temp_tail else 0): self.cursor = None self.search_key = None if self.__temp_tail: print 'popping temporary' self.__temp_tail = False - return self._commands.pop() + return self._temporary.pop() return '' - return self._commands[self.cursor] + return commands[self.cursor] def search(self, key): self.search_key = key @@ -54,24 +58,24 @@ class History(object): def add(self, cmd): if self.__temp_tail: - self._commands.pop() + self._temporary.pop() self.__temp_tail = False - self._commands.append(cmd) + shared_history.append(cmd) self.cursor = None self.search_key = None def add_temporary(self, cmd): assert not self.__temp_tail - self._commands.append(cmd) + self._temporary.append(cmd) self.__temp_tail = True - self.cursor = len(self._commands) - 1 + self.cursor = len(self._temporary) + len(shared_history) - 1 print 'adding temporary', self def __str__(self): - return "(History %s, %s)" % (self.cursor, str(self._commands)) + return "(History %s)" % (self.cursor) def get_history(uzbl): return UZBLS[uzbl] -- cgit v1.2.3 From 039caee15ad50e042d680a975ce6b066b3bdd19a Mon Sep 17 00:00:00 2001 From: keis Date: Thu, 5 Nov 2009 20:20:20 +0100 Subject: refactor history plugin. --- examples/data/uzbl/plugins/history.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py index 7855014..f514f36 100644 --- a/examples/data/uzbl/plugins/history.py +++ b/examples/data/uzbl/plugins/history.py @@ -13,67 +13,70 @@ class History(object): self.search_key = None def prev(self): - commands = shared_history + self._temporary if self.cursor is None: - self.cursor = len(commands) - 1 + self.cursor = len(self) - 1 else: self.cursor -= 1 if self.search_key: - while self.cursor >= 0 and self.search_key not in commands[self.cursor]: + while self.cursor >= 0 and self.search_key not in self[self.cursor]: self.cursor -= 1 - if self.cursor < 0 or len(commands) == 0: + if self.cursor < 0 or len(self) == 0: self.cursor = -1 return random.choice(end_messages) - return commands[self.cursor] + return self[self.cursor] def next(self): - commands = shared_history + self._temporary if self.cursor is None: return '' self.cursor += 1 if self.search_key: - while self.cursor < len(commands) and self.search_key not in commands[self.cursor]: + while self.cursor < len(self) and self.search_key not in self[self.cursor]: self.cursor += 1 - if self.cursor >= len(commands) - (1 if self.__temp_tail else 0): + if self.cursor >= len(shared_history): self.cursor = None self.search_key = None - if self.__temp_tail: + if self._temporary: print 'popping temporary' - self.__temp_tail = False return self._temporary.pop() return '' - return commands[self.cursor] + return self[self.cursor] def search(self, key): self.search_key = key return self.prev() def add(self, cmd): - if self.__temp_tail: + if self._temporary: self._temporary.pop() - self.__temp_tail = False shared_history.append(cmd) self.cursor = None self.search_key = None def add_temporary(self, cmd): - assert not self.__temp_tail + assert not self._temporary self._temporary.append(cmd) - self.__temp_tail = True - self.cursor = len(self._temporary) + len(shared_history) - 1 + self.cursor = len(self) - 1 print 'adding temporary', self + def __getitem__(self, i): + if i < len(shared_history): + return shared_history[i] + return self._temporary[i-len(shared_history)+1] + + def __len__(self): + return len(shared_history) + len(self._temporary) + def __str__(self): return "(History %s)" % (self.cursor) -- cgit v1.2.3 From b5042ed71d57e006bad8ac2b6fd02a5c0ece70be Mon Sep 17 00:00:00 2001 From: keis Date: Thu, 5 Nov 2009 20:21:32 +0100 Subject: add example history bindings. --- examples/config/uzbl/config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 8a2ad87..00c6c14 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -213,6 +213,8 @@ set formfiller = spawn @scripts_dir/formfiller @bind du = event APPEND_KEYCMD \@uri @bind dt = event APPEND_KEYCMD \@TITLE +@bind = request HISTORY_PREV +@bind = request HISTORY_NEXT # === command editing configuration ========================================== -- cgit v1.2.3 From 4e16343b4b30c1ff24c46e75945f092732413deb Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 8 Dec 2009 17:37:23 +0100 Subject: maintain separate histories for each prompt --- examples/data/uzbl/plugins/history.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py index f514f36..4467e5d 100644 --- a/examples/data/uzbl/plugins/history.py +++ b/examples/data/uzbl/plugins/history.py @@ -3,11 +3,12 @@ UZBLS = {} import random -shared_history = [] +shared_history = {'':[]} class History(object): def __init__(self): self._temporary = [] + self.prompt = '' self.cursor = None self.__temp_tail = False self.search_key = None @@ -38,7 +39,7 @@ class History(object): while self.cursor < len(self) and self.search_key not in self[self.cursor]: self.cursor += 1 - if self.cursor >= len(shared_history): + if self.cursor >= len(shared_history[self.prompt]): self.cursor = None self.search_key = None @@ -49,6 +50,13 @@ class History(object): return self[self.cursor] + def change_prompt(self, prompt): + self.prompt = prompt + self._temporary = [] + self.__temp_tail = False + if prompt not in shared_history: + shared_history[prompt] = [] + def search(self, key): self.search_key = key return self.prev() @@ -57,7 +65,7 @@ class History(object): if self._temporary: self._temporary.pop() - shared_history.append(cmd) + shared_history[self.prompt].append(cmd) self.cursor = None self.search_key = None @@ -70,17 +78,20 @@ class History(object): print 'adding temporary', self def __getitem__(self, i): - if i < len(shared_history): - return shared_history[i] + if i < len(shared_history[self.prompt]): + return shared_history[self.prompt][i] return self._temporary[i-len(shared_history)+1] def __len__(self): - return len(shared_history) + len(self._temporary) + return len(shared_history[self.prompt]) + len(self._temporary) def __str__(self): return "(History %s)" % (self.cursor) def get_history(uzbl): + if uzbl not in UZBLS: + add_instance(uzbl) + return UZBLS[uzbl] def add_instance(uzbl, *args): @@ -96,6 +107,11 @@ def keycmd_exec(uzbl, keylet): if cmd: history.add(cmd) +def config_changed(uzbl, key, value): + if key == 'keycmd_prompt': + history = get_history(uzbl) + history.change_prompt(value) + def history_prev(uzbl, _x): history = get_history(uzbl) cmd = uzbl.get_keylet().get_keycmd() @@ -123,6 +139,7 @@ def init(uzbl): connects = {'INSTANCE_START': add_instance, 'INSTANCE_EXIT': del_instance, 'KEYCMD_EXEC': keycmd_exec, + 'CONFIG_CHANGED': config_changed, 'HISTORY_PREV': history_prev, 'HISTORY_NEXT': history_next, 'HISTORY_SEARCH': history_search -- cgit v1.2.3 From 5930439a3003f1d77d71bca440bbe918e7c657d9 Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 8 Dec 2009 18:47:42 +0100 Subject: use event instead of request for history prev/next --- examples/config/uzbl/config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 1ef1758..e9f7f8d 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -248,8 +248,8 @@ set formfiller = spawn @scripts_dir/formfiller @bind du = event APPEND_KEYCMD \@uri @bind dt = event APPEND_KEYCMD \@TITLE -@bind = request HISTORY_PREV -@bind = request HISTORY_NEXT +@bind = event HISTORY_PREV +@bind = event HISTORY_NEXT # === command editing configuration ========================================== -- cgit v1.2.3 From c37f739ce5b51091732cec0452e8035fc187c096 Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 4 Apr 2010 22:27:11 +0200 Subject: move history plugin --- examples/data/plugins/history.py | 148 ++++++++++++++++++++++++++++++++++ examples/data/uzbl/plugins/history.py | 148 ---------------------------------- 2 files changed, 148 insertions(+), 148 deletions(-) create mode 100644 examples/data/plugins/history.py delete mode 100644 examples/data/uzbl/plugins/history.py diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py new file mode 100644 index 0000000..4467e5d --- /dev/null +++ b/examples/data/plugins/history.py @@ -0,0 +1,148 @@ +__export__ = ['get_history'] +UZBLS = {} + +import random + +shared_history = {'':[]} + +class History(object): + def __init__(self): + self._temporary = [] + self.prompt = '' + self.cursor = None + self.__temp_tail = False + self.search_key = None + + def prev(self): + if self.cursor is None: + self.cursor = len(self) - 1 + else: + self.cursor -= 1 + + if self.search_key: + while self.cursor >= 0 and self.search_key not in self[self.cursor]: + self.cursor -= 1 + + if self.cursor < 0 or len(self) == 0: + self.cursor = -1 + return random.choice(end_messages) + + return self[self.cursor] + + def next(self): + if self.cursor is None: + return '' + + self.cursor += 1 + + if self.search_key: + while self.cursor < len(self) and self.search_key not in self[self.cursor]: + self.cursor += 1 + + if self.cursor >= len(shared_history[self.prompt]): + self.cursor = None + self.search_key = None + + if self._temporary: + print 'popping temporary' + return self._temporary.pop() + return '' + + return self[self.cursor] + + def change_prompt(self, prompt): + self.prompt = prompt + self._temporary = [] + self.__temp_tail = False + if prompt not in shared_history: + shared_history[prompt] = [] + + def search(self, key): + self.search_key = key + return self.prev() + + def add(self, cmd): + if self._temporary: + self._temporary.pop() + + shared_history[self.prompt].append(cmd) + self.cursor = None + self.search_key = None + + def add_temporary(self, cmd): + assert not self._temporary + + self._temporary.append(cmd) + self.cursor = len(self) - 1 + + print 'adding temporary', self + + def __getitem__(self, i): + if i < len(shared_history[self.prompt]): + return shared_history[self.prompt][i] + return self._temporary[i-len(shared_history)+1] + + def __len__(self): + return len(shared_history[self.prompt]) + len(self._temporary) + + def __str__(self): + return "(History %s)" % (self.cursor) + +def get_history(uzbl): + if uzbl not in UZBLS: + add_instance(uzbl) + + return UZBLS[uzbl] + +def add_instance(uzbl, *args): + UZBLS[uzbl] = History() + +def del_instance(uzbl, *args): + if uzbl in UZBLS: + del UZBLS[uzbl] + +def keycmd_exec(uzbl, keylet): + history = get_history(uzbl) + cmd = keylet.get_keycmd() + if cmd: + history.add(cmd) + +def config_changed(uzbl, key, value): + if key == 'keycmd_prompt': + history = get_history(uzbl) + history.change_prompt(value) + +def history_prev(uzbl, _x): + history = get_history(uzbl) + cmd = uzbl.get_keylet().get_keycmd() + if history.cursor is None and cmd: + history.add_temporary(cmd) + + uzbl.set_keycmd(history.prev()) + print 'PREV', history + +def history_next(uzbl, _x): + history = get_history(uzbl) + cmd = uzbl.get_keylet().get_keycmd() + + uzbl.set_keycmd(history.next()) + print 'NEXT', history + +def history_search(uzbl, key): + history = get_history(uzbl) + uzbl.set_keycmd(history.search(key)) + print 'SEARCH', history + +end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') + +def init(uzbl): + connects = {'INSTANCE_START': add_instance, + 'INSTANCE_EXIT': del_instance, + 'KEYCMD_EXEC': keycmd_exec, + 'CONFIG_CHANGED': config_changed, + 'HISTORY_PREV': history_prev, + 'HISTORY_NEXT': history_next, + 'HISTORY_SEARCH': history_search + } + + uzbl.connect_dict(connects) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py deleted file mode 100644 index 4467e5d..0000000 --- a/examples/data/uzbl/plugins/history.py +++ /dev/null @@ -1,148 +0,0 @@ -__export__ = ['get_history'] -UZBLS = {} - -import random - -shared_history = {'':[]} - -class History(object): - def __init__(self): - self._temporary = [] - self.prompt = '' - self.cursor = None - self.__temp_tail = False - self.search_key = None - - def prev(self): - if self.cursor is None: - self.cursor = len(self) - 1 - else: - self.cursor -= 1 - - if self.search_key: - while self.cursor >= 0 and self.search_key not in self[self.cursor]: - self.cursor -= 1 - - if self.cursor < 0 or len(self) == 0: - self.cursor = -1 - return random.choice(end_messages) - - return self[self.cursor] - - def next(self): - if self.cursor is None: - return '' - - self.cursor += 1 - - if self.search_key: - while self.cursor < len(self) and self.search_key not in self[self.cursor]: - self.cursor += 1 - - if self.cursor >= len(shared_history[self.prompt]): - self.cursor = None - self.search_key = None - - if self._temporary: - print 'popping temporary' - return self._temporary.pop() - return '' - - return self[self.cursor] - - def change_prompt(self, prompt): - self.prompt = prompt - self._temporary = [] - self.__temp_tail = False - if prompt not in shared_history: - shared_history[prompt] = [] - - def search(self, key): - self.search_key = key - return self.prev() - - def add(self, cmd): - if self._temporary: - self._temporary.pop() - - shared_history[self.prompt].append(cmd) - self.cursor = None - self.search_key = None - - def add_temporary(self, cmd): - assert not self._temporary - - self._temporary.append(cmd) - self.cursor = len(self) - 1 - - print 'adding temporary', self - - def __getitem__(self, i): - if i < len(shared_history[self.prompt]): - return shared_history[self.prompt][i] - return self._temporary[i-len(shared_history)+1] - - def __len__(self): - return len(shared_history[self.prompt]) + len(self._temporary) - - def __str__(self): - return "(History %s)" % (self.cursor) - -def get_history(uzbl): - if uzbl not in UZBLS: - add_instance(uzbl) - - return UZBLS[uzbl] - -def add_instance(uzbl, *args): - UZBLS[uzbl] = History() - -def del_instance(uzbl, *args): - if uzbl in UZBLS: - del UZBLS[uzbl] - -def keycmd_exec(uzbl, keylet): - history = get_history(uzbl) - cmd = keylet.get_keycmd() - if cmd: - history.add(cmd) - -def config_changed(uzbl, key, value): - if key == 'keycmd_prompt': - history = get_history(uzbl) - history.change_prompt(value) - -def history_prev(uzbl, _x): - history = get_history(uzbl) - cmd = uzbl.get_keylet().get_keycmd() - if history.cursor is None and cmd: - history.add_temporary(cmd) - - uzbl.set_keycmd(history.prev()) - print 'PREV', history - -def history_next(uzbl, _x): - history = get_history(uzbl) - cmd = uzbl.get_keylet().get_keycmd() - - uzbl.set_keycmd(history.next()) - print 'NEXT', history - -def history_search(uzbl, key): - history = get_history(uzbl) - uzbl.set_keycmd(history.search(key)) - print 'SEARCH', history - -end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') - -def init(uzbl): - connects = {'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, - 'KEYCMD_EXEC': keycmd_exec, - 'CONFIG_CHANGED': config_changed, - 'HISTORY_PREV': history_prev, - 'HISTORY_NEXT': history_next, - 'HISTORY_SEARCH': history_search - } - - uzbl.connect_dict(connects) -- cgit v1.2.3 From 14bce08a78c86e8cca7a6ca4b64d3692fa2782b5 Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 30 Nov 2010 18:35:20 +0100 Subject: make history plugin work with new EM --- examples/data/plugins/history.py | 65 ++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py index 4467e5d..886cbe0 100644 --- a/examples/data/plugins/history.py +++ b/examples/data/plugins/history.py @@ -1,12 +1,10 @@ -__export__ = ['get_history'] -UZBLS = {} - import random shared_history = {'':[]} class History(object): - def __init__(self): + def __init__(self, uzbl): + self.uzbl = uzbl self._temporary = [] self.prompt = '' self.cursor = None @@ -86,63 +84,46 @@ class History(object): return len(shared_history[self.prompt]) + len(self._temporary) def __str__(self): - return "(History %s)" % (self.cursor) - -def get_history(uzbl): - if uzbl not in UZBLS: - add_instance(uzbl) - - return UZBLS[uzbl] - -def add_instance(uzbl, *args): - UZBLS[uzbl] = History() - -def del_instance(uzbl, *args): - if uzbl in UZBLS: - del UZBLS[uzbl] + return "(History %s, %s)" % (self.cursor, self.prompt) def keycmd_exec(uzbl, keylet): - history = get_history(uzbl) cmd = keylet.get_keycmd() if cmd: - history.add(cmd) - -def config_changed(uzbl, key, value): - if key == 'keycmd_prompt': - history = get_history(uzbl) - history.change_prompt(value) + uzbl.history.add(cmd) def history_prev(uzbl, _x): - history = get_history(uzbl) - cmd = uzbl.get_keylet().get_keycmd() - if history.cursor is None and cmd: - history.add_temporary(cmd) + cmd = uzbl.keylet.get_keycmd() + if uzbl.history.cursor is None and cmd: + uzbl.history.add_temporary(cmd) - uzbl.set_keycmd(history.prev()) - print 'PREV', history + uzbl.set_keycmd(uzbl.history.prev()) + uzbl.logger.debug('PREV %s' % uzbl.history) def history_next(uzbl, _x): - history = get_history(uzbl) - cmd = uzbl.get_keylet().get_keycmd() + cmd = uzbl.keylet.get_keycmd() - uzbl.set_keycmd(history.next()) - print 'NEXT', history + uzbl.set_keycmd(uzbl.history.next()) + uzbl.logger.debug('NEXT %s' % uzbl.history) def history_search(uzbl, key): - history = get_history(uzbl) uzbl.set_keycmd(history.search(key)) - print 'SEARCH', history + uzbl.logger.debug('SEARCH %s %s' % (key, uzbl.history)) end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') +# plugin init hook def init(uzbl): - connects = {'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, + connect_dict(uzbl, { 'KEYCMD_EXEC': keycmd_exec, - 'CONFIG_CHANGED': config_changed, 'HISTORY_PREV': history_prev, 'HISTORY_NEXT': history_next, 'HISTORY_SEARCH': history_search - } + }) + + export_dict(uzbl, { + 'history' : History(uzbl) + }) - uzbl.connect_dict(connects) +# plugin after hook +def after(uzbl): + uzbl.on_set('keycmd_prompt', lambda uzbl, k, v: uzbl.history.change_prompt(v)) -- cgit v1.2.3 From 7cf3fb88d1e094da5b516699a61d5e589c039e8f Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 30 Nov 2010 19:25:34 +0100 Subject: disable odd clear of keycmd was breaking history of prompts, for what I can tell no good reason --- examples/data/plugins/bind.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/data/plugins/bind.py b/examples/data/plugins/bind.py index 5b13476..bf693b3 100644 --- a/examples/data/plugins/bind.py +++ b/examples/data/plugins/bind.py @@ -421,7 +421,8 @@ def match_and_exec(uzbl, bind, depth, keylet, bindlet): if not has_args or on_exec: del uzbl.config['mode'] bindlet.reset() - uzbl.clear_current() + # cleared by keycmd_exec_current, why is this here? breaks history + #uzbl.clear_current() return True -- cgit v1.2.3 From 32800e94c6667c8f44dfe2178115049c280de339 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 27 Dec 2010 19:55:44 -0700 Subject: remove example cookie daemons --- Makefile | 16 +- examples/data/scripts/uzbl-cookie-daemon | 677 ------------------------------- examples/uzbl-cookie-manager.c | 381 ----------------- src/uzbl-browser | 7 - 4 files changed, 3 insertions(+), 1078 deletions(-) delete mode 100755 examples/data/scripts/uzbl-cookie-daemon delete mode 100644 examples/uzbl-cookie-manager.c diff --git a/Makefile b/Makefile index e4d1b42..2b1a70a 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ SRC = $(wildcard src/*.c) HEAD = $(wildcard src/*.h) OBJ = $(foreach obj, $(SRC:.c=.o), $(notdir $(obj))) -all: uzbl-browser uzbl-cookie-manager +all: uzbl-browser VPATH:=src @@ -24,11 +24,7 @@ uzbl-core: ${OBJ} @echo -e "\n${CC} -o $@ ${OBJ} ${UZBL_LDFLAGS}" @${CC} -o $@ ${OBJ} ${UZBL_LDFLAGS} -uzbl-cookie-manager: examples/uzbl-cookie-manager.o src/util.o - @echo -e "\n${CC} -o $@ uzbl-cookie-manager.o util.o ${LDFLAGS} ${shell pkg-config --libs glib-2.0 libsoup-2.4}" - @${CC} -o $@ uzbl-cookie-manager.o util.o ${LDFLAGS} $(shell pkg-config --libs glib-2.0 libsoup-2.4) - -uzbl-browser: uzbl-core uzbl-cookie-manager +uzbl-browser: uzbl-core # packagers, set DESTDIR to your "package directory" and PREFIX to the prefix you want to have on the end-user system # end-users who build from source: don't care about DESTDIR, update PREFIX if you want to @@ -66,10 +62,8 @@ test-uzbl-browser-sandbox: uzbl-browser make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data cp -np ./misc/env.sh ./sandbox/env.sh - -source ./sandbox/env.sh && uzbl-cookie-manager -v -source ./sandbox/env.sh && uzbl-event-manager restart -avv source ./sandbox/env.sh && uzbl-browser --uri http://www.uzbl.org --verbose - kill `cat ./sandbox/home/.cache/uzbl/cookie_daemon_socket.pid` source ./sandbox/env.sh && uzbl-event-manager stop -ivv make DESTDIR=./sandbox uninstall rm -rf ./sandbox/usr @@ -79,17 +73,14 @@ test-uzbl-tabbed-sandbox: uzbl-browser make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data cp -np ./misc/env.sh ./sandbox/env.sh - -source ./sandbox/env.sh && uzbl-cookie-manager -v -source ./sandbox/env.sh && uzbl-event-manager restart -avv source ./sandbox/env.sh && ./sandbox/home/.local/share/uzbl/scripts/uzbl-tabbed - kill `cat ./sandbox/home/.cache/uzbl/cookie_daemon_socket.pid` source ./sandbox/env.sh && uzbl-event-manager stop -ivv make DESTDIR=./sandbox uninstall rm -rf ./sandbox/usr clean: rm -f uzbl-core - rm -f uzbl-cookie-manager rm -f uzbl-core.o rm -f events.o rm -f callbacks.o @@ -121,9 +112,8 @@ install-uzbl-core: all install-dirs chmod 755 $(INSTALLDIR)/share/uzbl/examples/data/scripts/* install -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core -install-uzbl-browser: uzbl-cookie-manager install-dirs +install-uzbl-browser: install-dirs install -m755 src/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser - install -m755 uzbl-cookie-manager $(INSTALLDIR)/bin/uzbl-cookie-manager install -m755 examples/data/scripts/uzbl-event-manager $(INSTALLDIR)/bin/uzbl-event-manager mv $(INSTALLDIR)/bin/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser.bak sed 's#^PREFIX=.*#PREFIX=$(RUN_PREFIX)#' < $(INSTALLDIR)/bin/uzbl-browser.bak > $(INSTALLDIR)/bin/uzbl-browser diff --git a/examples/data/scripts/uzbl-cookie-daemon b/examples/data/scripts/uzbl-cookie-daemon deleted file mode 100755 index 0b9bef9..0000000 --- a/examples/data/scripts/uzbl-cookie-daemon +++ /dev/null @@ -1,677 +0,0 @@ -#!/usr/bin/env python - -# The Python Cookie Daemon for Uzbl. -# Copyright (c) 2009, Tom Adams -# Copyright (c) 2009, Dieter Plaetinck -# Copyright (c) 2009, Mason Larobina -# Copyright (c) 2009, Michael Fiano -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -''' -The Python Cookie Daemon -======================== - -This daemon is a re-write of the original cookies.py script found in uzbl's -master branch. This script provides more functionality than the original -cookies.py by adding numerous command line options to specify different cookie -jar locations, socket locations, verbose output, etc. This functionality is -very useful as it allows you to run multiple daemons at once serving cookies -to different groups of uzbl instances as required. - -Keeping up to date -================== - -Check the cookie daemon uzbl-wiki page for more information on where to -find the latest version of the cookie_daemon.py - - http://www.uzbl.org/wiki/cookie_daemon.py - -Command line options -==================== - -Use the following command to get a full list of the cookie_daemon.py command -line options: - - ./cookie_daemon.py --help - -Talking with uzbl -================= - -In order to get uzbl to talk to a running cookie daemon you add the following -to your uzbl config: - - set cookie_handler = talk_to_socket $XDG_CACHE_HOME/uzbl/cookie_daemon_socket - -Or if you prefer using the $HOME variable: - - set cookie_handler = talk_to_socket $HOME/.cache/uzbl/cookie_daemon_socket - -Todo list -========= - - - Use a pid file to make force killing a running daemon possible. - -Reporting bugs / getting help -============================= - -The best way to report bugs and or get help with the cookie daemon is to -contact the maintainers it the #uzbl irc channel found on the Freenode IRC -network (irc.freenode.org). -''' - -import cookielib -import os -import sys -import urllib2 -import select -import socket -import time -import atexit -from traceback import print_exc -from signal import signal, SIGTERM -from optparse import OptionParser -from os.path import join - -try: - import cStringIO as StringIO - -except ImportError: - import StringIO - - -# ============================================================================ -# ::: Default configuration section :::::::::::::::::::::::::::::::::::::::::: -# ============================================================================ - -def xdghome(key, default): - '''Attempts to use the environ XDG_*_HOME paths if they exist otherwise - use $HOME and the default path.''' - - xdgkey = "XDG_%s_HOME" % key - if xdgkey in os.environ.keys() and os.environ[xdgkey]: - return os.environ[xdgkey] - - return join(os.environ['HOME'], default) - -# Setup xdg paths. -CACHE_DIR = join(xdghome('CACHE', '.cache/'), 'uzbl/') -DATA_DIR = join(xdghome('DATA', '.local/share/'), 'uzbl/') -CONFIG_DIR = join(xdghome('CONFIG', '.config/'), 'uzbl/') - -# Ensure data paths exist. -for path in [CACHE_DIR, DATA_DIR, CONFIG_DIR]: - if not os.path.exists(path): - os.makedirs(path) - -# Default config -config = { - - # Default cookie jar, whitelist, and daemon socket locations. - 'cookie_jar': join(DATA_DIR, 'cookies.txt'), - 'cookie_whitelist': join(CONFIG_DIR, 'cookie_whitelist'), - 'cookie_socket': join(CACHE_DIR, 'cookie_daemon_socket'), - - # Don't use a cookie whitelist policy by default. - 'use_whitelist': False, - - # Time out after x seconds of inactivity (set to 0 for never time out). - # WARNING: Do not use this option if you are manually launching the daemon. - 'daemon_timeout': 0, - - # Daemonise by default. - 'daemon_mode': True, - - # Optionally print helpful debugging messages to the terminal. - 'verbose': False, - -} # End of config dictionary. - - -# ============================================================================ -# ::: End of configuration section ::::::::::::::::::::::::::::::::::::::::::: -# ============================================================================ - - -_SCRIPTNAME = os.path.basename(sys.argv[0]) -def echo(msg): - '''Prints only if the verbose flag has been set.''' - - if config['verbose']: - sys.stderr.write("%s: %s\n" % (_SCRIPTNAME, msg)) - - -def error(msg): - '''Prints error message and exits.''' - - sys.stderr.write("%s: error: %s\n" % (_SCRIPTNAME, msg)) - sys.exit(1) - - -def mkbasedir(filepath): - '''Create the base directories of the file in the file-path if the dirs - don't exist.''' - - dirname = os.path.dirname(filepath) - if not os.path.exists(dirname): - echo("creating dirs: %r" % dirname) - os.makedirs(dirname) - - -def daemon_running(cookie_socket): - '''Check if another process (hopefully a cookie_daemon.py) is listening - on the cookie daemon socket. If another process is found to be - listening on the socket exit the daemon immediately and leave the - socket alone. If the connect fails assume the socket has been abandoned - and delete it (to be re-created in the create socket function).''' - - if not os.path.exists(cookie_socket): - return False - - if os.path.isfile(cookie_socket): - raise Exception("regular file at %r is not a socket" % cookie_socket) - - - if os.path.isdir(cookie_socket): - raise Exception("directory at %r is not a socket" % cookie_socket) - - try: - sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) - sock.connect(cookie_socket) - sock.close() - echo("detected daemon listening on %r" % cookie_socket) - return True - - except socket.error: - # Failed to connect to cookie_socket so assume it has been - # abandoned by another cookie daemon process. - if os.path.exists(cookie_socket): - echo("deleting abandoned socket at %r" % cookie_socket) - os.remove(cookie_socket) - - return False - - -def send_command(cookie_socket, cmd): - '''Send a command to a running cookie daemon.''' - - if not daemon_running(cookie_socket): - return False - - try: - sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) - sock.connect(cookie_socket) - sock.send(cmd) - sock.close() - echo("sent command %r to %r" % (cmd, cookie_socket)) - return True - - except socket.error: - print_exc() - error("failed to send message %r to %r" % (cmd, cookie_socket)) - return False - - -def kill_daemon(cookie_socket): - '''Send the "EXIT" command to running cookie_daemon.''' - - if send_command(cookie_socket, "EXIT"): - # Now ensure the cookie_socket is cleaned up. - start = time.time() - while os.path.exists(cookie_socket): - time.sleep(0.1) - if (time.time() - start) > 5: - error("force deleting socket %r" % cookie_socket) - os.remove(cookie_socket) - return - - echo("stopped daemon listening on %r"% cookie_socket) - - else: - if os.path.exists(cookie_socket): - os.remove(cookie_socket) - echo("removed abandoned/broken socket %r" % cookie_socket) - - -def daemonize(): - '''Daemonize the process using the Stevens' double-fork magic.''' - - try: - if os.fork(): - os._exit(0) - - except OSError: - print_exc() - sys.stderr.write("fork #1 failed") - sys.exit(1) - - os.chdir('/') - os.setsid() - os.umask(0) - - try: - if os.fork(): - os._exit(0) - - except OSError: - print_exc() - sys.stderr.write("fork #2 failed") - sys.exit(1) - - if sys.stdout.isatty(): - sys.stdout.flush() - sys.stderr.flush() - - devnull = '/dev/null' - stdin = file(devnull, 'r') - stdout = file(devnull, 'a+') - stderr = file(devnull, 'a+', 0) - - os.dup2(stdin.fileno(), sys.stdin.fileno()) - os.dup2(stdout.fileno(), sys.stdout.fileno()) - os.dup2(stderr.fileno(), sys.stderr.fileno()) - - -class CookieMonster: - '''The uzbl cookie daemon class.''' - - def __init__(self): - '''Initialise class variables.''' - - self.server_socket = None - self.jar = None - self.last_request = time.time() - self._running = False - - - def run(self): - '''Start the daemon.''' - - # The check healthy function will exit if another daemon is detected - # listening on the cookie socket and remove the abandoned socket if - # there isnt. - if os.path.exists(config['cookie_socket']): - if daemon_running(config['cookie_socket']): - sys.exit(1) - - # Create cookie daemon socket. - self.create_socket() - - # Daemonize process. - if config['daemon_mode']: - echo("entering daemon mode") - daemonize() - - # Register a function to cleanup on exit. - atexit.register(self.quit) - - # Make SIGTERM act orderly. - signal(SIGTERM, lambda signum, stack_frame: sys.exit(1)) - - # Create cookie jar object from file. - self.open_cookie_jar() - - # Create a way to exit nested loops by setting a running flag. - self._running = True - - while self._running: - try: - # Enter main listen loop. - self.listen() - - except KeyboardInterrupt: - self._running = False - print - - except socket.error: - print_exc() - - except: - # Clean up - self.del_socket() - - # Raise exception - raise - - # Always delete the socket before calling create again. - self.del_socket() - # Create cookie daemon socket. - self.create_socket() - - - def load_whitelist(self): - '''Load the cookie jar whitelist policy.''' - - cookie_whitelist = config['cookie_whitelist'] - - if cookie_whitelist: - mkbasedir(cookie_whitelist) - - # Create cookie whitelist file if it does not exist. - if not os.path.exists(cookie_whitelist): - open(cookie_whitelist, 'w').close() - - # Read cookie whitelist file into list. - file = open(cookie_whitelist,'r') - domain_list = [line.rstrip('\n') for line in file] - file.close() - - # Define policy of allowed domains - policy = cookielib.DefaultCookiePolicy(allowed_domains=domain_list) - self.jar.set_policy(policy) - - # Save the last modified time of the whitelist. - self._whitelistmtime = os.stat(cookie_whitelist).st_mtime - - - def open_cookie_jar(self): - '''Open the cookie jar.''' - - cookie_jar = config['cookie_jar'] - cookie_whitelist = config['cookie_whitelist'] - - if cookie_jar: - mkbasedir(cookie_jar) - - # Create cookie jar object from file. - self.jar = cookielib.MozillaCookieJar(cookie_jar) - - # Load cookie whitelist policy. - if config['use_whitelist']: - self.load_whitelist() - - if cookie_jar: - try: - # Attempt to load cookies from the cookie jar. - self.jar.load(ignore_discard=True) - - # Ensure restrictive permissions are set on the cookie jar - # to prevent other users on the system from hi-jacking your - # authenticated sessions simply by copying your cookie jar. - os.chmod(cookie_jar, 0600) - - except: - pass - - - def reload_whitelist(self): - '''Reload the cookie whitelist.''' - - cookie_whitelist = config['cookie_whitelist'] - if os.path.exists(cookie_whitelist): - echo("reloading whitelist %r" % cookie_whitelist) - self.open_cookie_jar() - - - def create_socket(self): - '''Create AF_UNIX socket for communication with uzbl instances.''' - - cookie_socket = config['cookie_socket'] - mkbasedir(cookie_socket) - - self.server_socket = socket.socket(socket.AF_UNIX, - socket.SOCK_SEQPACKET) - - self.server_socket.bind(cookie_socket) - - # Set restrictive permissions on the cookie socket to prevent other - # users on the system from data-mining your cookies. - os.chmod(cookie_socket, 0600) - - - def listen(self): - '''Listen for incoming cookie PUT and GET requests.''' - - daemon_timeout = config['daemon_timeout'] - echo("listening on %r" % config['cookie_socket']) - - connections = [] - - while self._running: - # This line tells the socket how many pending incoming connections - # to enqueue at once. Raising this number may or may not increase - # performance. - self.server_socket.listen(1) - - r, w, x = select.select([self.server_socket]+connections, [], [], 1) - - for socket in r: - if self.server_socket == socket: - client_socket, _ = socket.accept() - connections.append(client_socket) - else: - if not self.handle_request(socket): - # connection was closed, forget about the client socket - connections.remove(socket) - - self.last_request = time.time() - - if daemon_timeout: - # Checks if the daemon has been idling for too long. - idle = time.time() - self.last_request - if idle > daemon_timeout: - self._running = False - - - def handle_request(self, client_socket): - '''Connection made, now to serve a cookie PUT or GET request.''' - - # Receive cookie request from client. - data = client_socket.recv(8192) - if not data: - return False - - # Cookie argument list in packet is null separated. - argv = data.split("\0") - action = argv[0].upper().strip() - - # Catch the EXIT command sent to kill running daemons. - if action == "EXIT": - self._running = False - return False - - # Catch whitelist RELOAD command. - elif action == "RELOAD": - self.reload_whitelist() - return True - - # Return if command unknown. - elif action not in ['GET', 'PUT']: - error("unknown command %r." % argv) - return True - - # Determine whether or not to print cookie data to terminal. - print_cookie = (config['verbose'] and not config['daemon_mode']) - if print_cookie: - print ' '.join(argv[:4]) - - uri = urllib2.urlparse.ParseResult( - scheme=argv[1], - netloc=argv[2], - path=argv[3], - params='', - query='', - fragment='').geturl() - - req = urllib2.Request(uri) - - if action == "GET": - self.jar._policy._now = self._now = int(time.time()) - cookies = self.jar._cookies_for_request(req) - attrs = self.jar._cookie_attrs(cookies) - if attrs: - cookie = "; ".join(attrs) - client_socket.send(cookie) - if print_cookie: - print cookie - else: - client_socket.send("\0") - - elif action == "PUT": - cookie = argv[4] if len(argv) > 3 else None - if print_cookie: - print cookie - - self.put_cookie(req, cookie) - client_socket.send("\0") - - if print_cookie: - print - - return True - - - def put_cookie(self, req, cookie=None): - '''Put a cookie in the cookie jar.''' - - hdr = urllib2.httplib.HTTPMessage(\ - StringIO.StringIO('Set-Cookie: %s' % cookie)) - res = urllib2.addinfourl(StringIO.StringIO(), hdr, - req.get_full_url()) - self.jar.extract_cookies(res, req) - if config['cookie_jar']: - self.jar.save(ignore_discard=True) - - - def del_socket(self): - '''Remove the cookie_socket file on exit. In a way the cookie_socket - is the daemons pid file equivalent.''' - - if self.server_socket: - try: - self.server_socket.close() - - except: - pass - - self.server_socket = None - - cookie_socket = config['cookie_socket'] - if os.path.exists(cookie_socket): - echo("deleting socket %r" % cookie_socket) - os.remove(cookie_socket) - - - def quit(self): - '''Called on exit to make sure all loose ends are tied up.''' - - self.del_socket() - sys.exit(0) - - -def main(): - '''Main function.''' - - # Define command line parameters. - usage = "usage: %prog [options] {start|stop|restart|reload}" - parser = OptionParser(usage=usage) - parser.add_option('-n', '--no-daemon', dest='no_daemon', - action='store_true', help="don't daemonise the process.") - - parser.add_option('-v', '--verbose', dest="verbose", - action='store_true', help="print verbose output.") - - parser.add_option('-t', '--daemon-timeout', dest='daemon_timeout', - action="store", metavar="SECONDS", help="shutdown the daemon after x "\ - "seconds inactivity. WARNING: Do not use this when launching the "\ - "cookie daemon manually.") - - parser.add_option('-s', '--cookie-socket', dest="cookie_socket", - metavar="SOCKET", help="manually specify the socket location.") - - parser.add_option('-j', '--cookie-jar', dest='cookie_jar', - metavar="FILE", help="manually specify the cookie jar location.") - - parser.add_option('-m', '--memory', dest='memory', action='store_true', - help="store cookies in memory only - do not write to disk") - - parser.add_option('-u', '--use-whitelist', dest='usewhitelist', - action='store_true', help="use cookie whitelist policy") - - parser.add_option('-w', '--cookie-whitelist', dest='whitelist', - action='store', help="manually specify whitelist location", - metavar='FILE') - - # Parse the command line arguments. - (options, args) = parser.parse_args() - - expand = lambda p: os.path.realpath(os.path.expandvars(p)) - - initcommands = ['start', 'stop', 'restart', 'reload'] - for arg in args: - if arg not in initcommands: - error("unknown argument %r" % args[0]) - sys.exit(1) - - if len(args) > 1: - error("the daemon only accepts one {%s} action at a time." - % '|'.join(initcommands)) - sys.exit(1) - - if len(args): - action = args[0] - - else: - action = "start" - - if options.no_daemon: - config['daemon_mode'] = False - - if options.cookie_socket: - config['cookie_socket'] = expand(options.cookie_socket) - - if options.cookie_jar: - config['cookie_jar'] = expand(options.cookie_jar) - - if options.memory: - config['cookie_jar'] = None - - if options.whitelist: - config['cookie_whitelist'] = expand(options.whitelist) - - if options.whitelist or options.usewhitelist: - config['use_whitelist'] = True - - if options.daemon_timeout: - try: - config['daemon_timeout'] = int(options.daemon_timeout) - - except ValueError: - error("expected int argument for -t, --daemon-timeout") - - # Expand $VAR's in config keys that relate to paths. - for key in ['cookie_socket', 'cookie_jar', 'cookie_whitelist']: - if config[key]: - config[key] = os.path.expandvars(config[key]) - - if options.verbose: - config['verbose'] = True - import pprint - sys.stderr.write("%s\n" % pprint.pformat(config)) - - # It would be better if we didn't need to start this python process just - # to send a command to the socket, but unfortunately socat doesn't seem - # to support SEQPACKET. - if action == "reload": - send_command(config['cookie_socket'], "RELOAD") - - if action in ['stop', 'restart']: - kill_daemon(config['cookie_socket']) - - if action in ['start', 'restart']: - CookieMonster().run() - - -if __name__ == "__main__": - main() diff --git a/examples/uzbl-cookie-manager.c b/examples/uzbl-cookie-manager.c deleted file mode 100644 index 70addf3..0000000 --- a/examples/uzbl-cookie-manager.c +++ /dev/null @@ -1,381 +0,0 @@ -#define _POSIX_SOURCE - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "../src/util.h" - -extern const XDG_Var XDG[]; - -int verbose = 0; - -#define SOCK_BACKLOG 10 -#define MAX_COOKIE_LENGTH 4096 - -char cookie_buffer[MAX_COOKIE_LENGTH]; - -int setup_socket(const char *cookied_socket_path) { - /* delete the cookie socket if it was left behind on a previous run */ - unlink(cookied_socket_path); - - int socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); - - if(socket_fd < 0) { - fprintf(stderr, "socket failed (%s)\n", strerror(errno)); - return -1; - } - - struct sockaddr_un sa; - sa.sun_family = AF_UNIX; - strcpy(sa.sun_path, cookied_socket_path); - - if(bind(socket_fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) { - fprintf(stderr, "bind failed (%s)\n", strerror(errno)); - return -1; - } - - if(listen(socket_fd, SOCK_BACKLOG) < 0) { - fprintf(stderr, "listen failed (%s)\n", strerror(errno)); - return -1; - } - - return socket_fd; -} - -const char *whitelist_path = NULL; -GPtrArray *whitelisted_hosts = NULL; -time_t whitelist_update_time = 0; - -void whitelist_line_cb(const gchar* line, void *user_data) { - (void) user_data; - - gchar *norm_host; - - const gchar *p = line; - while(isspace(*p)) - p++; - - if(p[0] == '#' || !p[0]) /* ignore comments and blank lines */ - return; - - if(p[0] == '.') - norm_host = g_strdup(p); - else - norm_host = g_strconcat(".", p, NULL); - - g_ptr_array_add(whitelisted_hosts, g_strchomp(norm_host)); -} - -gboolean load_whitelist(const char *whitelist_path) { - if(!file_exists(whitelist_path)) - return FALSE; - - /* check if the whitelist file was updated */ - struct stat f; - if(stat(whitelist_path, &f) < 0) - return FALSE; - - if(whitelisted_hosts == NULL) - whitelisted_hosts = g_ptr_array_new(); - - if(f.st_mtime > whitelist_update_time) { - /* the file was updated, reload the whitelist */ - if(verbose) puts("reloading whitelist"); - while(whitelisted_hosts->len > 0) { - g_free(g_ptr_array_index(whitelisted_hosts, 0)); - g_ptr_array_remove_index_fast(whitelisted_hosts, 0); - } - for_each_line_in_file(whitelist_path, whitelist_line_cb, NULL); - whitelist_update_time = f.st_mtime; - } - - return TRUE; -} - -gboolean should_save_cookie(const char *host) { - if(!load_whitelist(whitelist_path)) - return TRUE; /* some error with the file, assume no whitelist */ - - /* we normalize the hostname so it has a . in front like the whitelist entries */ - gchar *test_host = (host[0] == '.') ? g_strdup(host) : g_strconcat(".", host, NULL); - int hl = strlen(test_host); - - /* test against each entry in the whitelist */ - gboolean result = FALSE; - guint i; - for(i = 0; i < whitelisted_hosts->len; i++) { - /* a match means the host ends with (or is equal to) the whitelist entry */ - const gchar *entry = g_ptr_array_index(whitelisted_hosts, i); - int el = strlen(entry); - result = (el <= hl) && !strcmp(test_host + (hl - el), entry); - - if(result) - break; - } - - g_free(test_host); - - return result; -} - -void handle_request(SoupCookieJar *j, const char *buff, int len, int fd) { - const char *command = buff; - - const char *scheme = command + strlen(command) + 1; - if((scheme - buff) > len) { - fprintf(stderr, "got malformed or partial request\n"); - return; - } - - const char *host = scheme + strlen(scheme) + 1; - if((host - buff) > len) { - fprintf(stderr, "got malformed or partial request\n"); - return; - } - - const char *path = host + strlen(host) + 1; - if((path - buff) > len) { - fprintf(stderr, "got malformed or partial request\n"); - return; - } - - /* glue the parts back together into a SoupURI */ - char *u = g_strconcat(scheme, "://", host, path, NULL); - if(verbose) printf("%s %s\n", command, u); - SoupURI *uri = soup_uri_new(u); - g_free(u); - - if(!strcmp(command, "GET")) { - char *result = soup_cookie_jar_get_cookies(j, uri, TRUE); - if(result) { - if(verbose) puts(result); - if(write(fd, result, strlen(result)+1) < 0) - fprintf(stderr, "write failed (%s)", strerror(errno)); - - g_free(result); - } else { - if(verbose) puts("-"); - if(write(fd, "", 1) < 0) - fprintf(stderr, "write failed (%s)", strerror(errno)); - } - } else if(!strcmp(command, "PUT")) { - const char *name_and_val = path + strlen(path) + 1; - if((name_and_val - buff) > len) { - fprintf(stderr, "got malformed or partial request\n"); - return; - } - - if(verbose) puts(name_and_val); - - if(should_save_cookie(host)) { - char *eql = strchr(name_and_val, '='); - eql[0] = 0; - - const char *name = name_and_val; - const char *value = eql + 1; - - SoupCookie *cookie = soup_cookie_new(name, value, host, path, SOUP_COOKIE_MAX_AGE_ONE_YEAR); - - soup_cookie_jar_add_cookie(j, cookie); - } else if(verbose) - puts("no, blacklisted."); - - if(write(fd, "", 1) < 0) - fprintf(stderr, "write failed (%s)", strerror(errno)); - } - - soup_uri_free(uri); -} - -void -wait_for_things_to_happen_and_then_do_things(SoupCookieJar* j, int cookie_socket) { - GArray *connections = g_array_new (FALSE, FALSE, sizeof (int)); - - while(1) { - unsigned int i; - int r; - fd_set fs; - - int maxfd = cookie_socket; - FD_ZERO(&fs); - FD_SET(maxfd, &fs); - - for(i = 0; i < connections->len; i++) { - int fd = g_array_index(connections, int, i); - if(fd > maxfd) maxfd = fd; - FD_SET(fd, &fs); - } - - r = select(maxfd+1, &fs, NULL, NULL, NULL); - if(r < 0) { - fprintf(stderr, "select failed (%s)\n", strerror(errno)); - continue; - } - - if(FD_ISSET(cookie_socket, &fs)) { - /* handle new connection */ - int fd = accept(cookie_socket, NULL, NULL); - g_array_append_val(connections, fd); - if(verbose) puts("got connection."); - } - - for(i = 0; i < connections->len; i++) { - /* handle activity on a connection */ - int fd = g_array_index(connections, int, i); - if(FD_ISSET(fd, &fs)) { - r = read(fd, cookie_buffer, MAX_COOKIE_LENGTH); - if(r < 0) { - fprintf(stderr, "read failed (%s)\n", strerror(errno)); - continue; - } else if(r == 0) { - if(verbose) puts("client hung up."); - g_array_remove_index(connections, i); - i--; /* other elements in the array are moved down to fill the gap */ - continue; - } - cookie_buffer[r] = 0; - - handle_request(j, cookie_buffer, r, fd); - } - } - } -} - -void usage(const char *progname) { - printf("%s [-s socket-path] [-f cookies.txt] [-w whitelist-file] [-n] [-v]\n", progname); - puts("\t-n\tdon't daemonise the process"); - puts("\t-v\tbe verbose"); -} - -void daemonise() { - int r = fork(); - - if(r < 0) { - fprintf(stderr, "fork failed (%s)", strerror(errno)); - exit(1); - } else if (r > 0) { - /* this is the parent, which has done its job */ - exit(0); - } - - if(setsid() < 0) { - fprintf(stderr, "setsid failed (%s)", strerror(errno)); - exit(1); - } -} - -const char *pid_file_path = NULL; -const char *cookied_socket_path = NULL; - -void cleanup_after_signal(int signal) { - (void) signal; - unlink(pid_file_path); - unlink(cookied_socket_path); - exit(0); -} - -int main(int argc, char *argv[]) { - int i; - - const char *cookies_txt_path = NULL; - gboolean foreground = FALSE; - - for(i = 1; i < argc && argv[i][0] == '-'; i++) { - switch(argv[i][1]) { - case 's': - cookied_socket_path = argv[++i]; - break; - case 'f': - cookies_txt_path = argv[++i]; - break; - case 'w': - whitelist_path = argv[++i]; - break; - case 'n': - foreground = TRUE; - break; - case 'v': - verbose = 1; - break; - default: - usage(argv[0]); - return 1; - } - } - - if(!foreground) - daemonise(); - - if(!cookies_txt_path) - cookies_txt_path = g_strconcat(get_xdg_var(XDG[1]), "/uzbl/cookies.txt", NULL); - - if(!cookied_socket_path) - cookied_socket_path = g_strconcat(get_xdg_var(XDG[2]), "/uzbl/cookie_daemon_socket", NULL); - - if(!whitelist_path) - whitelist_path = g_strconcat(get_xdg_var(XDG[0]), "/uzbl/cookie_whitelist", NULL); - - /* write out and lock the pid file. - * this ensures that only one uzbl-cookie-manager is running per-socket. - * (we should probably also lock the cookies.txt to prevent accidents...) */ - pid_file_path = g_strconcat(cookied_socket_path, ".pid", NULL); - int lockfd = open(pid_file_path, O_RDWR|O_CREAT, 0600); - if(lockfd < 0) { - fprintf(stderr, "couldn't open pid file %s (%s)\n", pid_file_path, strerror(errno)); - return 1; - } - - if(flock(lockfd, LOCK_EX|LOCK_NB) < 0) { - fprintf(stderr, "couldn't lock pid file %s (%s)\n", pid_file_path, strerror(errno)); - fprintf(stderr, "uzbl-cookie-manager is probably already running\n"); - return 1; - } - - gchar* pids = g_strdup_printf("%d\n", getpid()); - write(lockfd, pids, strlen(pids)); - g_free(pids); - - struct sigaction sa; - sa.sa_handler = cleanup_after_signal; - if(sigaction(SIGINT, &sa, NULL) || sigaction(SIGTERM, &sa, NULL)) { - fprintf(stderr, "sigaction failed (%s)\n", strerror(errno)); - return 1; - } - - if(!foreground) { - /* close STDIO */ - close(0); - close(1); - close(2); - } - - g_type_init(); - - SoupCookieJar *j = soup_cookie_jar_text_new(cookies_txt_path, FALSE); - - int cookie_socket = setup_socket(cookied_socket_path); - if(cookie_socket < 0) - return 1; - - wait_for_things_to_happen_and_then_do_things(j, cookie_socket); - - return 0; -} diff --git a/src/uzbl-browser b/src/uzbl-browser index faa2829..81645ca 100755 --- a/src/uzbl-browser +++ b/src/uzbl-browser @@ -64,13 +64,6 @@ then export UZBL_UTIL_DIR fi -# uzbl-cookie-manager will exit if another instance is already running. -# we could also check if its pid file exists to avoid having to spawn it. -#if [ ! -f "$XDG_CACHE_HOME"/uzbl/cookie_daemon_socket.pid ] -#then -# ${UZBL_COOKIE_DAEMON:-uzbl-cookie-manager} -#fi - # uzbl-event-manager will exit if one is already running. # we could also check if its pid file exists to avoid having to spawn it. DAEMON_SOCKET="$XDG_CACHE_HOME"/uzbl/event_daemon -- cgit v1.2.3 From f6bd9e08bf16165f1ae2a7c98255fd89709a72a9 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 27 Dec 2010 21:40:22 -0700 Subject: remove talk_to_socket and all its associated bits --- README | 5 - docs/README.cookies | 63 ---------- extras/vim/syntax/uzbl.vim | 2 +- src/callbacks.c | 10 -- src/callbacks.h | 3 - src/cookie-jar.c | 286 ++------------------------------------------- src/cookie-jar.h | 12 -- src/uzbl-core.c | 5 +- src/uzbl-core.h | 1 - 9 files changed, 12 insertions(+), 375 deletions(-) delete mode 100644 docs/README.cookies diff --git a/README b/README index 35492da..2c87290 100644 --- a/README +++ b/README @@ -183,11 +183,6 @@ The following commands are recognized: the end, so the argument numbers will be higher. * `sync_sh ` - Synchronous version of `sh`, See `sync_spawn`. -* `talk_to_socket ` - - Send a message to `` and wait for a response. `` are - concatenated and separated by ASCII NUL bytes. - - Expects the socket type to be `SOCK_SEQPACKET` (see `connect(2)`). - - Waits for 500ms for a response. * `exit` - Closes `uzbl`. * `search ` diff --git a/docs/README.cookies b/docs/README.cookies deleted file mode 100644 index 148603f..0000000 --- a/docs/README.cookies +++ /dev/null @@ -1,63 +0,0 @@ -# Cookies and Uzbl # - -The speed of cookie lookups is important, since a single page load can involve -dozens of HTTP requests, each of which needs a separate cookie lookup (since -another instance of uzbl may have obtained new cookies for a site). - -It is possible handle cookie lookup (and storage) using a `spawn_async` cookie -handler, but spawning new processes is inherently slow so a `talk_to_socket` -cookie daemon (like the default uzbl-cookie-manager) is recommended. - -## uzbl-cookie-manager ## - -uzbl-cookie-manager is a cookie daemon based on libsoup's SoupCookieJar. Cookies -are stored in a file in the Mozilla cookies.txt format (default location -$XDG_DATA_HOME/.local/share/cookies.txt). - -### uzbl-cookie-manager Whitelist ### - -If a whitelist file is present (default location -$XDG_CONFIG_HOME/uzbl/cookie_whitelist), then website attempts to set cookies -will be ignored unless the site's domain is present in the whitelist. - -The whitelist can contain comment lines beginning with `#`, and domain lines. A -domain line beginning with . will whitelist the given domain name and any -subdomain of it. Otherwise only exact matches of the domain are whitelisted. - -For instance, given this whitelist file: - - example.com - .uzbl.org - -uzbl-cookie-manager would accept cookies for example.com, uzbl.org and -www.uzbl.org, but ignore cookies set for www.example.com (and any other -domain that is not a subdomain of uzbl.org). - -## uzbl-cookie-daemon ## - -uzbl-cookie-daemon is a Python cookie daemon based on Python's cookielib. -Cookielib's lookup algorithm isn't very efficient for our needs, so -uzbl-cookie-daemon is noticeably slow. - -## Cookie Daemon Protocol ## - -When uzbl's `cookie_handler` variable is set to `talk_to_socket path`, uzbl -connects to the Unix domain socket located at `path`. uzbl will send a cookie -lookup request on this socket every time it makes an HTTP request. The format of -this lookup request is: - - GET\0scheme\0host\0path\0 - -where `\0` is the null character, `scheme` is the URL scheme (http or https), -`host` is the hostname from the URL and `path` is the requested path. The cookie -daemon should respond with the names and values of cookies that match the -request, in the format used by the `Cookie` header, terminated with a `\0`. - -When a website adds, deletes or changes a cookie, uzbl notifies the cookie -daemon with a request in the format: - - PUT\0scheme\0host\0path\0name=value\0 - -where `scheme`, `host` and `path` are (approximately) as above, and `name=value` -is the cookie name-value pair to store. The cookie daemon should respond by -writing `\0` to the socket. diff --git a/extras/vim/syntax/uzbl.vim b/extras/vim/syntax/uzbl.vim index b8572c9..bf7108c 100644 --- a/extras/vim/syntax/uzbl.vim +++ b/extras/vim/syntax/uzbl.vim @@ -30,7 +30,7 @@ setl iskeyword=!-~,192-255 syn keyword uzblKeyword back forward scroll reload reload_ign_cache stop syn keyword uzblKeyword zoom_in zoom_out toggle_zoom_type uri script -syn keyword uzblKeyword toggle_status spawn sync_spawn sync_sh talk_to_socket +syn keyword uzblKeyword toggle_status spawn sync_spawn sync_sh sync_spawn_exec syn keyword uzblKeyword exit search search_reverse search_clear dehilight set syn keyword uzblKeyword dump_config dump_config_as_events chain print event syn keyword uzblKeyword request menu_add menu_link_add menu_image_add diff --git a/src/callbacks.c b/src/callbacks.c index f09dd0d..f41ac74 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -983,13 +983,3 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { } } } - -void -cmd_set_cookie_handler() { - if(uzbl.behave.cookie_handler[0] == 0) { - g_free(uzbl.behave.cookie_handler); - uzbl.behave.cookie_handler = NULL; - } - - uzbl_cookie_jar_set_handler(uzbl.net.soup_cookie_jar, uzbl.behave.cookie_handler); -} diff --git a/src/callbacks.h b/src/callbacks.h index 40fa80d..2116dd4 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -213,6 +213,3 @@ scroll_vert_cb(GtkAdjustment *adjust, void *w); gboolean scroll_horiz_cb(GtkAdjustment *adjust, void *w); - -void -cmd_set_cookie_handler(); diff --git a/src/cookie-jar.c b/src/cookie-jar.c index 626e454..82a5269 100644 --- a/src/cookie-jar.c +++ b/src/cookie-jar.c @@ -1,51 +1,20 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include #include #include "cookie-jar.h" #include "uzbl-core.h" #include "events.h" -static void -uzbl_cookie_jar_session_feature_init(SoupSessionFeatureInterface *iface, gpointer user_data); - -G_DEFINE_TYPE_WITH_CODE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR, - G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, uzbl_cookie_jar_session_feature_init)) +G_DEFINE_TYPE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR) -static void request_started (SoupSessionFeature *feature, SoupSession *session, SoupMessage *msg, SoupSocket *socket); static void changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie); -static void setup_handler(UzblCookieJar *jar); - -static void connect_cookie_socket(UzblCookieJar *jar); -static void disconnect_cookie_socket(UzblCookieJar *jar); - -static gchar *do_socket_request(UzblCookieJar *jar, gchar *request, int request_len); - -static bool has_socket_handler(UzblCookieJar *jar) { - return jar->socket_path != NULL; -} - static void soup_cookie_jar_socket_init(UzblCookieJar *jar) { - jar->handler = NULL; - jar->socket_path = NULL; - jar->connection_fd = -1; - jar->in_get_callback = 0; jar->in_manual_add = 0; } static void finalize(GObject *object) { - disconnect_cookie_socket(UZBL_COOKIE_JAR(object)); G_OBJECT_CLASS(soup_cookie_jar_socket_parent_class)->finalize(object); } @@ -55,120 +24,30 @@ soup_cookie_jar_socket_class_init(UzblCookieJarClass *socket_class) { SOUP_COOKIE_JAR_CLASS(socket_class)->changed = changed; } -/* override SoupCookieJar's request_started handler */ -static void -uzbl_cookie_jar_session_feature_init(SoupSessionFeatureInterface *iface, gpointer user_data) { - (void) user_data; - iface->request_started = request_started; -} - UzblCookieJar *uzbl_cookie_jar_new() { return g_object_new(UZBL_TYPE_COOKIE_JAR, NULL); } -void -uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar* handler) { - jar->handler = handler; - setup_handler(jar); -} - -char *get_cookies(UzblCookieJar *jar, SoupURI *uri) { - gchar *result, *path; - GString *s = g_string_new ("GET"); - - path = uri->path[0] ? uri->path : "/"; - - if(has_socket_handler(jar)) { - g_string_append_c(s, 0); /* null-terminate the GET */ - g_string_append_len(s, uri->scheme, strlen(uri->scheme)+1); - g_string_append_len(s, uri->host, strlen(uri->host)+1 ); - g_string_append_len(s, path, strlen(path)+1 ); - - result = do_socket_request(jar, s->str, s->len); - /* try it again; older cookie daemons closed the connection after each request */ - if(result == NULL) - result = do_socket_request(jar, s->str, s->len); - } else { - g_string_append_printf(s, " '%s' '%s' '%s'", uri->scheme, uri->host, uri->path); - - run_handler(jar->handler, s->str); - result = g_strdup(uzbl.comm.sync_stdout); - } - g_string_free(s, TRUE); - return result; -} - -/* this is a duplicate of SoupCookieJar's request_started that uses our get_cookies instead */ -static void -request_started(SoupSessionFeature *feature, SoupSession *session, - SoupMessage *msg, SoupSocket *socket) { - (void) session; (void) socket; - gchar *cookies; - - UzblCookieJar *jar = UZBL_COOKIE_JAR (feature); - SoupURI *uri = soup_message_get_uri(msg); - gboolean add_to_internal_jar = false; - - if(jar->handler) { - cookies = get_cookies(jar, uri); - } else { - /* no handler is set, fall back to the internal soup cookie jar */ - cookies = soup_cookie_jar_get_cookies(SOUP_COOKIE_JAR(jar), soup_message_get_uri (msg), TRUE); - } - - if (cookies && cookies[0] != 0) { - const gchar *next_cookie_start = cookies; - - if (add_to_internal_jar) { - /* add the cookie data that we just obtained from the cookie handler - to the cookie jar so that javascript has access to them. - we set this flag so that we don't trigger the PUT handler. */ - jar->in_get_callback = true; - do { - SoupCookie *soup_cookie = soup_cookie_parse(next_cookie_start, uri); - if(soup_cookie) - soup_cookie_jar_add_cookie(SOUP_COOKIE_JAR(uzbl.net.soup_cookie_jar), soup_cookie); - next_cookie_start = strchr(next_cookie_start, ';'); - } while(next_cookie_start++ != NULL); - jar->in_get_callback = false; - } - - soup_message_headers_replace (msg->request_headers, "Cookie", cookies); - } else { - soup_message_headers_remove (msg->request_headers, "Cookie"); - } - - if(cookies) - g_free (cookies); -} - static void changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { - SoupCookie * cookie = new_cookie ? new_cookie : old_cookie; + SoupCookie *cookie = new_cookie ? new_cookie : old_cookie; UzblCookieJar *uzbl_jar = UZBL_COOKIE_JAR(jar); - /* when Uzbl begins an HTTP request, it GETs cookies from the handler - and then adds them to the cookie jar so that javascript can access - these cookies. this causes a 'changed' callback, which we don't want - to do anything, so we just return. - - (if SoupCookieJar let us override soup_cookie_jar_get_cookies we - wouldn't have to do this.) */ - if(uzbl_jar->in_get_callback) - return; - - gchar *scheme = cookie->secure ? "https" : "http"; - - /* send a ADD or DELETE -_COOKIE event depending on what have changed */ + /* send a ADD or DELETE -_COOKIE event depending on what has changed. these + * events aren't sent when a cookie changes due to an add/delete_cookie + * command because otherwise a loop would occur when a cookie change is + * propagated to other uzbl instances using add/delete_cookie. */ if(!uzbl_jar->in_manual_add) { + gchar *scheme = cookie->secure ? "https" : "http"; + gchar *expires = NULL; if(cookie->expires) expires = g_strdup_printf ("%d", soup_date_to_time_t (cookie->expires)); gchar * eventstr = g_strdup_printf ("'%s' '%s' '%s' '%s' '%s' '%s'", cookie->domain, cookie->path, cookie->name, cookie->value, scheme, expires?expires:""); - if(new_cookie) + if(new_cookie) send_event(ADD_COOKIE, eventstr, NULL); else send_event(DELETE_COOKIE, eventstr, NULL); @@ -176,151 +55,4 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { if(expires) g_free(expires); } - - /* the cookie daemon is only interested in new cookies and changed - ones, it can take care of deleting expired cookies on its own. */ - if(!new_cookie) - return; - - GString *s = g_string_new ("PUT"); - - if(has_socket_handler(uzbl_jar)) { - g_string_append_c(s, 0); /* null-terminate the PUT */ - g_string_append_len(s, scheme, strlen(scheme)+1); - g_string_append_len(s, new_cookie->domain, strlen(new_cookie->domain)+1 ); - g_string_append_len(s, new_cookie->path, strlen(new_cookie->path)+1 ); - g_string_append_printf(s, "%s=%s", new_cookie->name, new_cookie->value); - - gchar *result = do_socket_request(uzbl_jar, s->str, s->len+1); - /* try it again; older cookie daemons closed the connection after each request */ - if(!result) - result = do_socket_request(uzbl_jar, s->str, s->len+1); - - g_free(result); - } else { - g_string_append_printf(s, " '%s' '%s' '%s' '%s=%s'", scheme, new_cookie->domain, new_cookie->path, new_cookie->name, new_cookie->value); - - run_handler(uzbl_jar->handler, s->str); - } - - g_string_free(s, TRUE); -} - -static void -setup_handler(UzblCookieJar *jar) { - if(jar->handler && strncmp(jar->handler, "talk_to_socket", strlen("talk_to_socket")) == 0) { - /* extract the socket path from the handler. */ - jar->socket_path = jar->handler + strlen("talk_to_socket"); - while(isspace(*jar->socket_path)) - jar->socket_path++; - if(*jar->socket_path == 0) - return; /* there was no path specified. */ - disconnect_cookie_socket(jar); - connect_cookie_socket(jar); - } else { - jar->socket_path = NULL; - } -} - -static void -connect_cookie_socket(UzblCookieJar *jar) { - struct sockaddr_un sa; - int fd; - - g_strlcpy(sa.sun_path, jar->socket_path, sizeof(sa.sun_path)); - sa.sun_family = AF_UNIX; - - /* create socket file descriptor and connect it to path */ - fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); - if(fd == -1) { - g_printerr("connect_cookie_socket: creating socket failed (%s)\n", strerror(errno)); - return; - } - - if(connect(fd, (struct sockaddr*)&sa, sizeof(sa))) { - g_printerr("connect_cookie_socket: connect failed (%s)\n", strerror(errno)); - close(fd); - return; - } - - /* successful connection! */ - jar->connection_fd = fd; -} - -static void -disconnect_cookie_socket(UzblCookieJar *jar) { - if(jar->connection_fd > 0) { - close(jar->connection_fd); - jar->connection_fd = -1; - } -} - -static gchar *do_socket_request(UzblCookieJar *jar, gchar *request, int request_length) { - int len; - ssize_t ret; - struct pollfd pfd; - gchar *result = NULL; - - if(jar->connection_fd < 0) - connect_cookie_socket(jar); /* connection was lost, reconnect */ - - /* write request */ - ret = write(jar->connection_fd, request, request_length); - if(ret == -1) { - g_printerr("talk_to_socket: write failed (%s)\n", strerror(errno)); - disconnect_cookie_socket(jar); - return NULL; - } - - /* wait for a response, with a 500ms timeout */ - pfd.fd = jar->connection_fd; - pfd.events = POLLIN; - while(1) { - ret = poll(&pfd, 1, 500); - if(ret == 1) break; - if(ret == 0) errno = ETIMEDOUT; - if(errno == EINTR) continue; - g_printerr("talk_to_socket: poll failed while waiting for input (%s)\n", - strerror(errno)); - if(errno != ETIMEDOUT) - disconnect_cookie_socket(jar); - return NULL; - } - - /* get length of response */ - if(ioctl(jar->connection_fd, FIONREAD, &len) == -1) { - g_printerr("talk_to_socket: cannot find daemon response length, " - "ioctl failed (%s)\n", strerror(errno)); - disconnect_cookie_socket(jar); - return NULL; - } - - /* there was an empty response. */ - if(len == 0) - return g_strdup(""); - - /* there is a response, read it */ - result = g_malloc(len + 1); - if(!result) { - g_printerr("talk_to_socket: failed to allocate %d bytes\n", len); - return NULL; - } - result[len] = 0; /* ensure result is null terminated */ - - gchar *p = result; - while(len > 0) { - ret = read(jar->connection_fd, p, len); - if(ret == -1) { - g_printerr("talk_to_socket: failed to read from socket (%s)\n", - strerror(errno)); - disconnect_cookie_socket(jar); - g_free(result); - return NULL; - } else { - len -= ret; - p += ret; - } - } - - return result; } diff --git a/src/cookie-jar.h b/src/cookie-jar.h index f3e3733..05f4a6f 100644 --- a/src/cookie-jar.h +++ b/src/cookie-jar.h @@ -10,12 +10,6 @@ typedef struct { SoupCookieJar parent; - const gchar *handler; - - const gchar *socket_path; - int connection_fd; - - gboolean in_get_callback; gboolean in_manual_add; } UzblCookieJar; @@ -25,10 +19,4 @@ typedef struct { UzblCookieJar *uzbl_cookie_jar_new(); -void -uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar *handler); - -char -*get_cookies(UzblCookieJar *jar, SoupURI *uri); - #endif diff --git a/src/uzbl-core.c b/src/uzbl-core.c index fc21978..66842a9 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -90,7 +90,6 @@ const struct var_name_to_ptr_t { { "title_format_short", PTR_V_STR(uzbl.behave.title_format_short, 1, NULL)}, { "icon", PTR_V_STR(uzbl.gui.icon, 1, set_icon)}, { "forward_keys", PTR_V_INT(uzbl.behave.forward_keys, 1, NULL)}, - { "cookie_handler", PTR_V_STR(uzbl.behave.cookie_handler, 1, cmd_set_cookie_handler)}, { "authentication_handler", PTR_V_STR(uzbl.behave.authentication_handler, 1, set_authentication_handler)}, { "scheme_handler", PTR_V_STR(uzbl.behave.scheme_handler, 1, NULL)}, { "download_handler", PTR_V_STR(uzbl.behave.download_handler, 1, NULL)}, @@ -584,10 +583,10 @@ struct {const char *key; CommandInfo value;} cmdlist[] = { "script", {run_external_js, 0} }, { "toggle_status", {toggle_status_cb, 0} }, { "spawn", {spawn_async, 0} }, - { "sync_spawn", {spawn_sync, 0} }, // needed for cookie handler + { "sync_spawn", {spawn_sync, 0} }, { "sync_spawn_exec", {spawn_sync_exec, 0} }, // needed for load_cookies.sh :( { "sh", {spawn_sh_async, 0} }, - { "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler + { "sync_sh", {spawn_sh_sync, 0} }, { "exit", {close_uzbl, 0} }, { "search", {search_forward_text, TRUE} }, { "search_reverse", {search_reverse_text, TRUE} }, diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 98ae342..14f03a6 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -124,7 +124,6 @@ typedef struct { gchar* status_background; gchar* fifo_dir; gchar* socket_dir; - gchar* cookie_handler; gchar* authentication_handler; gchar* default_font_family; gchar* monospace_font_family; -- cgit v1.2.3 From 113853220d5d99720c448c76474c91fc283ea4e5 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Wed, 29 Dec 2010 16:56:33 -0700 Subject: fix a null pointer dereference in create_stdin (found with cppcheck) --- src/uzbl-core.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 34cf364..039c520 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1687,21 +1687,16 @@ control_stdin(GIOChannel *gio, GIOCondition condition) { void create_stdin () { - GIOChannel *chan = NULL; - GError *error = NULL; - - chan = g_io_channel_unix_new(fileno(stdin)); + GIOChannel *chan = g_io_channel_unix_new(fileno(stdin)); if (chan) { if (!g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_stdin, NULL)) { - g_error ("Stdin: could not add watch\n"); - } else { - if (uzbl.state.verbose) - printf ("Stdin: watch added successfully\n"); + g_error ("create_stdin: could not add watch\n"); + } else if (uzbl.state.verbose) { + printf ("create_stdin: watch added successfully\n"); } } else { - g_error ("Stdin: Error while opening: %s\n", error->message); + g_error ("create_stdin: error while opening stdin\n"); } - if (error) g_error_free (error); } gboolean -- cgit v1.2.3 From 15c83d8a85a150f46e80f7fc97041f10a43a96df Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 1 Jan 2011 03:01:48 +0100 Subject: malformed cookie rows pass through delete --- examples/data/plugins/cookies.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py index c9fe2c3..9eccace 100644 --- a/examples/data/plugins/cookies.py +++ b/examples/data/plugins/cookies.py @@ -38,24 +38,38 @@ class TextStore(object): self.filename = filename def as_event(self, cookie): + """Convert cookie.txt row to uzbls cookie event format""" + scheme = { + 'TRUE' : 'https', + 'FALSE' : 'http' + } if cookie[0].startswith("#HttpOnly_"): domain = cookie[0][len("#HttpOnly_"):] elif cookie[0].startswith('#'): return None else: domain = cookie[0] - return (domain, - cookie[2], - cookie[5], - cookie[6], - 'https' if cookie[3] == 'TRUE' else 'http', - cookie[4]) + try: + return (domain, + cookie[2], + cookie[5], + cookie[6], + scheme[cookie[3]], + cookie[4]) + except (KeyError,IndexError): + # Let malformed rows pass through like comments + return None def as_file(self, cookie): + """Convert cookie event to cookie.txt row""" + secure = { + 'https' : 'TRUE', + 'http' : 'FALSE' + } return (cookie[0], 'TRUE' if cookie[0].startswith('.') else 'FALSE', cookie[1], - 'TRUE' if cookie[4] == 'https' else 'FALSE', + secure[cookie[4]], cookie[5], cookie[2], cookie[3]) -- cgit v1.2.3 From 08b45348831fadadeaac4cefb03eb11538c7aa0c Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 11 Jan 2011 12:51:00 +0100 Subject: fix bug in history search disable keycmd set in search as this will not work from stacked bindings --- examples/config/config | 1 + examples/data/plugins/history.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/config/config b/examples/config/config index 7b9fba2..ddeca7b 100644 --- a/examples/config/config +++ b/examples/config/config @@ -185,6 +185,7 @@ set ebind = @mode_bind global,-insert @ebind = event HISTORY_PREV @ebind = event HISTORY_NEXT +@ebind r_ = event HISTORY_SEARCH %s # Keycmd injection/append examples. #@ebind su = event INJECT_KEYCMD \@uri #@ebind st = event INJECT_KEYCMD \@title diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py index 886cbe0..78a94ce 100644 --- a/examples/data/plugins/history.py +++ b/examples/data/plugins/history.py @@ -57,7 +57,7 @@ class History(object): def search(self, key): self.search_key = key - return self.prev() + self.cursor = None def add(self, cmd): if self._temporary: @@ -106,7 +106,7 @@ def history_next(uzbl, _x): uzbl.logger.debug('NEXT %s' % uzbl.history) def history_search(uzbl, key): - uzbl.set_keycmd(history.search(key)) + uzbl.history.search(key) uzbl.logger.debug('SEARCH %s %s' % (key, uzbl.history)) end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') -- cgit v1.2.3 From 1bb84ff92e4ed2e7594a8311ec95428a4a0600cc Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 13 Jan 2011 12:11:09 -0700 Subject: simplify parse_cmd_line --- src/uzbl-core.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 147a9ae..8f9ff88 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1467,23 +1467,14 @@ set_var_value(const gchar *name, gchar *val) { void parse_cmd_line(const char *ctl_line, GString *result) { - size_t len=0; - gchar *ctlstrip = NULL; gchar *exp_line = NULL; - gchar *work_string = NULL; + gchar *work_string = g_strdup(ctl_line); - work_string = g_strdup(ctl_line); + /* strip trailing newline, and any other whitespace in front */ + g_strstrip(work_string); - /* strip trailing newline */ - len = strlen(ctl_line); - if (work_string[len - 1] == '\n') - ctlstrip = g_strndup(work_string, len - 1); - else - ctlstrip = g_strdup(work_string); - g_free(work_string); - - if( strcmp(g_strchug(ctlstrip), "") && - strcmp(exp_line = expand(ctlstrip, 0), "") + if( strcmp(work_string, "") && + strcmp(exp_line = expand(work_string, 0), "") ) { /* ignore comments */ if((exp_line[0] == '#')) @@ -1500,7 +1491,7 @@ parse_cmd_line(const char *ctl_line, GString *result) { g_free(exp_line); } - g_free(ctlstrip); + g_free(work_string); } /*@null@*/ gchar* -- cgit v1.2.3 From 9340e4f23264c7e820b52f18de5ca29132c68e72 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 13 Jan 2011 13:46:31 -0700 Subject: refactor parse_command and parse_cmd_line --- src/uzbl-core.c | 241 +++++++++++++++++++++++++++++++------------------------- src/uzbl-core.h | 15 +++- 2 files changed, 145 insertions(+), 111 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 8f9ff88..ba6b4de 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -571,55 +571,55 @@ VIEWFUNC(go_forward) #undef VIEWFUNC /* -- command to callback/function map for things we cannot attach to any signals */ -struct {const char *key; CommandInfo value;} cmdlist[] = +CommandInfo cmdlist[] = { /* key function no_split */ - { "back", {view_go_back, 0} }, - { "forward", {view_go_forward, 0} }, - { "scroll", {scroll_cmd, 0} }, - { "reload", {view_reload, 0}, }, - { "reload_ign_cache", {view_reload_bypass_cache, 0} }, - { "stop", {view_stop_loading, 0}, }, - { "zoom_in", {view_zoom_in, 0}, }, //Can crash (when max zoom reached?). - { "zoom_out", {view_zoom_out, 0}, }, - { "toggle_zoom_type", {toggle_zoom_type, 0}, }, - { "uri", {load_uri, TRUE} }, - { "js", {run_js, TRUE} }, - { "script", {run_external_js, 0} }, - { "toggle_status", {toggle_status_cb, 0} }, - { "spawn", {spawn_async, 0} }, - { "sync_spawn", {spawn_sync, 0} }, // needed for cookie handler - { "sync_spawn_exec", {spawn_sync_exec, 0} }, // needed for load_cookies.sh :( - { "sh", {spawn_sh_async, 0} }, - { "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler - { "exit", {close_uzbl, 0} }, - { "search", {search_forward_text, TRUE} }, - { "search_reverse", {search_reverse_text, TRUE} }, - { "search_clear", {search_clear, TRUE} }, - { "dehilight", {dehilight, 0} }, - { "set", {set_var, TRUE} }, - { "dump_config", {act_dump_config, 0} }, - { "dump_config_as_events", {act_dump_config_as_events, 0} }, - { "chain", {chain, 0} }, - { "print", {print, TRUE} }, - { "event", {event, TRUE} }, - { "request", {event, TRUE} }, - { "menu_add", {menu_add, TRUE} }, - { "menu_link_add", {menu_add_link, TRUE} }, - { "menu_image_add", {menu_add_image, TRUE} }, - { "menu_editable_add", {menu_add_edit, TRUE} }, - { "menu_separator", {menu_add_separator, TRUE} }, - { "menu_link_separator", {menu_add_separator_link, TRUE} }, - { "menu_image_separator", {menu_add_separator_image, TRUE}}, - { "menu_editable_separator", {menu_add_separator_edit, TRUE} }, - { "menu_remove", {menu_remove, TRUE} }, - { "menu_link_remove", {menu_remove_link, TRUE} }, - { "menu_image_remove", {menu_remove_image, TRUE} }, - { "menu_editable_remove", {menu_remove_edit, TRUE} }, - { "hardcopy", {hardcopy, TRUE} }, - { "include", {include, TRUE} }, - { "show_inspector", {show_inspector, 0} }, - { "add_cookie", {add_cookie, 0} }, - { "delete_cookie", {delete_cookie, 0} } + { "back", view_go_back, 0 }, + { "forward", view_go_forward, 0 }, + { "scroll", scroll_cmd, 0 }, + { "reload", view_reload, 0 }, + { "reload_ign_cache", view_reload_bypass_cache, 0 }, + { "stop", view_stop_loading, 0 }, + { "zoom_in", view_zoom_in, 0 }, //Can crash (when max zoom reached?). + { "zoom_out", view_zoom_out, 0 }, + { "toggle_zoom_type", toggle_zoom_type, 0 }, + { "uri", load_uri, TRUE }, + { "js", run_js, TRUE }, + { "script", run_external_js, 0 }, + { "toggle_status", toggle_status_cb, 0 }, + { "spawn", spawn_async, 0 }, + { "sync_spawn", spawn_sync, 0 }, // needed for cookie handler + { "sync_spawn_exec", spawn_sync_exec, 0 }, // needed for load_cookies.sh :( + { "sh", spawn_sh_async, 0 }, + { "sync_sh", spawn_sh_sync, 0 }, // needed for cookie handler + { "exit", close_uzbl, 0 }, + { "search", search_forward_text, TRUE }, + { "search_reverse", search_reverse_text, TRUE }, + { "search_clear", search_clear, TRUE }, + { "dehilight", dehilight, 0 }, + { "set", set_var, TRUE }, + { "dump_config", act_dump_config, 0 }, + { "dump_config_as_events", act_dump_config_as_events, 0 }, + { "chain", chain, 0 }, + { "print", print, TRUE }, + { "event", event, TRUE }, + { "request", event, TRUE }, + { "menu_add", menu_add, TRUE }, + { "menu_link_add", menu_add_link, TRUE }, + { "menu_image_add", menu_add_image, TRUE }, + { "menu_editable_add", menu_add_edit, TRUE }, + { "menu_separator", menu_add_separator, TRUE }, + { "menu_link_separator", menu_add_separator_link, TRUE }, + { "menu_image_separator", menu_add_separator_image, TRUE }, + { "menu_editable_separator", menu_add_separator_edit, TRUE }, + { "menu_remove", menu_remove, TRUE }, + { "menu_link_remove", menu_remove_link, TRUE }, + { "menu_image_remove", menu_remove_image, TRUE }, + { "menu_editable_remove", menu_remove_edit, TRUE }, + { "hardcopy", hardcopy, TRUE }, + { "include", include, TRUE }, + { "show_inspector", show_inspector, 0 }, + { "add_cookie", add_cookie, 0 }, + { "delete_cookie", delete_cookie, 0 } }; void @@ -629,7 +629,7 @@ commands_hash(void) uzbl.behave.commands = g_hash_table_new(g_str_hash, g_str_equal); for (i = 0; i < LENGTH(cmdlist); i++) - g_hash_table_insert(uzbl.behave.commands, (gpointer) cmdlist[i].key, &cmdlist[i].value); + g_hash_table_insert(uzbl.behave.commands, (gpointer) cmdlist[i].key, &cmdlist[i]); } void @@ -1141,15 +1141,15 @@ dehilight (WebKitWebView *page, GArray *argv, GString *result) { void chain (WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) result; - gchar *a = NULL; - gchar **parts = NULL; + (void) page; guint i = 0; - while ((a = argv_idx(argv, i++))) { - parts = g_strsplit (a, " ", 2); - if (parts[0]) - parse_command(parts[0], parts[1], result); - g_strfreev (parts); + const gchar *cmd; + while ((cmd = argv_idx(argv, i++))) { + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + CommandInfo *c = parse_command_parts(cmd, a); + if (c) + run_parsed_command(c, a, result); + g_array_free (a, TRUE); } } @@ -1332,48 +1332,81 @@ spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) { } void -parse_command(const char *cmd, const char *param, GString *result) { - CommandInfo *c; - GString *tmp = g_string_new(""); +run_parsed_command(CommandInfo *c, GArray *a, GString *result) { + c->function(uzbl.gui.web_view, a, result); - if ((c = g_hash_table_lookup(uzbl.behave.commands, cmd))) { - guint i; - gchar **par = split_quoted(param, TRUE); - GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + /* send the COMMAND_EXECUTED event, except for set and event/request commands */ + if(strcmp("set", c->key) && + strcmp("event", c->key) && + strcmp("request", c->key)) { + GString *tmp = g_string_new(c->key); + const gchar *p; + guint i = 0; + while ((p = argv_idx(a, i++))) + g_string_append_printf(tmp, " '%s'", p); + send_event(COMMAND_EXECUTED, tmp->str, NULL); + g_string_free(tmp, TRUE); + } +} - if (c->no_split) { /* don't split */ - sharg_append(a, param); - } else if (par) { - for (i = 0; i < g_strv_length(par); i++) - sharg_append(a, par[i]); - } +void +parse_command_arguments(const gchar *p, GArray *a, gboolean no_split) { + if (no_split && p) { /* pass the parameters through in one chunk */ + sharg_append(a, g_strdup(p)); + return; + } + + gchar **par = split_quoted(p, TRUE); + if (par) { + guint i; + for (i = 0; i < g_strv_length(par); i++) + sharg_append(a, g_strdup(par[i])); + g_strfreev (par); + } +} - if (result == NULL) { - GString *result_print = g_string_new(""); +CommandInfo * +parse_command_parts(const gchar *line, GArray *a) { + CommandInfo *c = NULL; - c->function(uzbl.gui.web_view, a, result_print); - if (result_print->len) - printf("%*s\n", (int)result_print->len, result_print->str); + gchar *exp_line = expand(line, 0); + if(exp_line[0] == '\0') + return NULL; - g_string_free(result_print, TRUE); - } else { - c->function(uzbl.gui.web_view, a, result); - } - g_strfreev (par); - g_array_free (a, TRUE); + /* separate the line into the command and its parameters */ + gchar **tokens = g_strsplit(exp_line, " ", 2); - if(strcmp("set", cmd) && - strcmp("event", cmd) && - strcmp("request", cmd)) { - g_string_printf(tmp, "%s %s", cmd, param?param:""); - send_event(COMMAND_EXECUTED, tmp->str, NULL); - } - } - else { - g_string_printf (tmp, "%s %s", cmd, param?param:""); - send_event(COMMAND_ERROR, tmp->str, NULL); + /* look up the command */ + c = g_hash_table_lookup(uzbl.behave.commands, tokens[0]); + + if(!c) { + send_event(COMMAND_ERROR, exp_line, NULL); + g_free(exp_line); + g_strfreev(tokens); + return NULL; } - g_string_free(tmp, TRUE); + + gchar *p = g_strdup(tokens[1]); + g_free(exp_line); + g_strfreev(tokens); + + /* parse the arguments */ + parse_command_arguments(p, a, c->no_split); + g_free(p); + + return c; +} + +void +parse_command(const char *cmd, const char *params, GString *result) { + CommandInfo *c = g_hash_table_lookup(uzbl.behave.commands, cmd); + + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + + parse_command_arguments(params, a, c->no_split); + run_parsed_command(c, a, result); + + g_array_free (a, TRUE); } @@ -1467,28 +1500,18 @@ set_var_value(const gchar *name, gchar *val) { void parse_cmd_line(const char *ctl_line, GString *result) { - gchar *exp_line = NULL; gchar *work_string = g_strdup(ctl_line); /* strip trailing newline, and any other whitespace in front */ g_strstrip(work_string); - if( strcmp(work_string, "") && - strcmp(exp_line = expand(work_string, 0), "") - ) { - /* ignore comments */ - if((exp_line[0] == '#')) - ; - - /* parse a command */ - else { - gchar **tokens = NULL; - - tokens = g_strsplit(exp_line, " ", 2); - parse_command(tokens[0], tokens[1], result); - g_strfreev(tokens); - } - g_free(exp_line); + if( strcmp(work_string, "") ) { + if((work_string[0] != '#')) { /* ignore comments */ + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + CommandInfo *c = parse_command_parts(work_string, a); + run_parsed_command(c, a, result); + g_array_free (a, TRUE); + } } g_free(work_string); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index f81722d..ef948ca 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -479,10 +479,21 @@ builtins(); typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result); typedef struct { - Command function; - gboolean no_split; + const gchar *key; + Command function; + gboolean no_split; } CommandInfo; +CommandInfo * +parse_command_parts(const gchar *line, GArray *a); + +void +parse_command_arguments(const gchar *p, GArray *a, gboolean no_split); + +void +run_parsed_command(CommandInfo *c, GArray *a, GString *result); + + typedef struct { gchar *name; gchar *cmd; -- cgit v1.2.3 From 975e322d37afaca6e565b37282f2d9e6038124bc Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 13 Jan 2011 12:11:19 -0700 Subject: add a variable @_ that expands to the result of the last sync command --- src/uzbl-core.c | 9 ++++++++- src/uzbl-core.h | 3 ++- tests/test-command.c | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index ba6b4de..8e14982 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -145,6 +145,7 @@ const struct var_name_to_ptr_t { { "SELECTED_URI", PTR_C_STR(uzbl.state.selected_url, NULL)}, { "NAME", PTR_C_STR(uzbl.state.instance_name, NULL)}, { "PID", PTR_C_STR(uzbl.info.pid_str, NULL)}, + { "_", PTR_C_STR(uzbl.state.last_result, NULL)}, { NULL, {.ptr.s = NULL, .type = TYPE_INT, .dump = 0, .writeable = 0, .func = NULL}} }; @@ -1347,6 +1348,11 @@ run_parsed_command(CommandInfo *c, GArray *a, GString *result) { send_event(COMMAND_EXECUTED, tmp->str, NULL); g_string_free(tmp, TRUE); } + + if(result) { + g_free(uzbl.state.last_result); + uzbl.state.last_result = g_strdup(result->str); + } } void @@ -2294,7 +2300,8 @@ initialize(int argc, char *argv[]) { uzbl.state.executable_path = g_strdup(argv[0]); uzbl.state.selected_url = NULL; - uzbl.state.searchtx = NULL; + uzbl.state.searchtx = NULL; + uzbl.state.last_result = NULL; GOptionContext* context = g_option_context_new ("[ uri ] - load a uri by default"); g_option_context_add_main_entries (context, entries, NULL); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index ef948ca..049053a 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -98,7 +98,8 @@ typedef struct { gchar *selected_url; gchar *last_selected_url; gchar *executable_path; - gchar* searchtx; + gchar *searchtx; + gchar *last_result; gboolean verbose; gboolean events_stdout; GPtrArray *event_buffer; diff --git a/tests/test-command.c b/tests/test-command.c index 7b33405..20c6aa0 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -281,6 +281,21 @@ test_js (void) { g_string_free(result, TRUE); } +void +test_last_result (void) { + GString *result = g_string_new(""); + + /* the last result gets set */ + parse_cmd_line("js -1", result); + g_assert_cmpstr("-1", ==, uzbl.state.last_result); + + /* the last result can be used in a chain */ + parse_cmd_line("chain 'js 1' 'js \\@_ + 1'", result); + g_assert_cmpstr("2", ==, uzbl.state.last_result); + + g_string_free(result, TRUE); +} + void test_run_handler_arg_order (void) { run_handler("sync_spawn echo uvw xyz", "abc def"); @@ -320,6 +335,8 @@ main (int argc, char *argv[]) { g_test_add_func("/test-command/js", test_js); + g_test_add_func("/test-command/last-result", test_last_result); + /* the following aren't really "command" tests, but they're not worth * splitting into a separate file yet */ g_test_add_func("/test-command/run_handler/arg-order", test_run_handler_arg_order); -- cgit v1.2.3 From 99961c4561f478523048ed69b37b37c432c42b8a Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 13 Jan 2011 17:41:08 -0700 Subject: kill run_handler, inject_handler_args, strfree and sync_stdout --- src/callbacks.c | 51 ++++++---- src/cookie-jar.c | 56 ++++++++--- src/uzbl-core.c | 271 ++++++++++++++++----------------------------------- src/uzbl-core.h | 12 +-- tests/test-command.c | 37 +------ 5 files changed, 166 insertions(+), 261 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index 7b06873..bc06a45 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -641,23 +641,26 @@ navigation_decision_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNe printf("Navigation requested -> %s\n", uri); if (uzbl.behave.scheme_handler) { - GString *s = g_string_new (""); - g_string_printf(s, "'%s'", uri); + GString *result = g_string_new (""); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + const CommandInfo *c = parse_command_parts(uzbl.behave.scheme_handler, a); - run_handler(uzbl.behave.scheme_handler, s->str); + if(c) { + g_array_append_val(a, uri); + run_parsed_command(c, a, result); + } + g_array_free(a, TRUE); - if(uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) { - char *p = strchr(uzbl.comm.sync_stdout, '\n' ); + if(result->len > 0) { + char *p = strchr(result->str, '\n' ); if ( p != NULL ) *p = '\0'; - if (!strcmp(uzbl.comm.sync_stdout, "USED")) { + if (!strcmp(result->str, "USED")) { webkit_web_policy_decision_ignore(policy_decision); decision_made = TRUE; } } - if (uzbl.comm.sync_stdout) - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); - g_string_free(s, TRUE); + g_string_free(result, TRUE); } if (!decision_made) webkit_web_policy_decision_use(policy_decision); @@ -841,27 +844,35 @@ download_cb(WebKitWebView *web_view, WebKitDownload *download, gpointer user_dat (this may be inaccurate, there's nothing we can do about that.) */ unsigned int total_size = webkit_download_get_total_size(download); - gchar *ev = g_strdup_printf("'%s' '%s' '%s' %d", uri, suggested_filename, - content_type, total_size); - run_handler(uzbl.behave.download_handler, ev); - g_free(ev); - - /* no response, cancel the download */ - if(!uzbl.comm.sync_stdout) { + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + const CommandInfo *c = parse_command_parts(uzbl.behave.download_handler, a); + if(!c) { webkit_download_cancel(download); + g_array_free(a, TRUE); return FALSE; } + g_array_append_val(a, uri); + g_array_append_val(a, suggested_filename); + g_array_append_val(a, content_type); + gchar *total_size_s = g_strdup_printf("%d", total_size); + g_array_append_val(a, total_size_s); + + GString *result = g_string_new (""); + run_parsed_command(c, a, result); + + g_free(total_size_s); + g_array_free(a, TRUE); + /* no response, cancel the download */ - if(uzbl.comm.sync_stdout[0] == 0) { + if(result->len == 0) { webkit_download_cancel(download); - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); return FALSE; } /* we got a response, it's the path we should download the file to */ - gchar *destination_path = uzbl.comm.sync_stdout; - uzbl.comm.sync_stdout = NULL; + gchar *destination_path = result->str; + g_string_free(result, FALSE); /* presumably people don't need newlines in their filenames. */ char *p = strchr(destination_path, '\n'); diff --git a/src/cookie-jar.c b/src/cookie-jar.c index 626e454..9ddef3b 100644 --- a/src/cookie-jar.c +++ b/src/cookie-jar.c @@ -74,11 +74,11 @@ uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar* handler) { char *get_cookies(UzblCookieJar *jar, SoupURI *uri) { gchar *result, *path; - GString *s = g_string_new ("GET"); path = uri->path[0] ? uri->path : "/"; if(has_socket_handler(jar)) { + GString *s = g_string_new ("GET"); g_string_append_c(s, 0); /* null-terminate the GET */ g_string_append_len(s, uri->scheme, strlen(uri->scheme)+1); g_string_append_len(s, uri->host, strlen(uri->host)+1 ); @@ -88,13 +88,30 @@ char *get_cookies(UzblCookieJar *jar, SoupURI *uri) { /* try it again; older cookie daemons closed the connection after each request */ if(result == NULL) result = do_socket_request(jar, s->str, s->len); + + g_string_free(s, TRUE); } else { - g_string_append_printf(s, " '%s' '%s' '%s'", uri->scheme, uri->host, uri->path); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + + const CommandInfo *c = parse_command_parts(jar->handler, a); + if(!c) { + g_array_free(a, TRUE); + return NULL; + } - run_handler(jar->handler, s->str); - result = g_strdup(uzbl.comm.sync_stdout); + /* add our handler args */ + g_array_append_val(a, "GET"); + g_array_append_val(a, uri->scheme); + g_array_append_val(a, uri->host); + g_array_append_val(a, uri->path); + + GString *r = g_string_new (""); + run_parsed_command(c, a, r); + result = r->str; + g_string_free(r, FALSE); + g_array_free(a, TRUE); } - g_string_free(s, TRUE); + return result; } @@ -168,7 +185,7 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { gchar * eventstr = g_strdup_printf ("'%s' '%s' '%s' '%s' '%s' '%s'", cookie->domain, cookie->path, cookie->name, cookie->value, scheme, expires?expires:""); - if(new_cookie) + if(new_cookie) send_event(ADD_COOKIE, eventstr, NULL); else send_event(DELETE_COOKIE, eventstr, NULL); @@ -182,9 +199,8 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { if(!new_cookie) return; - GString *s = g_string_new ("PUT"); - if(has_socket_handler(uzbl_jar)) { + GString *s = g_string_new ("PUT"); g_string_append_c(s, 0); /* null-terminate the PUT */ g_string_append_len(s, scheme, strlen(scheme)+1); g_string_append_len(s, new_cookie->domain, strlen(new_cookie->domain)+1 ); @@ -197,13 +213,29 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { result = do_socket_request(uzbl_jar, s->str, s->len+1); g_free(result); + g_string_free(s, TRUE); } else { - g_string_append_printf(s, " '%s' '%s' '%s' '%s=%s'", scheme, new_cookie->domain, new_cookie->path, new_cookie->name, new_cookie->value); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - run_handler(uzbl_jar->handler, s->str); - } + const CommandInfo *c = parse_command_parts(uzbl_jar->handler, a); + if(!c) { + g_array_free(a, TRUE); + return; + } + + g_array_append_val(a, "PUT"); + g_array_append_val(a, scheme); + g_array_append_val(a, new_cookie->domain); + g_array_append_val(a, new_cookie->path); - g_string_free(s, TRUE); + gchar *kv = g_strconcat(new_cookie->name, "=", new_cookie->value, NULL); + g_array_append_val(a, kv); + + run_parsed_command(c, a, NULL); + + g_free(kv); + g_array_free(a, TRUE); + } } static void diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 8e14982..0a90bb9 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -360,12 +360,6 @@ itos(int val) { return g_strdup(tmp); } -gchar* -strfree(gchar *str) { - g_free(str); - return NULL; -} - gchar* argv_idx(const GArray *a, const guint idx) { return g_array_index(a, gchar*, idx); } @@ -1119,7 +1113,8 @@ search_clear(WebKitWebView *page, GArray *argv, GString *result) { (void) result; webkit_web_view_unmark_text_matches (page); - uzbl.state.searchtx = strfree (uzbl.state.searchtx); + g_free(uzbl.state.searchtx); + uzbl.state.searchtx = NULL; } void @@ -1145,13 +1140,18 @@ chain (WebKitWebView *page, GArray *argv, GString *result) { (void) page; guint i = 0; const gchar *cmd; + GString *r = g_string_new (""); while ((cmd = argv_idx(argv, i++))) { GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - CommandInfo *c = parse_command_parts(cmd, a); + const CommandInfo *c = parse_command_parts(cmd, a); if (c) - run_parsed_command(c, a, result); + run_parsed_command(c, a, r); g_array_free (a, TRUE); } + if(result) + g_string_assign (result, r->str); + + g_string_free(r, TRUE); } void @@ -1185,7 +1185,8 @@ run_command (const gchar *command, const gchar **args, const gboolean sync, gboolean result; if (sync) { - if (*output_stdout) *output_stdout = strfree(*output_stdout); + if (*output_stdout) + g_free(*output_stdout); result = g_spawn_sync(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, output_stdout, NULL, NULL, &err); @@ -1253,25 +1254,28 @@ split_quoted(const gchar* src, const gboolean unquote) { } void -spawn(GArray *argv, gboolean sync, gboolean exec) { +spawn(GArray *argv, GString *result, gboolean exec) { gchar *path = NULL; gchar *arg_car = argv_idx(argv, 0); const gchar **arg_cdr = &g_array_index(argv, const gchar *, 1); if (arg_car && (path = find_existing_file(arg_car))) { - if (uzbl.comm.sync_stdout) - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); - run_command(path, arg_cdr, sync, sync?&uzbl.comm.sync_stdout:NULL); - // run each line of output from the program as a command - if (sync && exec && uzbl.comm.sync_stdout) { - gchar *head = uzbl.comm.sync_stdout; - gchar *tail; - while ((tail = strchr (head, '\n'))) { - *tail = '\0'; - parse_cmd_line(head, NULL); - head = tail + 1; + gchar *r = NULL; + run_command(path, arg_cdr, result != NULL, result ? &r : NULL); + if(result) { + g_string_assign(result, r); + // run each line of output from the program as a command + if (exec && r) { + gchar *head = r; + gchar *tail; + while ((tail = strchr (head, '\n'))) { + *tail = '\0'; + parse_cmd_line(head, NULL); + head = tail + 1; + } } } + g_free(r); g_free(path); } } @@ -1279,23 +1283,28 @@ spawn(GArray *argv, gboolean sync, gboolean exec) { void spawn_async(WebKitWebView *web_view, GArray *argv, GString *result) { (void)web_view; (void)result; - spawn(argv, FALSE, FALSE); + spawn(argv, NULL, FALSE); } void spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; (void)result; - spawn(argv, TRUE, FALSE); + (void)web_view; + spawn(argv, result, FALSE); } void spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; (void)result; - spawn(argv, TRUE, TRUE); + (void)web_view; + if(!result) { + GString *force_result = g_string_new(""); + spawn(argv, force_result, TRUE); + g_string_free (force_result, TRUE); + } else + spawn(argv, result, TRUE); } void -spawn_sh(GArray *argv, gboolean sync) { +spawn_sh(GArray *argv, GString *result) { if (!uzbl.behave.shell_cmd) { g_printerr ("spawn_sh: shell_cmd is not set!\n"); return; @@ -1303,19 +1312,23 @@ spawn_sh(GArray *argv, gboolean sync) { guint i; gchar **cmd = split_quoted(uzbl.behave.shell_cmd, TRUE); + if(!cmd) + return; + gchar *cmdname = g_strdup(cmd[0]); g_array_insert_val(argv, 1, cmdname); for (i = 1; i < g_strv_length(cmd); i++) g_array_prepend_val(argv, cmd[i]); - if (cmd) { - if (uzbl.comm.sync_stdout) - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); + if (result) { + gchar *r = NULL; + run_command(cmd[0], (const gchar **) argv->data, TRUE, &r); + g_string_assign(result, r); + g_free(r); + } else + run_command(cmd[0], (const gchar **) argv->data, FALSE, NULL); - run_command(cmd[0], (const gchar **) argv->data, - sync, sync?&uzbl.comm.sync_stdout:NULL); - } g_free (cmdname); g_strfreev (cmd); } @@ -1323,17 +1336,17 @@ spawn_sh(GArray *argv, gboolean sync) { void spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result) { (void)web_view; (void)result; - spawn_sh(argv, FALSE); + spawn_sh(argv, NULL); } void spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) { (void)web_view; (void)result; - spawn_sh(argv, TRUE); + spawn_sh(argv, result); } void -run_parsed_command(CommandInfo *c, GArray *a, GString *result) { +run_parsed_command(const CommandInfo *c, GArray *a, GString *result) { c->function(uzbl.gui.web_view, a, result); /* send the COMMAND_EXECUTED event, except for set and event/request commands */ @@ -1350,8 +1363,8 @@ run_parsed_command(CommandInfo *c, GArray *a, GString *result) { } if(result) { - g_free(uzbl.state.last_result); - uzbl.state.last_result = g_strdup(result->str); + g_free(uzbl.state.last_result); + uzbl.state.last_result = g_strdup(result->str); } } @@ -1371,7 +1384,7 @@ parse_command_arguments(const gchar *p, GArray *a, gboolean no_split) { } } -CommandInfo * +const CommandInfo * parse_command_parts(const gchar *line, GArray *a) { CommandInfo *c = NULL; @@ -1406,13 +1419,18 @@ parse_command_parts(const gchar *line, GArray *a) { void parse_command(const char *cmd, const char *params, GString *result) { CommandInfo *c = g_hash_table_lookup(uzbl.behave.commands, cmd); + if(c) { + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - - parse_command_arguments(params, a, c->no_split); - run_parsed_command(c, a, result); + parse_command_arguments(params, a, c->no_split); + run_parsed_command(c, a, result); - g_array_free (a, TRUE); + g_array_free (a, TRUE); + } else { + gchar *tmp = g_strconcat(cmd, " ", params, NULL); + send_event(COMMAND_ERROR, tmp, NULL); + g_free(tmp); + } } @@ -1514,7 +1532,7 @@ parse_cmd_line(const char *ctl_line, GString *result) { if( strcmp(work_string, "") ) { if((work_string[0] != '#')) { /* ignore comments */ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - CommandInfo *c = parse_command_parts(work_string, a); + const CommandInfo *c = parse_command_parts(work_string, a); run_parsed_command(c, a, result); g_array_free (a, TRUE); } @@ -1985,126 +2003,6 @@ create_plug () { return plug; } - -gchar** -inject_handler_args(const gchar *actname, const gchar *origargs, const gchar *newargs) { - /* - If actname is one that calls an external command, this function will inject - newargs in front of the user-provided args in that command line. They will - come become after the body of the script (in sh) or after the name of - the command to execute (in spawn). - i.e. sh becomes sh and - spawn becomes spawn . - - The return value consist of two strings: the action (sh, ...) and its args. - - If act is not one that calls an external command, then the given action merely - gets duplicated. - */ - GArray *rets = g_array_new(TRUE, FALSE, sizeof(gchar*)); - /* Arrr! Here be memory leaks */ - gchar *actdup = g_strdup(actname); - g_array_append_val(rets, actdup); - - if ((g_strcmp0(actname, "spawn") == 0) || - (g_strcmp0(actname, "sh") == 0) || - (g_strcmp0(actname, "sync_spawn") == 0) || - (g_strcmp0(actname, "sync_sh") == 0)) { - guint i; - GString *a = g_string_new(""); - gchar **spawnparts = split_quoted(origargs, FALSE); - g_string_append_printf(a, "%s", spawnparts[0]); /* sh body or script name */ - if (newargs) g_string_append_printf(a, " %s", newargs); /* handler args */ - - for (i = 1; i < g_strv_length(spawnparts); i++) /* user args */ - if (spawnparts[i]) g_string_append_printf(a, " %s", spawnparts[i]); - - g_array_append_val(rets, a->str); - g_string_free(a, FALSE); - g_strfreev(spawnparts); - } else { - gchar *origdup = g_strdup(origargs); - g_array_append_val(rets, origdup); - } - return (gchar**)g_array_free(rets, FALSE); -} - -void -run_handler (const gchar *act, const gchar *args) { - /* Consider this code a temporary hack to make the handlers usable. - In practice, all this splicing, injection, and reconstruction is - inefficient, annoying and hard to manage. Potential pitfalls arise - when the handler specific args 1) are not quoted (the handler - callbacks should take care of this) 2) are quoted but interfere - with the users' own quotation. A more ideal solution is - to refactor parse_command so that it doesn't just take a string - and execute it; rather than that, we should have a function which - returns the argument vector parsed from the string. This vector - could be modified (e.g. insert additional args into it) before - passing it to the next function that actually executes it. Though - it still isn't perfect for chain actions.. will reconsider & re- - factor when I have the time. -duc */ - - if (!act) return; - char **parts = g_strsplit(act, " ", 2); - if (!parts || !parts[0]) return; - if (g_strcmp0(parts[0], "chain") == 0) { - GString *newargs = g_string_new(""); - gchar **chainparts = split_quoted(parts[1], FALSE); - - /* for every argument in the chain, inject the handler args - and make sure the new parts are wrapped in quotes */ - gchar **cp = chainparts; - gchar quot = '\''; - gchar *quotless = NULL; - gchar **spliced_quotless = NULL; // sigh -_-; - gchar **inpart = NULL; - - while (*cp) { - if ((**cp == '\'') || (**cp == '\"')) { /* strip old quotes */ - quot = **cp; - quotless = g_strndup(&(*cp)[1], strlen(*cp) - 2); - } else quotless = g_strdup(*cp); - - spliced_quotless = g_strsplit(quotless, " ", 2); - inpart = inject_handler_args(spliced_quotless[0], spliced_quotless[1], args); - g_strfreev(spliced_quotless); - - g_string_append_printf(newargs, " %c%s %s%c", quot, inpart[0], inpart[1], quot); - g_free(quotless); - g_strfreev(inpart); - cp++; - } - - parse_command(parts[0], &(newargs->str[1]), NULL); - g_string_free(newargs, TRUE); - g_strfreev(chainparts); - - } else { - gchar **inparts; - gchar *inparts_[2]; - if (parts[1]) { - /* expand the user-specified arguments */ - gchar* expanded = expand(parts[1], 0); - inparts = inject_handler_args(parts[0], expanded, args); - g_free(expanded); - } else { - inparts_[0] = parts[0]; - inparts_[1] = g_strdup(args); - inparts = inparts_; - } - - parse_command(inparts[0], inparts[1], NULL); - - if (inparts != inparts_) { - g_free(inparts[0]); - g_free(inparts[1]); - } else - g_free(inparts[1]); - } - g_strfreev(parts); -} - void settings_init () { State *s = &uzbl.state; @@ -2145,32 +2043,34 @@ void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *au (void) user_data; if(uzbl.behave.authentication_handler && *uzbl.behave.authentication_handler != 0) { - gchar *info, *host, *realm; - gchar *p; - soup_session_pause_message(session, msg); - /* Sanitize strings */ - info = g_strdup(soup_auth_get_info(auth)); - host = g_strdup(soup_auth_get_host(auth)); - realm = g_strdup(soup_auth_get_realm(auth)); - for (p = info; *p; p++) if (*p == '\'') *p = '\"'; - for (p = host; *p; p++) if (*p == '\'') *p = '\"'; - for (p = realm; *p; p++) if (*p == '\'') *p = '\"'; + GString *result = g_string_new (""); - GString *s = g_string_new (""); - g_string_printf(s, "'%s' '%s' '%s' '%s'", - info, host, realm, retrying?"TRUE":"FALSE"); + gchar *info = g_strdup(soup_auth_get_info(auth)); + gchar *host = g_strdup(soup_auth_get_host(auth)); + gchar *realm = g_strdup(soup_auth_get_realm(auth)); - run_handler(uzbl.behave.authentication_handler, s->str); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + const CommandInfo *c = parse_command_parts(uzbl.behave.authentication_handler, a); + if(c) { + sharg_append(a, info); + sharg_append(a, host); + sharg_append(a, realm); + sharg_append(a, retrying ? "TRUE" : "FALSE"); - if (uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) { + run_parsed_command(c, a, result); + } + g_array_free(a, TRUE); + + if (result->len > 0) { char *username, *password; int number_of_endls=0; - username = uzbl.comm.sync_stdout; + username = result->str; - for (p = uzbl.comm.sync_stdout; *p; p++) { + gchar *p; + for (p = result->str; *p; p++) { if (*p == '\n') { *p = '\0'; if (++number_of_endls == 1) @@ -2184,12 +2084,9 @@ void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *au soup_auth_authenticate(auth, username, password); } - if (uzbl.comm.sync_stdout) - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); - soup_session_unpause_message(session, msg); - g_string_free(s, TRUE); + g_string_free(result, TRUE); g_free(info); g_free(host); g_free(realm); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 049053a..14b0571 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -83,7 +83,6 @@ typedef struct { /* stores (key)"variable name" -> (value)"pointer to var*/ GHashTable *proto_var; - gchar *sync_stdout; GPtrArray *connect_chan; GPtrArray *client_chan; } Communication; @@ -237,9 +236,6 @@ typedef struct { char * itos(int val); -gchar* -strfree(gchar *str); - void clean_up(void); @@ -343,9 +339,6 @@ create_window (); GtkPlug* create_plug (); -void -run_handler (const gchar *act, const gchar *args); - void settings_init (); @@ -485,15 +478,14 @@ typedef struct { gboolean no_split; } CommandInfo; -CommandInfo * +const CommandInfo * parse_command_parts(const gchar *line, GArray *a); void parse_command_arguments(const gchar *p, GArray *a, gboolean no_split); void -run_parsed_command(CommandInfo *c, GArray *a, GString *result); - +run_parsed_command(const CommandInfo *c, GArray *a, GString *result); typedef struct { gchar *name; diff --git a/tests/test-command.c b/tests/test-command.c index 20c6aa0..d07bf79 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -263,11 +263,12 @@ test_toggle_status (void) { void test_sync_sh (void) { - parse_cmd_line("sync_sh 'echo Test echo.'", NULL); - g_assert_cmpstr("Test echo.\n", ==, uzbl.comm.sync_stdout); + GString *result = g_string_new(""); + + parse_cmd_line("sync_sh 'echo Test echo.'", result); + g_assert_cmpstr("Test echo.\n", ==, result->str); - /* clean up after ourselves */ - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); + g_string_free(result, TRUE); } void @@ -296,29 +297,6 @@ test_last_result (void) { g_string_free(result, TRUE); } -void -test_run_handler_arg_order (void) { - run_handler("sync_spawn echo uvw xyz", "abc def"); - - assert(uzbl.comm.sync_stdout); - - /* the rest of the result should be the arguments passed to run_handler. */ - /* the arguments in the second argument to run_handler should be placed before any - * included in the first argument to run handler. */ - g_assert_cmpstr("abc def uvw xyz\n", ==, uzbl.comm.sync_stdout); -} - -void -test_run_handler_expand (void) { - uzbl.net.useragent = "Test uzbl uzr agent"; - run_handler("sync_spawn echo @useragent", "result:"); - - assert(uzbl.comm.sync_stdout); - - /* the user-specified arguments to the handler should have been expanded */ - g_assert_cmpstr("result: Test uzbl uzr agent\n", ==, uzbl.comm.sync_stdout); -} - int main (int argc, char *argv[]) { /* set up tests */ @@ -337,11 +315,6 @@ main (int argc, char *argv[]) { g_test_add_func("/test-command/last-result", test_last_result); - /* the following aren't really "command" tests, but they're not worth - * splitting into a separate file yet */ - g_test_add_func("/test-command/run_handler/arg-order", test_run_handler_arg_order); - g_test_add_func("/test-command/run_handler/expand", test_run_handler_expand); - /* set up uzbl */ initialize(argc, argv); -- cgit v1.2.3 From 6a737a7137c8cfbbe21bb5f0c0182ca2255a5b4c Mon Sep 17 00:00:00 2001 From: keis Date: Mon, 17 Jan 2011 21:37:08 +0100 Subject: multiple components/re -pairs in cookie filters --- README | 4 ++-- docs/README.uzbl-event-manager | 20 ++++++++++---------- examples/config/config | 6 +++++- examples/data/plugins/cookies.py | 28 ++++++++++++++++++---------- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/README b/README index a8c500c..d20cbd2 100644 --- a/README +++ b/README @@ -770,12 +770,12 @@ Events/requests which the EM and its plugins listens for move the cursor back by one character. * `START_COMPLETION`: TODO explain completion * `BLACKLIST_COOKIE`: add a rule for blacklisting cookies - - `request BLACKLIST_COOKIE `: Blacklist cookies where + - `request BLACKLIST_COOKIE [ ]*`: Blacklist cookies where `` matches ``. `` is one of `domain`, `path`, `name`, `value`, `scheme` or `expires`. * `WHITELIST_COOKIE`: add a rule for whitelisting cookies (if any whitelist is set then only cookies that are whitelisted cookies will be used) - - `request WHITELIST_COOKIE `: Whitelist cookies where + - `request WHITELIST_COOKIE [ ]*`: Whitelist cookies where `` matches ``. `` is one of `domain`, `path`, `name`, `value`, `scheme` or `expires`. diff --git a/docs/README.uzbl-event-manager b/docs/README.uzbl-event-manager index 074811e..b9467d7 100644 --- a/docs/README.uzbl-event-manager +++ b/docs/README.uzbl-event-manager @@ -83,17 +83,17 @@ events. If any whitelist is set, then any cookie that is not whitelisted will be rejected. Otherwise, only cookies that have been blacklisted will be rejected. -BLACKLIST_COOKIE - Adds a new blacklist filter. cookies where the component specified by - `part` matches the regular expression `re` will be filtered. part can be - either 0-5 or any of the symbolic names domain, path, name, value, scheme, - expires +BLACKLIST_COOKIE [ ]* + Adds a new blacklist filter. cookies where the components specified by + `component` matches the regular expression `re` will be filtered. component + may be either 0-5 or any of the symbolic names domain, path, name, value, + scheme, expires - for example to block all cookies which name is "__utm" followed by a single + for example to block all cookies which name is "__utm" followed by a single character (google analytics cookies) do. request BLACKLIST_COOKIE name '^__utm.$' -WHITELIST_COOKIE - Adds a new whitelist filter. cookies where the component specified by - `part` matches the regular expression `re` will be allowed. part can be any - of the parts allowed for the BLACKLIST_COOKIE event +WHITELIST_COOKIE [ ]* + Adds a new whitelist filter. cookies where the components specified by + `component` matches the regular expression `re` will be allowed. component + may be any of the components allowed for the BLACKLIST_COOKIE event diff --git a/examples/config/config b/examples/config/config index a2ecdb8..bdf1c00 100644 --- a/examples/config/config +++ b/examples/config/config @@ -129,7 +129,11 @@ set progress.pending = set useragent = Uzbl (Webkit @{WEBKIT_MAJOR}.@{WEBKIT_MINOR}) (@(+uname -sm)@ [@ARCH_UZBL]) # === Configure cookie blacklist ======================================================== -# Drop google analytics tracking cookies + +# Accept 'session cookies' from uzbl.org (when you have a whitelist all other cookies are dropped) +#request WHITELIST_COOKIE domain 'uzbl.org$' expires '^$' + +# Drop google analytics tracking cookies (applied after whitelists if any) #request BLACKLIST_COOKIE name '^__utm.$' # === Key binding configuration ============================================== diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py index 9eccace..6ee8798 100644 --- a/examples/data/plugins/cookies.py +++ b/examples/data/plugins/cookies.py @@ -106,8 +106,11 @@ DefaultStore = TextStore(os.path.join(xdg_data_home, 'uzbl/cookies.txt')) SessionStore = TextStore(os.path.join(xdg_data_home, 'uzbl/session-cookies.txt')) def match_list(_list, cookie): - for component, match in _list: - if match(cookie[component]) is not None: + for matcher in _list: + for component, match in matcher: + if match(cookie[component]) is None: + break + else: return True return False @@ -158,18 +161,21 @@ def delete_cookie(uzbl, cookie): store.delete_cookie(cookie, splitted) # add a cookie matcher to a whitelist or a blacklist. -# a matcher is a (component, re) tuple that matches a cookie when the +# a matcher is a list of (component, re) tuples that matches a cookie when the # "component" part of the cookie matches the regular expression "re". # "component" is one of the keys defined in the variable "symbolic" above, # or the index of a component of a cookie tuple. def add_cookie_matcher(_list, arg): - component, regexp = splitquoted(arg) - try: - component = symbolic[component] - except KeyError: - component = int(component) - assert component <= 5 - _list.append((component, re.compile(regexp).search)) + args = splitquoted(arg) + mlist = [] + for (component, regexp) in zip(args[0::2], args[1::2]): + try: + component = symbolic[component] + except KeyError: + component = int(component) + assert component <= 5 + mlist.append((component, re.compile(regexp).search)) + _list.append(mlist) def blacklist(uzbl, arg): add_cookie_matcher(uzbl.cookie_blacklist, arg) @@ -188,3 +194,5 @@ def init(uzbl): 'cookie_blacklist' : [], 'cookie_whitelist' : [] }) + +# vi: set et ts=4: -- cgit v1.2.3 From f93cce44561b2475965c91419e72895bc368918e Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 23 Jan 2011 16:59:49 +0100 Subject: disable keycmd reset on mode change * makes history search work * adds new KEYCMD_CLEAR event * configure to clear keycmd on ESCAPE event --- examples/config/config | 1 + examples/data/plugins/bind.py | 3 ++- examples/data/plugins/history.py | 3 +++ examples/data/plugins/keycmd.py | 5 ++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/config/config b/examples/config/config index 4934469..2fea0d7 100644 --- a/examples/config/config +++ b/examples/config/config @@ -172,6 +172,7 @@ set ebind = @mode_bind global,-insert # Resets keycmd and returns to default mode. @on_event ESCAPE @set_mode +@on_event ESCAPE event KEYCMD_CLEAR @bind = event ESCAPE @bind [ = event ESCAPE diff --git a/examples/data/plugins/bind.py b/examples/data/plugins/bind.py index bf693b3..261dc5d 100644 --- a/examples/data/plugins/bind.py +++ b/examples/data/plugins/bind.py @@ -379,7 +379,6 @@ def mode_changed(uzbl, mode): if mode != 'stack': uzbl.bindlet.reset() - uzbl.clear_keycmd() def match_and_exec(uzbl, bind, depth, keylet, bindlet): @@ -470,3 +469,5 @@ def init(uzbl): 'mode_bind': mode_bind, 'bindlet': Bindlet(uzbl), }) + +# vi: set et ts=4: diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py index 78a94ce..2ab2ce3 100644 --- a/examples/data/plugins/history.py +++ b/examples/data/plugins/history.py @@ -107,6 +107,7 @@ def history_next(uzbl, _x): def history_search(uzbl, key): uzbl.history.search(key) + uzbl.send('event HISTORY_PREV') uzbl.logger.debug('SEARCH %s %s' % (key, uzbl.history)) end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') @@ -127,3 +128,5 @@ def init(uzbl): # plugin after hook def after(uzbl): uzbl.on_set('keycmd_prompt', lambda uzbl, k, v: uzbl.history.change_prompt(v)) + +# vi: set et ts=4: diff --git a/examples/data/plugins/keycmd.py b/examples/data/plugins/keycmd.py index 2fb2283..928c597 100644 --- a/examples/data/plugins/keycmd.py +++ b/examples/data/plugins/keycmd.py @@ -210,7 +210,7 @@ def modkey_addition_parse(uzbl, modkeys): add_modkey_addition(uzbl, keys[:-1], keys[-1]) -def clear_keycmd(uzbl): +def clear_keycmd(uzbl, *args): '''Clear the keycmd for this uzbl instance.''' k = uzbl.keylet @@ -493,6 +493,7 @@ def init(uzbl): 'KEYCMD_DELETE': keycmd_delete, 'KEYCMD_EXEC_CURRENT': keycmd_exec_current, 'KEYCMD_STRIP_WORD': keycmd_strip_word, + 'KEYCMD_CLEAR': clear_keycmd, 'KEY_PRESS': key_press, 'KEY_RELEASE': key_release, 'MODKEY_ADDITION': modkey_addition_parse, @@ -514,3 +515,5 @@ def init(uzbl): 'set_cursor_pos': set_cursor_pos, 'set_keycmd': set_keycmd, }) + +# vi: set et ts=4: -- cgit v1.2.3 From fc33a2fc3c27da78edb3db5c437e72537f718315 Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 23 Jan 2011 18:42:40 +0100 Subject: with gtk3: fix setting of background color --- src/callbacks.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index fa2ed1f..8cfb073 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -47,15 +47,20 @@ set_authentication_handler() { void set_status_background() { - GdkColor color; - gdk_color_parse (uzbl.behave.status_background, &color); /* labels and hboxes do not draw their own background. applying this * on the vbox/main_window is ok as the statusbar is the only affected * widget. (if not, we could also use GtkEventBox) */ - if (uzbl.gui.main_window) - gtk_widget_modify_bg (uzbl.gui.main_window, GTK_STATE_NORMAL, &color); - else if (uzbl.gui.plug) - gtk_widget_modify_bg (GTK_WIDGET(uzbl.gui.plug), GTK_STATE_NORMAL, &color); + GtkWidget* widget = uzbl.gui.main_window ? uzbl.gui.main_window : GTK_WIDGET (uzbl.gui.plug); + +#if GTK_CHECK_VERSION(2,91,0) + GdkRGBA color; + gdk_rgba_parse (&color, uzbl.behave.status_background); + gtk_widget_override_background_color (widget, GTK_STATE_NORMAL, &color); +#else + GdkColor color; + gdk_color_parse (uzbl.behave.status_background, &color); + gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &color); +#endif } void -- cgit v1.2.3 From 42ead959c23fdaacb530744139be2bb94600be3d Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 23 Jan 2011 21:14:42 +0100 Subject: clear keycmd after following link in follow.sh --- examples/data/scripts/follow.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/data/scripts/follow.sh b/examples/data/scripts/follow.sh index d1560bf..d7fe117 100755 --- a/examples/data/scripts/follow.sh +++ b/examples/data/scripts/follow.sh @@ -17,5 +17,5 @@ case $result in echo 'event FORM_ACTIVE' > "$UZBL_FIFO" ;; *XXXRESET_MODEXXX*) # a link was selected, reset uzbl's input mode - echo 'set mode=' > "$UZBL_FIFO" ;; + printf 'set mode=\nevent KEYCMD_CLEAR\n' > "$UZBL_FIFO" ;; esac -- cgit v1.2.3 From a159bc7c3f437857f3684959caeeee9e33972598 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Fri, 7 Jan 2011 12:20:52 -0700 Subject: tidying after the history branch merge --- examples/config/config | 3 +-- examples/data/plugins/bind.py | 2 -- examples/data/plugins/history.py | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/examples/config/config b/examples/config/config index 2fea0d7..c708576 100644 --- a/examples/config/config +++ b/examples/config/config @@ -200,8 +200,7 @@ set ebind = @mode_bind global,-insert #@ebind du = event APPEND_KEYCMD \@uri #@ebind dt = event APPEND_KEYCMD \@title - -# === Mouse bindings ========================================================= +# --- Mouse bindings --------------------------------------------------------- # Middle click open in new window @bind = sh 'if [ "$1" ]; then echo "event REQ_NEW_WINDOW $1" > "$UZBL_FIFO"; else echo "uri $(xclip -o | sed s/\\\@/%40/g)" > "$UZBL_FIFO"; fi' '\@SELECTED_URI' diff --git a/examples/data/plugins/bind.py b/examples/data/plugins/bind.py index 261dc5d..41f96c5 100644 --- a/examples/data/plugins/bind.py +++ b/examples/data/plugins/bind.py @@ -420,8 +420,6 @@ def match_and_exec(uzbl, bind, depth, keylet, bindlet): if not has_args or on_exec: del uzbl.config['mode'] bindlet.reset() - # cleared by keycmd_exec_current, why is this here? breaks history - #uzbl.clear_current() return True diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py index 2ab2ce3..5e9e4e1 100644 --- a/examples/data/plugins/history.py +++ b/examples/data/plugins/history.py @@ -42,7 +42,6 @@ class History(object): self.search_key = None if self._temporary: - print 'popping temporary' return self._temporary.pop() return '' @@ -73,8 +72,6 @@ class History(object): self._temporary.append(cmd) self.cursor = len(self) - 1 - print 'adding temporary', self - def __getitem__(self, i): if i < len(shared_history[self.prompt]): return shared_history[self.prompt][i] -- cgit v1.2.3 From 8ae529244eeefa13b43a08593eedf80cf6d3a2b3 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 10 Jan 2011 10:28:49 -0700 Subject: document history plugin and add example HISTORY_SEARCH binding --- docs/README.uzbl-event-manager | 19 +++++++++++++++++++ examples/config/config | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/README.uzbl-event-manager b/docs/README.uzbl-event-manager index 074811e..92f0228 100644 --- a/docs/README.uzbl-event-manager +++ b/docs/README.uzbl-event-manager @@ -97,3 +97,22 @@ WHITELIST_COOKIE Adds a new whitelist filter. cookies where the component specified by `part` matches the regular expression `re` will be allowed. part can be any of the parts allowed for the BLACKLIST_COOKIE event + +### history.py ### +- Status bar command history +- Connects To: (KEYCMD_EXEC, HISTORY_PREV, HISTORY_NEXT, HISTORY_SEARCH) + +Records commands that are typed into the status bar so that they can be +recalled. The same history is shared by all uzbl instances connected to the +same event manager. + +HISTORY_PREV + Iterates backwards through commands that have been issued (filtered by the + last HISTORY_SEARCH if applicable). + +HISTORY_NEXT + Iterates forwards through commands that have been issued (filtered by the + last HISTORY_SEARCH if applicable). + +HISTORY_SEARCH + Searches backwards through command history for an exact string. diff --git a/examples/config/config b/examples/config/config index c708576..864d37e 100644 --- a/examples/config/config +++ b/examples/config/config @@ -193,7 +193,7 @@ set ebind = @mode_bind global,-insert @ebind = event HISTORY_PREV @ebind = event HISTORY_NEXT -@ebind r_ = event HISTORY_SEARCH %s +@ebind r_ = event HISTORY_SEARCH %s # Keycmd injection/append examples. #@ebind su = event INJECT_KEYCMD \@uri #@ebind st = event INJECT_KEYCMD \@title -- cgit v1.2.3 From d9a413d5a1a80b86c94bb38b278e60ac1d0656c8 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 14 Feb 2011 21:39:16 -0700 Subject: gtk3 needs us to include gtk/gtkx.h --- src/uzbl-core.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/uzbl-core.h b/src/uzbl-core.h index f81722d..7a2adca 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -40,6 +40,10 @@ #include #include +#if GTK_CHECK_VERSION(2,91,0) + #include +#endif + #include "cookie-jar.h" #define LENGTH(x) (sizeof x / sizeof x[0]) -- cgit v1.2.3