]> git.pld-linux.org Git - projects/setup.git/commitdiff
- shameles ripoff of joinpasswd.c
authorJan Rękorajski <baggins@pld-linux.org>
Mon, 26 Jan 2009 18:26:35 +0000 (18:26 +0000)
committerJan Rękorajski <baggins@pld-linux.org>
Mon, 26 Jan 2009 18:26:35 +0000 (18:26 +0000)
Changed files:
    grouprename.c -> 1.1

grouprename.c [new file with mode: 0644]

diff --git a/grouprename.c b/grouprename.c
new file mode 100644 (file)
index 0000000..0203be8
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * $Id$
+ * 
+ * Copyright (c) 2001 Michal Moskal <malekith@pld-linux.org>.
+ * Copyright (c) 2009 Jan Rękorajski <baggins@pld-linux.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Michal Moskal.
+ * 4. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MICHAL MOSKAL AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *
+ * 
+ * USAGE: grouprename old-name new-name
+ *
+ * Change the name of a group from old-name to new-name,
+ * It is usable as part of setup package, during upgrade in case a group name
+ * has to change. If new-name is already found in system database or old-name
+ * is not found, nothing changes,. UIDs/GIDs are *not* checked anyhow. 
+ *
+ * Written for PLD Linux (http://www.pld-linux.org/) setup package.
+ *
+ * Compilation against uClibc:
+ * UCROOT=/usr/lib/bootdisk/usr
+ * gcc -I$UCROOT/include -nostdlib -O2 grouprename.c $UCROOT/lib/crt0.o \
+ *             $UCROOT/lib/libc.a -lgcc -o grouprename
+ * strip -R .comment -R .note grouprename
+ *
+ * Shamelss ripoff of the joinpasswd.c program
+ * 
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h> // for rename(2)
+#include <string.h>
+#include <signal.h>
+
+#define FILE3 "/etc/group"
+#define FILE4 "/etc/gshadow"
+
+/* #define OLD_LOCK */
+
+#define LOCK_FILE "/etc/.pwd.lock"
+
+/* maybe "-" or sth? */
+#define BACKUP ".old"
+
+/* #define SILENT */
+
+void eputs(const char *msg)
+{
+       write(2, msg, strlen(msg));
+}
+
+void fatal(const char *msg)
+{
+       eputs(msg);
+       eputs("\n");
+       exit(1);
+}
+
+char *map_file(const char *name, int *sz, int *mfd)
+{
+       int fd;
+       void *ptr;
+       struct stat st;
+
+       fd = open(name, O_RDONLY);
+       if (fd == -1)
+               return NULL;
+       *mfd = fd;
+       fstat(fd, &st);
+       *sz = st.st_size;
+       ptr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+       if (ptr == MAP_FAILED)
+               return NULL;
+
+       return ptr;
+}
+
+int exist(char *id, int id_len, char *ptr, int sz)
+{
+       int i;
+
+       for (i = 0; i < sz; ) {
+               if (sz - i > id_len && memcmp(id, ptr, id_len) == 0)
+                       return 1;
+               while (i < sz && ptr[i] != '\n')
+                       i++;
+               i++;
+       }
+
+       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;
+}
+
+#ifndef OLD_LOCK
+int lock_fd = -1;
+void noop(int x)
+{
+       (void)x;
+}
+#endif
+
+int try_lock(const char *name)
+{
+#ifdef OLD_LOCK
+       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;
+#else
+       struct flock fl;
+       
+       if (lock_fd != -1)
+               return -1;
+       lock_fd = open(LOCK_FILE, O_RDWR|O_CREAT, 0600);
+       if (lock_fd == -1)
+               return -1;
+       signal(SIGALRM, noop);
+       alarm(15);
+       memset(&fl, 0, sizeof(fl));
+       fl.l_type = F_WRLCK;
+       fl.l_whence = SEEK_SET;
+       if (fcntl(lock_fd, F_SETLKW, &fl) != 0) {
+               alarm(0);
+               close(lock_fd);
+               lock_fd = -1;
+               return -1;
+       }
+       alarm(0);
+       
+       return 0;
+#endif
+}
+
+void unlock(const char *name)
+{
+#ifdef OLD_LOCK
+       char lock[strlen(name) + 32];
+
+       strcpy(lock, name);
+       strcat(lock, ".lock");
+       unlink(lock);
+#else
+       if (lock_fd != -1)
+               close(lock_fd);
+       lock_fd = -1;
+#endif
+}
+
+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 *oldgr, const char *newgr, const char *name, const char *backup)
+{
+       char *old, *id;
+       int i, fd, mfd;
+       int sz;
+
+//     lock(name);
+       old = map_file(name, &sz, &mfd);
+       if (old == NULL)
+               fatal("cannot mmap old");
+
+       fd = open(backup, O_WRONLY|O_CREAT|O_TRUNC, 0600);
+       if (fd < 0)
+               fatal("cannot make backup");
+       write(fd, old, sz);
+       close(fd);
+
+       munmap(old, sz);
+       close(mfd);
+
+#ifndef SILENT
+       eputs("working on `");
+       eputs(name);
+       eputs("'\n");
+#endif /* SILENT */
+
+       old = map_file(backup, &sz, &mfd);
+       if (old == NULL)
+               fatal("cannot mmap backup");
+
+       fd = open(name, O_CREAT|O_WRONLY|O_TRUNC, 0644);
+       if (fd < 0)
+               fatal("cannot open new file");
+       
+       for (i = 0; i < sz; ) {
+               id = old + i;
+               while (i < sz && old[i] != ':' && old[i] != '\n')
+                       i++;
+               if (i < sz && old[i] == ':') {
+                       int id_len, line_len;
+                       char *rem = old + i;
+
+                       id_len = i - (id - old);
+                       while (i < sz && old[i] != '\n')
+                               i++;
+                       if (i < sz)
+                               i++;
+                       line_len = i - (rem - old);
+
+                       if (id_len == strlen(oldgr) &&
+                                       memcmp(id, oldgr, id_len) == 0) {
+#ifndef SILENT
+                               eputs(oldgr);
+                               eputs(": ranaming to `");
+                               eputs(newgr);
+                               eputs("'\n");
+#endif /* SILENT */
+                               write(fd, newgr, strlen(newgr));
+                       } else
+                               write(fd, id, id_len);
+                       write(fd, rem, line_len);
+               } else if (i < sz)
+                       i++;
+       }
+       close(fd);
+
+       munmap(old, sz);
+       close(mfd);
+
+//     unlock(name);
+
+       return 0;
+}
+
+int main(int argc, const char *argv[])
+{
+       const char *oldgr, *newgr;
+
+       if (argc != 3) {
+               eputs("Usage: grouprename old-name new-name");
+               return 1;
+       }
+       oldgr = argv[1];
+       newgr = argv[2];
+
+#if 0
+       join(oldgr, newgr, FILE3, FILE3 BACKUP);
+       join(oldgr, newgr, FILE4, FILE4 BACKUP);
+#else
+       join(oldgr, newgr, "test", "test.old");
+#endif
+       return 0;
+}
This page took 0.149736 seconds and 4 git commands to generate.