Subject: bin/6452: mk-amd-map is broken
To: None <gnats-bugs@gnats.netbsd.org>
From: None <arnej@math.ntnu.no>
List: netbsd-bugs
Date: 11/17/1998 16:35:48
>Number:         6452
>Category:       bin
>Synopsis:       mk-amd-map is broken
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Nov 17 07:50:01 1998
>Last-Modified:
>Originator:     Arne H. Juul
>Organization:
	Norwegian University of Technology and Science
>Release:        NetBSD-current as of Nov 17, 1998
>Environment:

System: NetBSD leon.math.ntnu.no 1.3H NetBSD 1.3H (LEO) #1: Sat Oct 24 01:29:43 CEST 1998 arnej@leon.math.ntnu.no:/usr/src/sys/arch/i386/compile/LEO i386

>Description:
	
>How-To-Repeat:
	Try to run mk-amd-map:

leon:/etc/amd:(510)# mk-amd-map homes
WARNING: existing map "homes.db" destroyed
leon:/etc/amd:(511)# ls -la homes* dbm*
-rw-------  1 root  wheel      0 Nov 17 15:37 dbm18559a
-rw-------  1 root  wheel  67180 Nov 17 15:35 homes
-r--r--r--  1 root  wheel  16384 Nov 17 15:37 homes.db

	Here, I'm getting a bogus warning, a leftover
	empty dbm file, and a database that's smaller than
	the text file used as input.  Things are *very* wrong here...
	These bugs are probably imported from 6.0a16.

>Fix:
	Import a newer version of am-utils, or apply this patch, which
	is largely based on am-utils-6.0b2s3:

--- mk-amd-map.c.orig	Tue Nov 17 16:08:04 1998
+++ mk-amd-map.c	Tue Nov 17 16:24:54 1998
@@ -216,9 +216,8 @@
 main(int argc, char *argv[])
 {
   FILE *mapf;
-  int mapfd = -1;
-  char *map;
-  int rc = 0;
+  int error;
+  char *mapsrc;
   DBM *mapd = NULL;
   static char maptmp[] = "dbmXXXXXX";
   char maptdb[16];
@@ -245,37 +244,39 @@
     fputs("Usage: mk-amd-map [-p] file-map\n", stderr);
     exit(1);
   }
-  map = argv[optind];
+  mapsrc = argv[optind];
 
   /* test if can get to the map directory */
-  sl = strrchr(map, '/');
+  sl = strrchr(mapsrc, '/');
   if (sl) {
     *sl = '\0';
-    if (chdir(map) < 0) {
+    if (chdir(mapsrc) < 0) {
       fputs("Can't chdir to ", stderr);
-      perror(map);
+      perror(mapsrc);
       exit(1);
     }
-    map = sl + 1;
+    mapsrc = sl + 1;
+  }
+
+  /* open source file */
+  mapf = fopen(mapsrc, "r");
+  if (!mapf) {
+    fprintf(stderr, "cannot open source file ");
+    perror(mapsrc);
+    exit(1);
   }
 
   if (!printit) {
-    len = strlen(map);
+    len = strlen(mapsrc);
     mapdb = (char *) malloc(len + 4);
     if (!mapdb) {
       perror("mk-amd-map: malloc");
       exit(1);
     }
-#ifdef HAVE_MKSTEMP
-    mapfd = mkstemp(maptmp);
-#else /* not HAVE_MKSTEMP */
-    map = mktemp(maptmp);
-    if (!maptmp) {
+    if (!mktemp(maptmp)) {
       fprintf(stderr, "cannot create temporary file\n");
       exit(1);
     }
-    mapfd = open(map, O_RDONLY);
-#endif /* not HAVE_MKSTEMP */
 
     /* open DBM files */
     sprintf(maptdb, "%s.db", maptmp);
@@ -284,54 +285,48 @@
       perror(maptdb);
       exit(1);
     }
-  }
-  /* open and check if map file was opened OK */
-  mapf = fdopen(mapfd, "r");
-  if (mapf && !printit)
     mapd = dbm_open(maptmp, O_RDWR|O_CREAT, 0444);
-  else
-    mapd = 0;
+    if (!mapd) {
+      fprintf(stderr, "cannot initialize temporary database: %s", maptmp);
+      exit(1);
+    }
+  }
 
 #ifndef DEBUG
-  /* ignore ^C if debuggung is on (but why?) */
+  /* ignore ^C unless debugging is on (to avoid leaving half-filled db) */
   signal(SIGINT, SIG_IGN);
 #endif /* not DEBUG */
 
-  if (mapd || printit) {
-    int error = read_file(mapf, map, mapd);
-    (void) close(mapfd);
-    (void) fclose(mapf);
-    dbm_close(mapd);
-    if (printit) {
-      if (error) {
-	fprintf(stderr, "Error creating ndbm map for %s\n", map);
-	rc = 1;
-      }
-    } else {
-
-      if (error) {
-	fprintf(stderr, "Error reading source file  %s\n", map);
-	rc = 1;
-      } else {
-	sprintf(mapdb, "%s.db", map);
-	if (unlink(mapdb) == 0)
-	  fprintf(stderr, "WARNING: existing map \"%s.db\" destroyed\n", map);
-	if (rename(maptdb, mapdb) < 0) {
-	  fprintf(stderr, "Couldn't rename %s to ", maptdb);
-	  perror(mapdb);
-	  /* Throw away the temporary map */
-	  unlink(maptdb);
-	  rc = 1;
-	}
-      }
-    }
-
-  } else {
-    fprintf(stderr, "Can't open \"%s.db\" for ", map);
-    perror("writing");
-    rc = 1;
+  /* print input db to stdout or to temp database */
+  error = read_file(mapf, mapsrc, mapd);
+  (void) fclose(mapf);
+  if (error) {
+    if (printit)
+      fprintf(stderr, "Error reading source file  %s\n", mapsrc);
+    else
+      fprintf(stderr, "Error creating database map for %s\n", mapsrc);
+    (void) unlink(maptdb);
+    exit(1);
   }
-  exit(rc);
+
+  if (printit)
+    exit(0);                    /* nothing more to do */
+
+  /* if gets here, we wrote to a database */
+
+  dbm_close(mapd);
+  /* all went well */
+
+  sprintf(mapdb, "%s.db", mapsrc);
+  if (rename(maptdb, mapdb) < 0) {
+    fprintf(stderr, "Couldn't rename %s to ", maptdb);
+    perror(mapdb);
+    /* Throw away the temporary map */
+    unlink(maptdb);
+    exit(1);
+  }
+
+  exit(0);
 }
 
 #else /* not HAVE_MAP_NDBM */
>Audit-Trail:
>Unformatted: