diff options
author | Willy Tarreau <willy@wtap.(none)> | 2006-07-26 10:46:55 +0200 |
---|---|---|
committer | Willy Tarreau <willy@wtap.(none)> | 2006-07-26 10:46:55 +0200 |
commit | fcb250efba23ae522c4c8cb03c47dd40edcf9603 (patch) | |
tree | 3756bd1748842a3f1049d857e8412f148a8741b9 /mktmp/mktmp.c | |
parent | Initial commit (diff) | |
download | flxutils-fcb250efba23ae522c4c8cb03c47dd40edcf9603.tar.xz |
[RELEASE] flxutils-0.1.4.2v0.1.4.2
Diffstat (limited to 'mktmp/mktmp.c')
-rw-r--r-- | mktmp/mktmp.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/mktmp/mktmp.c b/mktmp/mktmp.c new file mode 100644 index 0000000..3230ff6 --- /dev/null +++ b/mktmp/mktmp.c @@ -0,0 +1,136 @@ +/* + * mklock - create a secured lock entry with given data + * (c) 2003 - willy tarreau - willy@ant-computing.com + * + * You may use, copy and redistribute with no restriction. Use at your own + * risk, I will not be held responsible for any loss or damage. + * + * usage : + * # mklock <directory> [data] + * + * This will create a symlink under <directory>, either pointing to <data> if + * <data> is specified, or pointing to /proc/<getppid()> if no data is given. + * This way, the link will automatically be broken as soon as the father dies. + * The name of the link will be generated randomly until no conflict happens + * with an existing entry. The full pathname of the resulting link is returned + * to stdout so that a script can easily use it. + * This method ensures the use of a secure lock. + * + * Example : + * # file=`mklock /tmp $$` + */ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> + +#define writetxt(fd, text) write(fd, text, strlen(text)) +#define LOCK_PREFIX ".lock." +#define PROC_PREFIX "/proc/" +#define MAX_PID_DIGITS 10 /* 10 digits do code a 32bit pid in decimal */ + +const char lock_prefix[] = LOCK_PREFIX; +const char proc_prefix[] = PROC_PREFIX; + +/* writes <l> in at most 9 decimal digits to <to> */ +void ultoa(char *to, unsigned long l) { + unsigned long div = 1000000000; + int zero = 1; + while (div > 0) { + *to = (l / div % 10) + '0'; + div /= 10; + zero &= (*to == '0'); + if (!zero) + to++; + } + *to = 0; +} + +/* writes <l> as 8 hex digits to <to> */ +void ultoh(char *to, unsigned long l) { + int shift = 32; + while ((shift -= 4) >= 0) { + int digit = (l >> shift) & 0xf; + if (digit > 9) + digit += 'A' - '9' - 1; + *to++ = digit + '0'; + } + *to = 0; +} + +void usage() { + writetxt(2, "Usage: mklock [ -d ] [ -p prefix ] <directory> [data]\n"); + exit(1); +} + +main(int argc, char **argv) { + char *text, *prefix; + char *directory; + char *fullname; + int len, num = 0, ret; + int use_dir = 0; + int plen; + + prefix = lock_prefix; + + argv++; argc--; + + while (argc > 0 && **argv == '-') { + if (!strcmp(*argv, "-d")) { + use_dir = 1; + } + else if (!strcmp(*argv, "-p")) { + if (argc > 1) { + argv++; argc--; + prefix = argv[0]; + } + else + usage(); + } + argv++; argc--; + } + + if (argc < 1) + usage(); + + plen = strlen(prefix); + directory = argv[0]; + len = strlen(directory); + while (len > 0 && directory[len - 1] == '/') + directory[--len] = 0; + + fullname = (char *)calloc(1, len + 1 + plen + 10); + memcpy(fullname, directory, len); + fullname[len++] = '/'; + memcpy(fullname + len, prefix, plen + 1); + len += plen; + + argv++; argc--; + + if (argc > 0) /* use this arg as where the link points to */ + text = argv[0]; + else { /* point to /proc/<getppid()> */ + text = (char *)malloc(strlen(PROC_PREFIX) + MAX_PID_DIGITS + 1); + memcpy(text, proc_prefix, strlen(PROC_PREFIX) + 1); + ultoa(text + strlen(PROC_PREFIX), getppid()); + } + + do { + /* try to create the entry with an increasing suffix until we succeed */ + ultoh(fullname+len, num++); + + if (use_dir) + ret = mkdir(fullname, 0700); + else + ret = symlink(text, fullname); + + if (ret == 0) { + fullname[len + 8]='\n'; + /* success, return the link or directory name */ + write(1, fullname, len + 9); + return 0; + } + } while (errno == EEXIST); + /* other error, let's return 2 */ + return 2; +} |