Author: baggins Date: Mon Jan 26 18:26:41 2009 GMT Module: setup Tag: HEAD ---- Log message: - shameles ripoff of joinpasswd.c
---- Files affected: setup: grouprename.c (NONE -> 1.1) (NEW) ---- Diffs: ================================================================ Index: setup/grouprename.c diff -u /dev/null setup/grouprename.c:1.1 --- /dev/null Mon Jan 26 19:26:41 2009 +++ setup/grouprename.c Mon Jan 26 19:26:35 2009 @@ -0,0 +1,342 @@ +/* + * $Id$ + * + * Copyright (c) 2001 Michal Moskal <[email protected]>. + * Copyright (c) 2009 Jan Rękorajski <[email protected]>. + * 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; +} ================================================================ _______________________________________________ pld-cvs-commit mailing list [email protected] http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit
