]> arthur.barton.de Git - netatalk.git/commitdiff
experimental code added from Bob Rogers to generate more persistant DIDs
authorrufustfirefly <rufustfirefly>
Fri, 25 May 2001 16:18:08 +0000 (16:18 +0000)
committerrufustfirefly <rufustfirefly>
Fri, 25 May 2001 16:18:08 +0000 (16:18 +0000)
(please note that the code is not used by afpd yet)

ChangeLog
configure.in
contrib/shell_utils/Makefile.am
contrib/shell_utils/afpd-mtab.pl [new file with mode: 0755]
doc/Makefile.am
etc/afpd/.cvsignore
etc/afpd/Makefile.am
etc/afpd/parse_mtab.c [new file with mode: 0644]
etc/afpd/parse_mtab.h [new file with mode: 0644]
etc/afpd/test_parse_mtab.c [new file with mode: 0644]

index 46e480cabad25fe73ffc450b7452ca2d2ce3bea5..a875f4c8fd9c991a01a5987e69e7ea8f5c72466b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,9 +1,16 @@
-($Id: ChangeLog,v 1.38 2001-05-25 13:23:55 rufustfirefly Exp $)
+($Id: ChangeLog,v 1.39 2001-05-25 16:18:08 rufustfirefly Exp $)
 
 2001-05-25  jeff b  <jeff@univrel.pr.uconn.edu>
        * etc/uams/uams_passwd.c: another Tru64 fix from Burkhard
        Schmidt <bs@cpfs.mpg.de>
 
+       * configure.in, contrib/shell_utils/Makefile.am,
+       contrib/shell_utils/afpd-mtab.pl, doc/Makefile.am,
+       doc/COPYRIGHT.mtab, doc/README.mtab, doc/README.mtab.distribution,
+       etc/afpd/.cvsignore, etc/afpd/Makefile.am, etc/afpd/parse_mtab.c,
+       etc/afpd/parse_mtab.h, test_parse_mtab.c: experimental mtab
+       code from Bob Rogers to generate more persistant DIDs
+
 2001-05-22  jeff b  <jeff@univrel.pr.uconn.edu>
        * configure.in, etc/afpd/unix.h: more portability fixes, and
        integration of Tru64 build fix from Edmund Lam <epl@unimelb.edu.au>
index a1937955449827b19824d8c3f445f824bc659ed1..da05ffe31264ad050bf6045b974e78d77ed8a5fe 100644 (file)
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.77 2001-05-24 00:12:01 samnoble Exp $
+dnl $Id: configure.in,v 1.78 2001-05-25 16:18:08 rufustfirefly Exp $
 dnl configure.in for netatalk
 
 AC_INIT(bin/adv1tov2/adv1tov2.c)
