qasim 0.1.11.dev.2014102811

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +31 -0
  3. data/Gemfile +7 -0
  4. data/LICENSE-GPL-3 +674 -0
  5. data/Makefile +180 -0
  6. data/README.md +81 -0
  7. data/Rakefile +1 -0
  8. data/TODO.md +28 -0
  9. data/bin/qasim-cli +89 -0
  10. data/bin/qasim-gui +300 -0
  11. data/conf/config +2 -0
  12. data/conf/default.map +32 -0
  13. data/conf/qasim.desktop +13 -0
  14. data/data/icons/qasim.128.png +0 -0
  15. data/data/icons/qasim.16.png +0 -0
  16. data/data/icons/qasim.256.png +0 -0
  17. data/data/icons/qasim.32.png +0 -0
  18. data/data/icons/qasim.64.png +0 -0
  19. data/data/icons/qasim.png +0 -0
  20. data/data/icons/qasim.svg +192 -0
  21. data/data/text/authors.html +7 -0
  22. data/data/text/gpl-3.0-standalone.html +694 -0
  23. data/data/text/thanks.html +0 -0
  24. data/debian/changelog +73 -0
  25. data/debian/compat +1 -0
  26. data/debian/control +13 -0
  27. data/debian/copyright +38 -0
  28. data/debian/dirs +3 -0
  29. data/debian/docs +0 -0
  30. data/debian/rules +80 -0
  31. data/debian/source/format +1 -0
  32. data/demo.map +29 -0
  33. data/examples/config +2 -0
  34. data/examples/default.map +32 -0
  35. data/lib/qasim.rb +11 -0
  36. data/lib/qasim/config.rb +56 -0
  37. data/lib/qasim/configold.rb +123 -0
  38. data/lib/qasim/constants.rb +11 -0
  39. data/lib/qasim/map.rb +225 -0
  40. data/lib/qasim/qasim.qrc +8 -0
  41. data/lib/qasim/ui.rb +7 -0
  42. data/lib/qasim/ui/about.rb +58 -0
  43. data/lib/qasim/ui/about.ui +192 -0
  44. data/lib/qasim/ui/listmaps.ui +59 -0
  45. data/lib/qasim/ui/preferences.rb +12 -0
  46. data/lib/qasim/ui/preferences.ui +90 -0
  47. data/lib/qasim/version.rb +5 -0
  48. data/man/qasim-cli.1 +98 -0
  49. data/man/qasim-gui.1 +98 -0
  50. data/man/sshfs-mapper.1 +98 -0
  51. data/mapparser.y +155 -0
  52. data/qasim.gemspec +34 -0
  53. data/sshfs-mapper.completion +24 -0
  54. data/sshfs-mapper.sh +253 -0
  55. metadata +147 -0
