aboutsummaryrefslogtreecommitdiff
path: root/mktmp/mktmp.c
diff options
context:
space:
mode:
authorWilly Tarreau <willy@wtap.(none)>2006-07-26 10:46:55 +0200
committerWilly Tarreau <willy@wtap.(none)>2006-07-26 10:46:55 +0200
commitfcb250efba23ae522c4c8cb03c47dd40edcf9603 (patch)
tree3756bd1748842a3f1049d857e8412f148a8741b9 /mktmp/mktmp.c
parentInitial commit (diff)
downloadflxutils-fcb250efba23ae522c4c8cb03c47dd40edcf9603.tar.xz
[RELEASE] flxutils-0.1.4.2v0.1.4.2
Diffstat (limited to 'mktmp/mktmp.c')
-rw-r--r--mktmp/mktmp.c136
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;
+}