]> mj.ucw.cz Git - umpf.git/blobdiff - lock.c
fix many little bugs, release 0.1
[umpf.git] / lock.c
diff --git a/lock.c b/lock.c
index b7e3ef49d7d2fb40be24f4214fd0dda1c370ae0d..12f40830b4e4f4bee8b4846556b986e8cb6d221c 100644 (file)
--- a/lock.c
+++ b/lock.c
@@ -1,16 +1,37 @@
+#define _GNU_SOURCE
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-#define _GNU_SOURCE
 #include <unistd.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <sys/stat.h>
+#include <time.h>
+
+#include "umpf.h"
+
+#define LOCK_MAX_TRIES 3
+gid_t rgid, egid, sgid;
+
+void
+save_gids(void)
+{
+       getresgid(&rgid, &egid, &sgid); 
+}
 
-#include "brum.h"
+static void
+drop_gid(void)
+{
+       setresgid(rgid, rgid, egid);
+}
 
-#define LOCK_MAX_TRIES 30
+static void
+raise_gid(void)
+{
+       setresgid(rgid, sgid, sgid);
+}
 
 static void
 random_sleep(unsigned int about, unsigned int offset)
@@ -25,17 +46,16 @@ random_sleep(unsigned int about, unsigned int offset)
        usleep(about * 1000000 + myrand * 500000);
 }
 
-static char*
+char*
 cat(char* l, char* r)
 {
        char* res = xmalloc(strlen(l) + strlen (r) + 1);
        strcpy(res, l);
        strcat(res, r);
-
+       
        return res;     
 }
 
-/* FIXME: what about privileges? */
 static int
 dot_lock(char* path)
 {
@@ -43,21 +63,27 @@ dot_lock(char* path)
        int fd;
        int res = -1;
        char* lockfile = cat(path, ".lock");
-       
+
+       raise_gid();
        for (i = 0; i < LOCK_MAX_TRIES; i++){
+               struct stat buf;
+
                if ((fd = open(lockfile, O_WRONLY | O_EXCL | O_CREAT, 0)) 
                        >= 0) {
                        close(fd);
+                       res = 0;
                        break;
                }
 
                if (errno != EEXIST)
                        break;
-
-               /* FIXME: deal with old locks */
-
+               /* deal with old locks */
+               stat(lockfile, &buf);
+               if ((time(NULL) - buf.st_mtime) > 3600)
+                       unlink(lockfile);               
                random_sleep(1, 1);
        }
+       drop_gid();
 
        free(lockfile);
        return res;
@@ -68,13 +94,14 @@ dot_unlock(char* path)
 {
        char* lockfile = cat(path, ".lock");
 
+       raise_gid();
        unlink(lockfile);
-
+       drop_gid();
        free(lockfile);
 }
 
-int
-open_mailbox(char* path, int use_default_mailbox)
+static int
+do_open_mailbox(char* path, int is_default_mailbox)
 {
        int fd;
 
@@ -85,30 +112,17 @@ open_mailbox(char* path, int use_default_mailbox)
        /* if OK, try to open the file:
                either we are saving to default mailbox (no problem here)
                or we are saving somewhere else (no need to be privileged)
-       */      
-       if (use_default_mailbox){
-               /* get our preciousss out of pocket */
-               gid_t ruid, euid, suid;
-               getresgid(&ruid, &euid, &suid);
-               setresgid(ruid, suid, suid);
-
-               /* we are not going to create default mailbox */
-               fd = open(path, O_RDWR);
-               if (fd < 0)
-                       return -1;      
-
-               /* hide it again */
-               setresgid(ruid, ruid, suid);
-       } else {
-               fd = open(path, O_RDWR);
-               if (fd < 0 && errno == ENOENT){
-                       fd = open(path, O_RDWR | O_CREAT | O_EXCL,
-                               S_IRUSR | S_IWUSR);
-                       if (fd < 0)
-                               return -1;      
-
-               } else if (fd < 0)
-                       return -1;      
+       */
+       int perms = S_IRUSR | S_IWUSR;
+       if (is_default_mailbox)
+               perms |=  (S_IRGRP | S_IWGRP);
+
+       mode_t oldmask = umask(0);
+       fd = open(path, O_RDWR | O_CREAT, perms);
+       umask(oldmask);
+       if (fd < 0){
+               dot_unlock(path);
+               return -1;
        }       
 
        /* fcntl then */
@@ -126,8 +140,8 @@ open_mailbox(char* path, int use_default_mailbox)
        return fd; 
 }
 
-void
-close_mailbox(int fd, char* path)
+static void
+do_close_mailbox(int fd, char* path)
 {
        struct flock mb_lock;
        memset(&mb_lock, 0, sizeof(struct flock));
@@ -137,23 +151,26 @@ close_mailbox(int fd, char* path)
        dot_unlock(path);
 }
 
+void
+close_mailbox(int fd, char* path, int is_default_mailbox)
+{
+       if (is_default_mailbox)
+               raise_gid();
+       do_close_mailbox(fd, path);
+       if (is_default_mailbox)
+               drop_gid();
+}
+
 int
-main(int argc, char** argv)
+open_mailbox(char* path, int is_default_mailbox)
 {
-       /* FIXME: move somewhere */
        int fd;
-       gid_t ruid, euid, suid;
-       if (argc < 2)
-               return 1;
-       char* mb = argv[1]; 
-       getresgid(&ruid, &euid, &suid);
-       setresgid(ruid, ruid, euid);
-       fd = open_mailbox(mb, 1);
-       printf("%d\n", fd); 
-       if (fd < 0)
-               return 1;       
-
-       close_mailbox(fd, mb);
-
-       return 0;
+
+       if (is_default_mailbox)
+               raise_gid();
+       fd = do_open_mailbox(path, is_default_mailbox);
+       if (is_default_mailbox)
+               drop_gid();
+
+       return fd;
 }