]> git.pld-linux.org Git - projects/setup.git/commitdiff
- added locking databases (compatibile with shadow)
authorMichal Moskal <michal@moskal.me>
Mon, 13 Aug 2001 12:31:11 +0000 (12:31 +0000)
committerMichal Moskal <michal@moskal.me>
Mon, 13 Aug 2001 12:31:11 +0000 (12:31 +0000)
Changed files:
    joinpasswd.c -> 1.3

joinpasswd.c

index 80e4c98c2e13a76c7c1ae247424d0bdab9b45d39..5c1bde8b002d031ea0dcb8f245e67eb09c83265f 100644 (file)
@@ -38,8 +38,8 @@
  * Add entries from freshly created {passwd,shadow,group}.rpmnew to existing
  * {passwd,shadow,group}. It is usable as part of setup package, during upgrade
  * where new system user/group is to be added. If entry is already found in 
- * system database, it is left, otherwise it is added. UIDs/GIDs are *not* checked
- * anyhow. 
+ * system database, it is left, otherwise it is added. UIDs/GIDs are *not* 
+ * checked anyhow. 
  *
  * For typical sizes of files in setup package, it takes about 1 second per
  * 20000 users in system database on Pentium class machine. After static link
@@ -120,6 +120,94 @@ int exist(char *id, int id_len, char *ptr, int sz)
        return 0;
 }
 
+void itoa(char *buf, long i)
+{
+       char tmp[32];
+       char *p;
+
+       if (i < 0) {
+               strcpy(buf, "-");
+               buf++;
+               i = -i;
+       }
+       if (i == 0) {
+               strcpy(buf, "0"); 
+               return;
+       }
+       for (p = tmp; i; i /= 10)
+               *p++ = (i % 10) + '0';
+       while (p > tmp)
+               *buf++ = *--p;
+       *buf = 0;
+}
+
+int try_lock(const char *name)
+{
+       char file[strlen(name) + 32], lock[strlen(name) + 32];
+       char buf[32];
+       int fd;
+       long pid;
+
+       strcpy(lock, name);
+       strcpy(file, name);
+       strcat(lock, ".lock");
+       itoa(buf, (long)getpid());
+       strcat(file, ".");
+       strcat(file, buf);
+       
+       fd = open(file, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600);
+       if (fd < 0)
+               return -1;
+       write(fd, buf, strlen(buf));
+       close(fd);
+
+       if (link(file, lock) == 0) {
+               unlink(file);
+               return 0;
+       }
+
+       fd = open(lock, O_RDONLY);
+       if (fd < 0)
+               goto oops;
+       memset(buf, 0, sizeof(buf));
+       read(fd, buf, sizeof(buf));
+       pid = atol(buf);
+       if (pid == 0 || kill(pid, 0) != 0) {
+               /* stale lock */
+               unlink(file);
+               unlink(lock);
+               /* try again */
+               return try_lock(name);
+       }
+
+oops:
+       unlink(file);
+       return -1;
+}
+
+void unlock(const char *name)
+{
+       char lock[strlen(name) + 32];
+
+       strcpy(lock, name);
+       strcat(lock, ".lock");
+       unlink(lock);
+}
+
+void lock(const char *name)
+{
+       int n;
+
+       n = 5;
+       while (n--) {
+               if (try_lock(name) == 0)
+                       return;
+               eputs("waiting for lock...\n");
+               sleep(1);
+       }
+       fatal("cannot get lock");
+}
+
 int join(const char *old_name, const char *new_name, const char *backup_name)
 {
        char *old, *new, *id;
@@ -129,7 +217,8 @@ int join(const char *old_name, const char *new_name, const char *backup_name)
        new = map_file(new_name, &new_sz);
        if (new == NULL)
                return -1;
-               
+       
+       lock(old_name);
        old = map_file(old_name, &old_sz);
        if (old == NULL)
                fatal("cannot mmap old");
@@ -181,18 +270,19 @@ int join(const char *old_name, const char *new_name, const char *backup_name)
        /* user may want to exime this file... */
        unlink(new_name);
 #endif
+       unlock(old_name);
 
        return 0;
 }
 
 int main()
 {
-#if 1
-       join(FILE1, FILE1 SUFFIX);
-       join(FILE2, FILE2 SUFFIX);
-       join(FILE3, FILE3 SUFFIX);
+#if 
+       join(FILE1, FILE1 SUFFIX, FILE1 BACKUP);
+       join(FILE2, FILE2 SUFFIX, FILE2 BACKUP);
+       join(FILE3, FILE3 SUFFIX, FILE3 BACKUP);
 #else
-       join("test", "test.new");
+       join("test", "test.new", "test.old");
 #endif
        return 0;
 }
This page took 0.037159 seconds and 4 git commands to generate.