@@ -85,7 +85,7 @@ dnl Checks for header files.
 AC_HEADER_DIRENT
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(fcntl.h limits.h stdint.h strings.h sys/fcntl.h sys/file.h sys/ioctl.h sys/time.h sys/mnttab.h sys/statvfs.h sys/vfs.h mntent.h syslog.h unistd.h termios.h sys/termios.h netdb.h sgtty.h ufs/quota.h mount.h sys/mount.h statfs.h)
+AC_CHECK_HEADERS(fcntl.h limits.h stdint.h strings.h sys/fcntl.h sys/file.h sys/ioctl.h sys/time.h sys/mnttab.h sys/statvfs.h sys/stat.h sys/vfs.h mntent.h syslog.h unistd.h termios.h sys/termios.h netdb.h sgtty.h ufs/quota.h mount.h sys/mount.h statfs.h)
 AC_CHECK_HEADER(sys/cdefs.h,,
        AC_MSG_RESULT([enabling generic cdefs.h from tree])
        CFLAGS="-I\$(top_srcdir)/sys/generic $CFLAGS"
index 603b94341a8205fd8dcbb24757fced63af53307a..359f54cd6020f07b2ecde2d8a1c579f00f223dd6 100644 (file)
@@ -11,6 +11,6 @@ SUFFIXES = .tmpl .
 CLEANFILES = lp2pap.sh
 
 bin_SCRIPTS = apple_cp apple_mv apple_rm cleanappledouble.pl lp2pap.sh \
-       netatalkshorternamelinks.pl
+       netatalkshorternamelinks.pl afpd-mtab.pl
 
 EXTRA_DIST = $(bin_SCRIPTS)
diff --git a/contrib/shell_utils/afpd-mtab.pl b/contrib/shell_utils/afpd-mtab.pl
new file mode 100755 (executable)
index 0000000..6f7dba5
--- /dev/null
@@ -0,0 +1,20 @@
+#! /usr/bin/perl
+#
+# Create an afpd.mtab on standard output from the mtab-format file on standard
+# input.
+#
+#      afpd-mtab.pl < /etc/mtab > /etc/afpd.mtab
+#
+#    Modification history:
+#
+# created.  -- rgr, 9-Apr-01.
+#
+
+print("# afpd.mtab, generated by afpd-mtab.pl on ",
+      `date`);
+while (<>) {
+    ($device, $mount_point, $fstype) = split;
+    next
+       if $device eq 'none' || $mount_point eq '/boot';
+    printf("%2d %-10s %s\n", ++$did_index, $device, $mount_point);
+}
index fb14c3889c513ade1ed7ebf07f90c401e9abe2c6..a2d9efddbbfb045e46dfa433c8640dbd7330287b 100644 (file)
@@ -1,6 +1,7 @@
 # Makefile.am for INSTALL/
 
 EXTRA_DIST = \
+       COPYRIGHT.mtab \
        INSTALL.txt \
        FAQ     \
        README \
@@ -13,4 +14,6 @@ EXTRA_DIST = \
        README.OPENBSD  \
        README.SOLARIS  \
        README.SUNOS    \
-       README.ULTRIX
+       README.ULTRIX   \
+       README.mtab             \
+       README.mtab.distribution
index 6026dd019460202be44d454e15b3a1f873c01c3f..6bc5977fe061fc446e4ffd96da4729c8b68a9475 100644 (file)
@@ -1,5 +1,6 @@
 Makefile
 Makefile.in
 afpd
+test_parse_mtab
 .deps
 .libs
index 8e546bc2560174e867895fcba4e89a1366bfc22a..5c7e82548bc11af1bfa004d652708e43b713f602 100644 (file)
@@ -4,17 +4,22 @@ SUBDIRS = nls
 
 sbin_PROGRAMS = afpd
 
+bin_PROGRAMS = test_parse_mtab
+
 afpd_SOURCES = unix.c ofork.c main.c switch.c auth.c volume.c directory.c \
         file.c enumerate.c desktop.c filedir.c fork.c appl.c gettok.c \
         status.c afp_options.c afp_asp.c afp_dsi.c messages.c afp_config.c \
-        nfsquota.c codepage.c quota.c uam.c afs.c uid.c
+        nfsquota.c codepage.c quota.c uam.c afs.c uid.c parse_mtab.c
+
+test_parse_mtab_SOURCES = test_parse_mtab.c
+test_parse_mtab_LDADD = $(top_builddir)/libatalk/libatalk.la
 
 afpd_LDADD = $(top_builddir)/libatalk/libatalk.la
 afpd_LDFLAGS = -rdynamic
 
 noinst_HEADERS = auth.h codepage.h afp_config.h desktop.h directory.h file.h \
         filedir.h fork.h globals.h icon.h misc.h status.h switch.h uam_auth.h \
-        uid.h unix.h volume.h
+        uid.h unix.h volume.h parse_mtab.h
 
 LIBS = @LIBS@ @AFPD_LIBS@
 
diff --git a/etc/afpd/parse_mtab.c b/etc/afpd/parse_mtab.c
new file mode 100644 (file)
index 0000000..d2b56ef
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * $Id: parse_mtab.c,v 1.1 2001-05-25 16:18:09 rufustfirefly Exp $
+ *
+ * afpd_mtab_parse & support.  -- rgr, 9-Apr-01.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "directory.h"
+#include "parse_mtab.h"
+
+#define MAX_AFPD_MTAB_ENTRIES 256      /* unreasonably large number */
+#define MTAB_DELIM_CHARS " \t\n"       /* delimiters for parsing */
+
+#ifndef COPY_STRING
+#define COPY_STRING(lval, str) \
+         (lval) = malloc(1+strlen(str)), strcpy((lval), (str))
+#endif /* COPY_STRING */
+
+/* global mount table; afpd_st_cnid uses this to lookup the right entry.  */
+static struct afpd_mount_table *afpd_mount_table = NULL;
+
+static int
+ceil_log_2 __P((int n))
+     /* Return the number of bits required to represent n.  Only works for
+       positive n.  */
+{
+  int n_bits = 0;
+
+  while (n) {
+    n >>= 1;
+    n_bits += 1;
+  }
+  return(n_bits);
+}
+
+unsigned int
+afpd_st_cnid __P((struct stat *st))
+     /* Given a stat structure, look up the device in afpd_mount_table, and
+        compute and return a CNID.  */
+{
+  int id;
+  struct afpd_mtab_entry *entry;
+
+  if (afpd_mount_table != NULL) {
+    for (id = 0; id < afpd_mount_table->size; id++) {
+      entry = afpd_mount_table->table[id];
+      if (entry != NULL
+         && entry->dev_major == major(st->st_dev)
+         && entry->dev_minor == minor(st->st_dev)) {
+       return(entry->bit_value | st->st_ino);
+      }
+    }
+  }
+
+  /* Fallback. */
+  return(st->st_ino);
+}
+
+struct afpd_mount_table *
+afpd_mtab_parse __P((char *file_name))
+     /* Parse the given mtab file, returning a new afpd_mount_table structure.
+       Also saves it in the afpd_mount_table static variable for use by the
+       afpd_st_cnid function.  Returns NULL if it encounters an error.
+
+        [It would be great if this could generate a warning for any device that
+        allows more inodes than we can allocate bits for.  -- rgr, 9-Apr-01.]
+        */
+{
+  struct afpd_mtab_entry *entries[MAX_AFPD_MTAB_ENTRIES];      /* temp */
+  int id, max_id = 0, n_errors = 0;
+  struct stat st;
+  char line[1000], *p, *index_tok, *dev_tok, *mount_tok;
+  int line_number = 0;         /* one-based */
+  FILE *f = fopen(file_name, "r");
+
+  if (f == NULL) {
+    fprintf(stderr, "Error:  Can't open %s:  code %d\n",
+           file_name, errno);
+    return(NULL);
+  }
+  for (id = 0; id < MAX_AFPD_MTAB_ENTRIES; id++)
+    entries[id] = NULL;
+  while (fgets(line, sizeof(line), f) != NULL) {
+    line_number++;
+    /* flush comment */
+    if ((p = strchr(line, '#')) != NULL)
+      *p = '\0';
+    /* get fields */
+    index_tok = strtok(line, MTAB_DELIM_CHARS);
+    dev_tok = strtok(NULL, MTAB_DELIM_CHARS);
+    mount_tok = strtok(NULL, MTAB_DELIM_CHARS);
+    if (mount_tok == NULL) {
+      /* [warning here if index_tok nonempty?  -- rgr, 9-Apr-01.]  */
+    }
+    else if (id = strtol(index_tok, &p, 10),
+            *p != '\0') {
+      fprintf(stderr, "afpd:%s:%d:  Non-integer device index value '%s'.\n",
+             file_name, line_number, index_tok);
+      n_errors++;
+    }
+    else if (id < 1 || id > MAX_AFPD_MTAB_ENTRIES) {
+      fprintf(stderr,
+             "afpd:%s:%d:  Expected an integer from 1 to %d, but got '%s'.\n",
+             file_name, line_number, MAX_AFPD_MTAB_ENTRIES-1, index_tok);
+      n_errors++;
+    }
+    else if (entries[id] != NULL) {
+      /* not unique. */
+      fprintf(stderr,
+             "afpd:%s:%d:  Id %d is already taken for %s.\n",
+             file_name, line_number, id, entries[id]->device);
+      n_errors++;
+    }
+    else if (stat(dev_tok, &st) != 0) {
+      fprintf(stderr, "afpd:%s:%d:  Can't stat '%s':  code %d\n",
+             file_name, line_number, dev_tok, errno);
+      n_errors++;
+    }
+    else if (! S_ISBLK(st.st_mode)) {
+      fprintf(stderr, "afpd:%s:%d:  '%s' is not a block device.\n",
+             file_name, line_number, dev_tok);
+      n_errors++;
+    }
+    else {
+      /* make a new entry */
+      struct afpd_mtab_entry *entry
+       = (struct afpd_mtab_entry *) malloc(sizeof(struct afpd_mtab_entry));
+
+      entry->id = id;
+      entry->dev_major = major(st.st_rdev);
+      entry->dev_minor = minor(st.st_rdev);
+      COPY_STRING(entry->device, dev_tok);
+      COPY_STRING(entry->mount_point, mount_tok);
+      entries[id] = entry;
+      if (id > max_id)
+       max_id = id;
+    }
+  } /* next line */
+
+  close(f);
+  if (n_errors) {
+    fprintf(stderr, "Got %d errors while reading %s; exiting.\n",
+           n_errors, file_name);
+    return(NULL);
+  }
+  else {
+    /* make the table. */
+    struct afpd_mount_table *mount_table       /* return value */
+      = (struct afpd_mount_table *) malloc(sizeof(struct afpd_mount_table));
+    int n_bits = ceil_log_2(max_id);
+    int table_size;
+    struct afpd_mtab_entry **new_entries;
+
+    if (n_bits < AFPD_MTAB_MIN_DEV_BITS)
+      n_bits = AFPD_MTAB_MIN_DEV_BITS;
+    table_size = 1 << n_bits;
+    new_entries = (struct afpd_mtab_entry **)
+      malloc(table_size*sizeof(struct afpd_mtab_entry *));
+    mount_table->size = table_size;
+    mount_table->bits = n_bits;
+    mount_table->shift = AFPD_MTAB_DEV_AND_INODE_BITS-n_bits;
+    for (id = 0; id < table_size; id++) {
+      if (entries[id] != NULL)
+       entries[id]->bit_value = entries[id]->id << mount_table->shift;
+      new_entries[id] = entries[id];
+    }
+    mount_table->table = new_entries;
+
+    afpd_mount_table = mount_table;
+    return(mount_table);
+  }
+}
diff --git a/etc/afpd/parse_mtab.h b/etc/afpd/parse_mtab.h
new file mode 100644 (file)
index 0000000..17faccb
--- /dev/null
@@ -0,0 +1,38 @@
+/* header for afpd_mtab_parse, afpd_st_cnid */
+
+#ifndef _parse_mtab_h
+#define _parse_mtab_h
+
+/* set this to 31 to reserve the high-order bit for distinguishing files and
+   directories.  */
+#define AFPD_MTAB_DEV_AND_INODE_BITS 32
+/* this gives us some stability when adding partitions. */
+#define AFPD_MTAB_MIN_DEV_BITS 3
+
+struct afpd_mtab_entry {
+  /* Description of one partition.  */
+  int id;              /* unique index (a small integer) */
+  int dev_major, dev_minor;    /* device numbers */
+  int bit_value;       /* preshifted device index field */
+  char *device;                /* device name string (for debugging) */
+  char *mount_point;   /* mounted directory (for debugging) */
+};
+
+struct afpd_mount_table {
+  /* Description of all partitions.  */
+  int size;            /* length of entries array, a power of 2 */
+  int bits;            /* number of bits, log2(size) */
+  unsigned int shift;  /* amount by which to shift into CNID device field */
+  struct afpd_mtab_entry **table;      /* index -> entry map vector, some
+                                          entries may be null */
+};
+
+extern
+unsigned int
+afpd_st_cnid __P((struct stat *st));
+
+extern
+struct afpd_mount_table *
+afpd_mtab_parse __P((char *file_name));
+
+#endif /* not _parse_mtab_h */
diff --git a/etc/afpd/test_parse_mtab.c b/etc/afpd/test_parse_mtab.c
new file mode 100644 (file)
index 0000000..8db58c4
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * $Id: test_parse_mtab.c,v 1.1 2001-05-25 16:18:09 rufustfirefly Exp $
+ * test driver for the afpd_mtab_parse fn.  -- rgr, 9-Apr-01.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+
+#include "directory.h"
+#include "parse_mtab.h"
+
+/* hack.  etc/afpd/directory.h would need to be patched accordingly.  this
+   version ignores the filep stuff.  based on the comment starting around
+   line 200 in etc/afpd/file.c (search for "fucking mess"), this may be OK.
+   */
+#ifdef CNID
+#undef CNID
+#endif /* ! CNID */
+
+/* keep-filep version.  must also decrement AFPD_MTAB_DEV_AND_INODE_BITS.  */
+/* #define CNID(pst, filep)    (afpd_st_cnid(pst) | CNID_FILE(filep)) */
+#define CNID(pst, filep)       (afpd_st_cnid(pst))
+
+int
+main(int argc, char **argv)
+{
+  char *file_name = "afpd.mtab";
+  struct afpd_mount_table *table = NULL;
+  int arg = 1;
+
+  if (argc >= 3 && strcmp(argv[1], "-f") == 0) {
+    file_name = argv[2];
+    arg += 2;
+  }
+  if (arg < argc && argv[arg][0] == '-') {
+    /* either they don't understand, or they must be asking for help anyway. */
+    fprintf(stderr, "Usage:  %s [-f file-name] [file . . . ]\n",
+           argv[0]);
+    exit(1);
+  }
+  table = afpd_mtab_parse(file_name);
+  if (table != NULL) {
+    struct stat st;
+    int id, count = 0;
+
+    fprintf(stderr, "File %s:  Field width %d, shift %d.\n",
+           file_name, table->bits, table->shift);
+    for (id = 0; id < table->size; id++) {
+      struct afpd_mtab_entry *entry = table->table[id];
+
+      if (entry != NULL) {
+       fprintf(stderr, "  Id %d -> device %s (%d,%d) on %s -> bits 0x%08x.\n",
+               id, entry->device, entry->dev_major, entry->dev_minor,
+               entry->mount_point, entry->bit_value);
+       count++;
+      }
+    }
+    fprintf(stderr, "%d entries used out of a maximum of %d (1..%d).\n",
+           count, table->size-1, table->size-1);
+    for (; arg < argc; arg++) {
+      if (lstat(argv[arg], &st) != 0) {
+       fprintf(stderr, "Can't lstat '%s':  code %d\n",
+               argv[arg], errno);
+      }
+      else {
+       fprintf(stderr, "File %s, device (%d,%d), inode %d, CNID 0x%08x.\n",
+               argv[arg], major(st.st_dev), minor(st.st_dev), st.st_ino,
+               CNID(&st, S_ISDIR(st.st_mode) ? 1 : 0));
+      }
+    }
+  }
+  return(0);
+}