-($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>
-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)
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"
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)
--- /dev/null
+#! /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);
+}
# Makefile.am for INSTALL/
EXTRA_DIST = \
+ COPYRIGHT.mtab \
INSTALL.txt \
FAQ \
README \
README.OPENBSD \
README.SOLARIS \
README.SUNOS \
- README.ULTRIX
+ README.ULTRIX \
+ README.mtab \
+ README.mtab.distribution
Makefile
Makefile.in
afpd
+test_parse_mtab
.deps
.libs
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@
--- /dev/null
+/*
+ * $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);
+ }
+}
--- /dev/null
+/* 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 */
--- /dev/null
+/*
+ * $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);
+}