data/Makefile ADDED
@@ -0,0 +1,180 @@
1
+
2
+ NAME=qasim
3
+ DESTDIR=
4
+ DEV_DESTDIR=tmp
5
+ CONFDIR=$(DESTDIR)/etc
6
+ BINDIR=$(DESTDIR)/usr/bin
7
+ MANDIR=$(DESTDIR)/usr/share/man
8
+ DOCDIR=$(DESTDIR)/usr/share/doc
9
+ SHAREDIR=$(DESTDIR)/usr/share
10
+
11
+ RUBYVERSION=2.0
12
+ RDOC=rdoc$(RUBYVERSION)
13
+
14
+ all: \
15
+ build \
16
+ install
17
+
18
+ clean: \
19
+ clean-ui \
20
+ clean-qrc \
21
+ clean-bin \
22
+ clean-lib \
23
+ clean-data \
24
+ clean-doc
25
+
26
+ build: \
27
+ build-ui \
28
+ build-qrc \
29
+ build-bin \
30
+ build-lib \
31
+ build-data
32
+
33
+ doc: build-doc
34
+
35
+ install: \
36
+ install-ui \
37
+ install-qrc \
38
+ install-bin \
39
+ install-lib \
40
+ install-data
41
+
42
+ ## DOC SECTION
43
+
44
+ .PHONY: build-doc
45
+
46
+ clean-doc:
47
+ rm -fr doc
48
+
49
+ build-doc: clean-doc
50
+ $(RDOC) \
51
+ --promiscuous \
52
+ --inline-source \
53
+ --line-numbers \
54
+ -o doc lib/$(NAME)/ \
55
+ bin/
56
+ # --diagram
57
+
58
+ install-doc:
59
+ # # install documentation
60
+ rm -fr $(DOCDIR)/$(NAME)
61
+ mkdir -p $(DOCDIR)/$(NAME)
62
+ cp -a doc $(DOCDIR)/$(NAME)
63
+
64
+
65
+ ## QRC -> QRC_RB SECTION
66
+
67
+ QRC_FILES=$(wildcard lib/$(NAME)/*.qrc)
68
+ RBQRC_FILES=$(patsubst %.qrc,%_qrc.rb,$(QRC_FILES))
69
+
70
+ clean-qrc:
71
+ rm -f $(RBQRC_FILES)
72
+
73
+ build-qrc: $(RBQRC_FILES)
74
+ echo $(RBQRC_FILES)
75
+
76
+ install-qrc: $(RBQRC_FILES)
77
+ # FIXME install qrc
78
+
79
+ %_qrc.rb: %.qrc
80
+ rbrcc $< -o $@
81
+
82
+ ## UI -> UI_RB SECTION
83
+
84
+ UI_FILES=$(wildcard lib/$(NAME)/ui/*.ui)
85
+ RBUI_FILES=$(patsubst %.ui,%_ui.rb,$(UI_FILES))
86
+
87
+ clean-ui:
88
+ rm -f $(RBUI_FILES)
89
+
90
+ build-ui: $(RBUI_FILES)
91
+ echo $(RBUI_FILES)
92
+
93
+ install-ui: $(RBUI_FILES)
94
+ # FIXME install
95
+
96
+ %_ui.rb: %.ui
97
+ rbuic4 $< -o $@
98
+ sed -e '/^module Ui/,/^end # module Ui/d' \
99
+ -i $@
100
+
101
+
102
+ ## BINARY SECTION
103
+
104
+ clean-bin:
105
+ # remove external packages
106
+ rm -fr vendor/bundle
107
+
108
+ build-bin:
109
+
110
+ install-bin:
111
+ env |sort
112
+ mkdir -p $(BINDIR)
113
+ for binfile in bin/*.rb ; do \
114
+ BINFILE=`basename $$binfile |sed -e 's/.rb$$//'`; \
115
+ install -D -o root -g root -m 755 $$binfile $(BINDIR)/$$BINFILE; \
116
+ sed -i -e 's|^QASIM_INCLUDE_DIR.*|QASIM_INCLUDE_DIR = "$(SHAREDIR)/$(NAME)/lib"|' $(BINDIR)/$$BINFILE; \
117
+ sed -i -e 's|^QASIM_DATA_DIR.*|QASIM_DATA_DIR = "$(SHAREDIR)/$(NAME)"|' $(BINDIR)/$$BINFILE; \
118
+ done
119
+ #install -D -o root -g root -m 755 $(CURDIR)/bin/$(NAME)-gui.rb $(BINDIR)/$(NAME)-gui
120
+
121
+ ## LIB SECTION
122
+
123
+ clean-lib:
124
+
125
+ build-lib:
126
+
127
+ install-lib:
128
+ IFS="" find lib -name '*.rb' | while read libfile ; do \
129
+ install -D -o root -g root -m 644 $$libfile $(SHAREDIR)/$(NAME)/$$libfile; \
130
+ done
131
+
132
+
133
+ ## DATA SECTION
134
+
135
+ clean-data:
136
+
137
+ build-data:
138
+
139
+ install-data:
140
+ ## Install man pages
141
+ mkdir -p $(MANDIR)/man1
142
+ for binfile in bin/*.rb ; do \
143
+ BINFILE=`basename $$binfile |sed -e 's/.rb$$//'`; \
144
+ cat man/$${BINFILE}.1 | gzip > $(MANDIR)/man1/$${BINFILE}.1.gz ; \
145
+ done
146
+ #
147
+ ## Install icons
148
+ mkdir -p $(SHAREDIR)/$(NAME)/icons
149
+ install -D -o root -g root -m 644 $(CURDIR)/data/icons/$(NAME).svg \
150
+ $(SHAREDIR)/$(NAME)/icons/$(NAME).svg
151
+ #
152
+ ## Install completion file
153
+ # install -D -o root -g root -m 644 $(CURDIR)/$(NAME).completion $(DESTDIR)/etc/bash_completion.d/$(NAME)
154
+ #
155
+ ## Install configuration files
156
+ mkdir -p $(CONFDIR)/xdg/autostart
157
+ install -D -o root -g root -m 644 $(CURDIR)/conf/$(NAME).desktop \
158
+ $(CONFDIR)/xdg/autostart/$(NAME).desktop
159
+ install -D -o root -g root -m 644 $(CURDIR)/conf/$(NAME).desktop \
160
+ $(SHAREDIR)/applications/$(NAME).desktop
161
+ mkdir -p $(CONFDIR)/$(NAME)
162
+ install -D -o root -g root -m 644 $(CURDIR)/conf/config \
163
+ $(CONFDIR)/$(NAME)/config
164
+ install -D -o root -g root -m 644 $(CURDIR)/conf/default.map \
165
+ $(CONFDIR)/$(NAME)/default.map
166
+ #
167
+ # Install examples
168
+ mkdir -p $(DOCDIR)/$(NAME)/examples
169
+ for f in `ls examples`; do \
170
+ cat examples/$$f | gzip -f9 > $(DOCDIR)/$(NAME)/examples/$$f.gz ; \
171
+ done
172
+
173
+
174
+ ## OTHER
175
+
176
+ .PHONY: destdir
177
+ dev-install:
178
+ rm -fr $(DEV_DESTDIR)
179
+ fakeroot $(MAKE) install DESTDIR=$(DEV_DESTDIR)
180
+
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ README
2
+ ======
3
+
4
+ Requirements
5
+ ------------
6
+
7
+ First, make sure your ruby was compiled with the --enable-shared options.
8
+ If not, reinstall it (let's say version 1.9.3-p392) with with :
9
+
10
+ CONFIGURE_OPTS="--enable-shared" rbenv install 1.9.3-p392
11
+
12
+ Install the following gems
13
+
14
+ qtbindings
15
+
16
+ Those could also be provided by your linux distribution and installable
17
+ with
18
+
19
+ apt-get install libqt4-ruby
20
+
21
+ or
22
+
23
+ apt-get install ruby-qt4
24
+
25
+
26
+ Installation
27
+ ------------
28
+
29
+ Add this line to your application's Gemfile:
30
+
31
+ gem 'qasim'
32
+
33
+ And then execute:
34
+
35
+ $ bundle
36
+
37
+ Or install it yourself as:
38
+
39
+ $ gem install qasim
40
+
41
+
42
+ Usage
43
+ -----
44
+
45
+ TODO: Write usage instructions here
46
+
47
+
48
+ Contributing
49
+ ------------
50
+
51
+ 1. Fork it ( http://github.com/glenux/qasim/fork )
52
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
53
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
54
+ 4. Push to the branch (`git push origin my-new-feature`)
55
+ 5. Create new Pull Request
56
+
57
+
58
+ Copyright & License
59
+ -------------------
60
+
61
+ Copyright (C) 2010-2012 Glenn Y. Rolland
62
+
63
+ This program is free software: you can redistribute it and/or modify
64
+ it under the terms of the GNU General Public License as published by
65
+ the Free Software Foundation, either version 3 of the License, or
66
+ (at your option) any later version.
67
+
68
+ This program is distributed in the hope that it will be useful,
69
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
70
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
71
+ GNU General Public License for more details.
72
+
73
+ You should have received a copy of the GNU General Public License
74
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
75
+
76
+
77
+ Alternatives
78
+ ------------
79
+
80
+ * [Mountoid](http://kde-apps.org/content/show.php/Mountoid?content=115943)
81
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/TODO.md ADDED
@@ -0,0 +1,28 @@
1
+ Global Qasim parameters
2
+
3
+ * Default local cache directory
4
+ * Default mount point directory
5
+
6
+ * AutoSSH (disable if not installed)
7
+ * autossh executable path
8
+ * use autossh (default: yes)
9
+ * Unison (disable if not installed)
10
+ * unison executable path
11
+ * use unison (default: yes)
12
+ * sync interval (0=none, ...) in hours
13
+
14
+ Global SSHFS Options
15
+
16
+ * reconnect (default: yes)
17
+ * compress (default: yes)
18
+ * transform_symlinks (default: yes)
19
+ * ServerAliveInterval (default: 30)
20
+ * ServerAliveCountMax (default: 30)
21
+
22
+ ssh_command='autossh -M 0'
23
+
24
+
25
+ Fixes
26
+
27
+ Use Rakefile
28
+ ex: https://github.com/ryanmelt/qtbindings/blob/master/Rakefile
data/bin/qasim-cli ADDED
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $DEBUG = true
4
+ $VERBOSE = true
5
+
6
+ QASIM_INCLUDE_DIR = "lib"
7
+ QASIM_DATA_DIR = "."
8
+
9
+ $:.push QASIM_INCLUDE_DIR
10
+ p $:.inspect
11
+
12
+ #
13
+ # external libraries
14
+ #
15
+ require 'bundler/setup'
16
+ require 'pp'
17
+ #require 'thor'
18
+
19
+ #
20
+ # project libraries
21
+ #
22
+ require 'qasim'
23
+
24
+ module Qasim
25
+
26
+ class QasimCli
27
+ #
28
+ #
29
+ #
30
+ def initialize
31
+ @all_maps = nil
32
+ @active_maps = nil
33
+
34
+ puts "-- sshfs-mapper --"
35
+ @config = Config.new
36
+ @config.parse_cmd_line ARGV
37
+ @config.parse_file
38
+
39
+ @all_maps = {}
40
+ pp @config
41
+ end
42
+
43
+
44
+ # create default map for each selected map
45
+ # or default.map if none selected
46
+ def run_init
47
+ end
48
+
49
+ def run_mount
50
+
51
+ # asynchronous mount
52
+ selected_maps = @config.maps.select do |map|
53
+ pp map
54
+ map.online?
55
+ # if map.available? then
56
+ # map.connect!
57
+ # end
58
+ end
59
+
60
+ end
61
+
62
+ def run_umount
63
+ end
64
+
65
+ #
66
+ #
67
+ #
68
+ def run
69
+ case @config.action
70
+ when Config::ACTION_INIT
71
+ run_init
72
+ when Config::ACTION_MOUNT
73
+ run_mount
74
+ when Config::ACTION_UMOUNT
75
+ run_umount
76
+ else
77
+ raise RuntimeError, "Unknown action"
78
+ end
79
+
80
+ puts "--run"
81
+ end
82
+
83
+ end
84
+ end
85
+
86
+ app = Qasim::Qasim.new
87
+ app.run
88
+
89
+
data/bin/qasim-gui ADDED
@@ -0,0 +1,300 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'Qt4'
4
+
5
+ $DEBUG = true
6
+ $VERBOSE = true
7
+
8
+ require 'pp'
9
+ require 'set'
10
+ require 'fcntl'
11
+ require 'pathname'
12
+
13
+ QASIM_INCLUDE_DIR = Pathname.new(File.dirname(__FILE__)).parent + "lib"
14
+ QASIM_DATA_DIR = Pathname.new(File.dirname(__FILE__)).parent + "data"
15
+
16
+ $:.push QASIM_INCLUDE_DIR
17
+
18
+ require 'qasim'
19
+ require 'qasim/qasim_qrc'
20
+
21
+ # QaSiM // Qt Sshfs Mapper
22
+
23
+ def _ str
24
+ Qt::Object.tr(str)
25
+ end
26
+
27
+
28
+ module Qasim
29
+ class QasimApp
30
+ def initialize
31
+ end
32
+ end
33
+
34
+ class QasimGui < QasimApp
35
+
36
+ class LockError < RuntimeError ; end
37
+
38
+ def initialize
39
+ @config = Config.new
40
+ #@config.parse_cmd_line ARGV
41
+
42
+ @map_menu = nil
43
+ @context_menu = nil
44
+ @connect_error = {}
45
+ @connect_running = {}
46
+ end
47
+
48
+ def dbus_notify title, body, icon
49
+ bus = Qt::DBusConnection.sessionBus
50
+ if !bus.connected?
51
+ $stderr.puts("Cannot connect to the D-BUS session bus.\n" \
52
+ "To start it, run:\n" \
53
+ "\teval `dbus-launch --auto-syntax`\n")
54
+ exit 1
55
+ end
56
+ msg = Qt::DBusMessage.create_method_call( 'org.freedesktop.Notifications',
57
+ '/org/freedesktop/Notifications',
58
+ 'org.freedesktop.Notifications',
59
+ 'Notify' )
60
+ msg.arguments = [ APP_NAME, Qt::Variant.from_value( 0, "unsigned int" ),
61
+ icon, title, body, [], {}, -1 ]
62
+ rep = bus.call( msg )
63
+ # if rep.type == Qt::DBusMessage
64
+
65
+ # si.showMessage("Qasim",
66
+ # "Sorry dude", 2, 5000 )
67
+ end
68
+
69
+
70
+ #
71
+ # Rebuild map menu
72
+ #
73
+ def build_map_menu
74
+ # reload maps dynamically
75
+ @config.parse_maps
76
+ if @map_menu.nil? then
77
+ @map_menu = Qt::Menu.new
78
+ else
79
+ @map_menu.clear
80
+ end
81
+
82
+ previous_host = nil
83
+ @config.maps.sort do |mx,my|
84
+ mx.host <=> my.host
85
+ end.each do |map|
86
+ if map.host != previous_host and not previous_host.nil? then
87
+ @map_menu.addSeparator
88
+ end
89
+ itemx = Qt::Action.new(map.name, @map_menu)
90
+ itemx.setCheckable true;
91
+ if map.connected? then
92
+ itemx.setChecked true
93
+ end
94
+ itemx.connect(SIGNAL(:triggered)) do
95
+ action_trigger_map_item map, itemx
96
+ end
97
+ @map_menu.addAction itemx;
98
+ previous_host = map.host
99
+ end
100
+ end
101
+
102
+ #
103
+ # Action when map item triggered
104
+ #
105
+ def action_trigger_map_item map, item
106
+ @connect_error[map.path] = Set.new
107
+ @connect_running[map.path] = 0
108
+ method = if map.connected? then :disconnect
109
+ else :connect
110
+ end
111
+
112
+ begin
113
+ map.send(method) do |linkname,cmd,cmd_args|
114
+ process = Qt::Process.new
115
+ process.connect(SIGNAL('finished(int, QProcess::ExitStatus)')) do |exitcode,exitstatus|
116
+ #puts "exitcode = %s, exitstatus = %s" % [exitcode, exitstatus]
117
+ @connect_running[map.path] -= 1
118
+ if exitcode != 0 then
119
+ @connect_error[map.path].add linkname
120
+ else
121
+ end
122
+ if @connect_running[map.path] == 0 then
123
+ # display someting
124
+ if @connect_error[map.path].empty? then
125
+
126
+ dbus_notify "%s (%s)" % [APP_NAME, map.name],
127
+ ("<b>Map %sed successfully<b>" % method.to_s),
128
+ 'dialog-information'
129
+ else
130
+ erroneous = @connect_error[map.path].to_a.join(', ')
131
+ dbus_notify "%s (%s)" % [APP_NAME, map.name],
132
+ ("<b>Unable to %s map</b><br>" % method.to_s) +
133
+ ("Broken link(s): %s" % erroneous),
134
+ 'dialog-error'
135
+ end
136
+ end
137
+ end
138
+ @connect_running[map.path] += 1
139
+ process.start cmd, cmd_args
140
+ end
141
+
142
+ rescue Map::ConnectError => e
143
+ puts e.inspect
144
+ end
145
+ end
146
+
147
+ #
148
+ #
149
+ #
150
+ def build_context_menu
151
+ @context_menu = Qt::Menu.new
152
+
153
+ act_pref = Qt::Action.new _('&Preferences'), @context_menu
154
+ act_pref.setIcon( Qt::Icon::fromTheme("configure") ) rescue nil
155
+ act_pref.setIconVisibleInMenu true
156
+ act_pref.setEnabled false
157
+ act_pref.connect(SIGNAL(:triggered)) do
158
+ res = @pref_dialog.show
159
+ end
160
+ @context_menu.addAction act_pref;
161
+
162
+ act_about = Qt::Action.new '&About', @context_menu
163
+ act_about.setIcon( Qt::Icon::fromTheme("help-about") ) rescue nil
164
+ act_about.setIconVisibleInMenu true
165
+ #act_about.setEnabled true
166
+ act_about.connect(SIGNAL(:triggered)) do
167
+ res = @about_dialog.show
168
+ end
169
+ @context_menu.addAction act_about;
170
+
171
+ @context_menu.addSeparator
172
+
173
+ act_quit = Qt::Action.new _('Quit'), @context_menu
174
+ act_quit.setIcon( Qt::Icon::fromTheme("application-exit") ) rescue nil
175
+ act_quit.setIconVisibleInMenu true
176
+ act_quit.connect(SIGNAL(:triggered)) { @app.quit }
177
+ @context_menu.addAction act_quit
178
+ end
179
+
180
+
181
+ #
182
+ #
183
+ #
184
+ def build_interface
185
+
186
+ @app = Qt::Application.new(ARGV)
187
+ #Qt.debug_level = Qt::DebugLevel::High
188
+ #Qt.debug_level = Qt::DebugLevel::Extensive
189
+ @app.setQuitOnLastWindowClosed false
190
+
191
+ @main_win = Qt::MainWindow.new
192
+ @systray = Qt::SystemTrayIcon.new @main_win
193
+ @about_dialog = Qasim::Ui::About.new @main_win
194
+ @pref_dialog = Qasim::Ui::Preferences.new @main_win
195
+
196
+ std_icon = Qt::Icon.new( ":/qasim/qasim-icon" )
197
+ alt_icon = Qt::Icon.new
198
+ blinking = false
199
+
200
+ @systray.icon = std_icon
201
+ @systray.show
202
+
203
+
204
+ @systray.setToolTip("Qasim %s" % APP_VERSION);
205
+
206
+ build_map_menu
207
+ build_context_menu
208
+
209
+ @systray.contextMenu = @context_menu
210
+
211
+ @systray.connect(SIGNAL('activated(QSystemTrayIcon::ActivationReason)')) do |reason|
212
+ case reason
213
+ when Qt::SystemTrayIcon::Trigger then
214
+ build_map_menu
215
+ @map_menu.popup(Qt::Cursor::pos())
216
+ #blinking = !blinking
217
+ #si.icon = blinking ? alt_icon : std_icon
218
+ when Qt::SystemTrayIcon::MiddleClick then
219
+ #
220
+ when Qt::SystemTrayIcon::Context then
221
+ #
222
+ when Qt::SystemTrayIcon::DoubleClick then
223
+ #
224
+ end
225
+ end
226
+ end
227
+
228
+
229
+ def lock_set
230
+ begin
231
+ # create an exclusive lock file
232
+ have_lock = true
233
+
234
+ FileUtils.mkdir_p APP_CONFIG_DIR unless File.exist? APP_CONFIG_DIR
235
+ lockfname = File.join APP_CONFIG_DIR, "lock"
236
+ fd = IO::sysopen( lockfname,
237
+ Fcntl::O_WRONLY | Fcntl::O_EXCL | Fcntl::O_CREAT)
238
+ f = IO.open(fd)
239
+ f.syswrite( "#{Process.pid}\n" )
240
+ f.close
241
+ rescue Errno::EEXIST => e
242
+ # test if the other process still exist
243
+ masterpid = File.read(lockfname).strip
244
+ other_path = "/proc/#{masterpid.to_i}"
245
+ STDERR.puts "testing %s" % other_path
246
+ if File.exist? other_path then
247
+ cmdline = File.read( File.join( other_path, 'cmdline' ) )
248
+ if cmdline =~ /qasim/ then
249
+ raise LockError, "Another instance of %s is already running." % APP_NAME
250
+ end
251
+ end
252
+ fd = IO::sysopen( lockfname,
253
+ Fcntl::O_WRONLY | Fcntl::O_EXCL )
254
+ f = IO.open(fd)
255
+ f.syswrite( "#{Process.pid}\n" )
256
+ f.close
257
+ end
258
+ end
259
+
260
+ def lock_unset
261
+ # remove lock if it exists
262
+ lockfname = File.join APP_CONFIG_DIR, "lock"
263
+ return unless File.exist? lockfname
264
+ masterpid = File.read(lockfname).strip
265
+ if masterpid.to_i == Process.pid then
266
+ FileUtils.rm lockfname
267
+ end
268
+ end
269
+
270
+ #
271
+ #
272
+ #
273
+ def run
274
+ Process.daemon(true) #FIXME: add foreground mode too
275
+ lock_set
276
+ @app.exec
277
+ exit 0
278
+ rescue LockError
279
+ STDERR.puts "Error: %s is already running" % APP_NAME
280
+ exit 1
281
+ ensure
282
+ lock_unset
283
+ end
284
+
285
+
286
+ #
287
+ #
288
+ #
289
+ def self.main
290
+ qasim = QasimGui.new
291
+ qasim.build_interface
292
+ qasim.run
293
+ end
294
+
295
+ end
296
+
297
+ end
298
+
299
+ Qasim::QasimGui::main
300
+