aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xlclipd.lua103
1 files changed, 70 insertions, 33 deletions
diff --git a/lclipd.lua b/lclipd.lua
index 342a24d..7c72259 100755
--- a/lclipd.lua
+++ b/lclipd.lua
@@ -33,12 +33,13 @@ local sys_stat = require("posix.sys.stat")
local unistd = require("posix.unistd")
local posix_syslog = require("posix.syslog")
local sqlite3 = require("lsqlite3")
+local posix_wait = require("posix.sys.wait")
local sql_create_table = [=[
create table if not exists lclipd (
id integer primary key,
content text unique not null,
- dateAdded integer not null
+ dateAdded integer unique not null
);
]=]
@@ -56,6 +57,7 @@ begin
end;
]=]
+-- We are deleting old entries in groups of 20 instead of one by one
local sql_old_reap_trigger = [=[
create trigger if not exists hist_old_reap before insert on lclipd
begin
@@ -63,7 +65,7 @@ begin
where id = (
select id from lclipd
order by timeAdded
- asc
+ asc
limit 20
) and (
select count(id)
@@ -79,6 +81,9 @@ insert into lclipd(content,dateAdded) values('XXX', unixepoch());
local pid_file = "/tmp/lclipd.pid"
local db_file_name = "/tmp/lclipd_db_name"
+--- A sleep function
+local function sleep(n) os.execute("sleep " .. tonumber(n)) end
+
--- We are not longer running.
local function remove_pid_file() os.remove(pid_file) end
@@ -103,6 +108,11 @@ local function log_to_syslog(log_str, log_priority)
posix_syslog.closelog()
end
+local function check_uid_gid()
+ log_to_syslog(tostring(unistd.getuid()) .. ":" .. tostring(unistd.getgid()),
+ posix_syslog.LOG_INFO)
+end
+
--- Checks to make sure that the pid file for clipd does not exist.
local function check_pid_file()
local f = sys_stat.stat(pid_file)
@@ -124,30 +134,40 @@ end
--- Get the clipboard content from X or wayland.
local function get_clipboard_content()
- -- clipnotify exits when there is a new entry on the clipboard
- -- so we do want a blocking call here
- os.execute("clipnotify")
-
- -- we dont care whether all the calls to clipboard progs succeed
- -- or not. so we just mask the errors.
- local _, handle_x = pcall(io.popen, "xsel -ob")
- handle_x:flush()
- local last_clip_entry_x = handle_x:read("*a")
-
- local _, handle_w = pcall(io.popen, "wl-paste")
- handle_w:flush()
- local last_clip_entry_w = handle_w:read("*a")
-
- -- local _, handle_p = pcall(io.popen, "pyclip paste")
- -- handle_p:flush()
- -- local last_clip_entry_p = handle_p:read("*a")
-
- -- if last_clip_entry_p ~= "" then
- -- return last_clip_entry_p
- if last_clip_entry_x ~= "" then
- return last_clip_entry_x
- elseif last_clip_entry_w ~= "" then
- return last_clip_entry_w
+ -- if we use a plain os.execute for clipnotify we wont get the ctrl-c
+ -- when it is pressed. doing it manually though the parent receives
+ -- the SIGINT just fine.
+ local pid, errmsg = unistd.fork()
+ if pid == nil then
+ log_to_syslog("could not fork", posix_syslog.LOG_CRIT)
+ log_to_syslog(errmsg, posix_syslog.LOG_CRIT)
+ remove_pid_file()
+ os.exit(1)
+ elseif pid == 0 then
+ -- clipnotify exits when there is a new entry on the clipboard
+ -- so we do want a blocking call here
+ os.execute("clipnotify")
+ os.exit(0)
+ else
+ posix_wait.wait(pid)
+ -- we dont care whether all the calls to clipboard progs succeed
+ -- or not. so we just mask the errors.
+ local _, handle_x = pcall(io.popen, "xsel -ob")
+ local last_clip_entry_x = handle_x:read("*a")
+
+ local _, handle_w = pcall(io.popen, "wl-paste")
+ local last_clip_entry_w = handle_w:read("*a")
+
+ local _, handle_p = pcall(io.popen, "pyclip paste")
+ local last_clip_entry_p = handle_p:read("*a")
+
+ if last_clip_entry_p ~= "" then
+ return last_clip_entry_p
+ elseif last_clip_entry_x ~= "" and last_clip_entry_x ~= nil then
+ return last_clip_entry_x
+ elseif last_clip_entry_w ~= "" and last_clip_entry_w ~= nil then
+ return last_clip_entry_w
+ end
end
end
@@ -155,7 +175,7 @@ end
local function get_sqlite_handle()
local tmp_db_name = "/tmp/" ..
io.popen(
- "tr -dc A-Za-z0-9 </dev/urandom | head -c 13"):read(
+ "tr -dc A-Za-z0-9 </dev/urandom | head -c 17"):read(
"*a")
log_to_syslog(tmp_db_name, posix_syslog.LOG_INFO)
local clipDB = sqlite3.open(tmp_db_name,
@@ -207,8 +227,13 @@ local function loop(clip_hist_size)
lclip_exit(1)
end
+ log_to_syslog("starting the main loop", posix_syslog.LOG_INFO)
while true do
local clip_content = get_clipboard_content()
+ -- remove trailing/leading whitespace
+ if clip_content == nil then goto continue end
+ clip_content = string.gsub(clip_content, '^%s*(.-)%s*$', '%1')
+ sleep(0.2)
if clip_content ~= nil then
local insert_string = sql_insert:gsub("XXX", clip_content)
@@ -217,19 +242,31 @@ local function loop(clip_hist_size)
log_to_syslog(tostring(return_code), posix_syslog.LOG_WARNING)
end
end
+ ::continue::
end
end
--- The entry point.
local function main()
- signal.signal(signal.SIGINT, function(signum) os.exit(128 + signum) end)
+ -- local pgrpid = unistd.getpgrp()
+ signal.signal(signal.SIGINT, function(signum)
+ remove_pid_file()
+ io.write("\n")
+ os.exit(128 + signum)
+ end)
+ signal.signal(signal.SIGTERM, function(signum)
+ remove_pid_file()
+ io.write("\n")
+ os.exit(128 + signum)
+ end)
local args = parser:parse()
- check_pid_file()
- write_pid_file()
+ -- check_pid_file()
+ -- write_pid_file()
+ check_uid_gid()
local status, err = pcall(loop, args["hist_size"])
- if ~status then log_to_syslog(err, posix_syslog.LOG_CRIT) end
- remove_pid_file()
+ if status ~= true then log_to_syslog(err, posix_syslog.LOG_CRIT) end
end
-main()
+local status, _ = pcall(main)
+if status ~= true then remove_pid_file() end