Subject: bin/963: netgroup_mkdb fails if destination exists + others
To: None <gnats-admin@NetBSD.ORG>
From: None <sh391@city.ac.uk>
List: netbsd-bugs
Date: 04/14/1995 04:20:03
>Number:         963
>Category:       bin
>Synopsis:       netgroup_mkdb fails if destination exists + others
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Apr 14 04:20:01 1995
>Originator:     David Brownlee
>Organization:
Private
>Release:        Mar '95
>Environment:
sparc, 1.0A, current
System: NetBSD gluon.city.ac.uk 1.0A NetBSD 1.0A (GLUON) #1: Thu Feb 9 11:25:40 GMT 1995 monoadm@gluon.city.ac.uk:/mono/u1/NetBSD/src/sys/arch/sparc/compile/GLUON sparc


>Description:
	netgroup_mkdb complains if the destination file already exists.
	It is also possible to end up with a partial .db file if the partition
	is full.
	As a final point it would make sense for it to default to /etc/netgroup
	as a source file if none is specified.


>How-To-Repeat:
>Fix:

	I have tried to make minimal changes in the patches, so the way of
	ensuring the temp file is deleted may not be the best (but thinking
	about it it doesn't seem bad :), and my usual C formatting is nothing
	like 4.4 so apologies for style inconsistencies.

*** netgroup_mkdb.c.old	Fri Apr 14 10:37:53 1995
--- netgroup_mkdb.c	Fri Apr 14 11:35:05 1995
***************
*** 66,71 ****
--- 66,72 ----
  
  struct stringlist;
  
+ 
  extern struct stringlist
  		*_ng_sl_init __P((void));
  extern void      _ng_sl_add __P((struct stringlist *, char *));
***************
*** 75,80 ****
--- 76,82 ----
  extern char     *_ng_makekey __P((const char *, const char *, size_t));
  extern int       _ng_parse __P((char **, char **, struct netgroup **));
  
+ static void	 remove_tmp_dbname __P((void));
  static DB       *ng_insert __P((DB *, const char *));
  static void	 ng_reventry __P((DB *, DB *, struct nentry *, char *,
  				  size_t, struct stringlist *));
***************
*** 93,98 ****
--- 95,101 ----
  #endif /* DEBUG_NG */
  
  static char    *dbname = _PATH_NETGROUP_DB;
+ static char    *tmp_dbname = 0;
  
  int
  main(argc, argv)
***************
*** 101,106 ****
--- 104,110 ----
  {
  	DB             *db, *ndb, *hdb, *udb;
  	int             ch;
+ 	char		*fname = _PATH_NETGROUP;
  
  	while ((ch = getopt(argc, argv, "o:")) != EOF)
  		switch (ch) {
***************
*** 116,126 ****
  	argc -= optind;
  	argv += optind;
  
! 	if (argc != 1)
  		usage();
  
  	/* Read and parse the netgroup file */
! 	ndb = ng_load(*argv);
  #ifdef DEBUG_NG
  	(void) fprintf(stderr, "#### Database\n");
  	ng_dump(ndb);
--- 120,132 ----
  	argc -= optind;
  	argv += optind;
  
! 	if (argc == 1)
! 		fname = *argv;
! 	else if (argc > 1 )
  		usage();
  
  	/* Read and parse the netgroup file */
! 	ndb = ng_load(fname);
  #ifdef DEBUG_NG
  	(void) fprintf(stderr, "#### Database\n");
  	ng_dump(ndb);
***************
*** 140,146 ****
  	ng_rdump(udb);
  #endif
  
! 	db = dbopen(dbname, O_RDWR | O_CREAT | O_EXCL,
  		    (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, NULL);
  	if (!db)
  		err(1, dbname);
--- 146,159 ----
  	ng_rdump(udb);
  #endif
  
! 	if ( (tmp_dbname = malloc(strlen(dbname)+8)) == 0 )
! 		err(1, "filename malloc failed");
! 	strcpy(tmp_dbname, dbname);
! 	strcat(tmp_dbname, ".tmpXXX");
! 	if( atexit(remove_tmp_dbname) )
! 		err(1, "atexit malloc failed");
! 
! 	db = dbopen(tmp_dbname, O_RDWR | O_CREAT,
  		    (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH), DB_HASH, NULL);
  	if (!db)
  		err(1, dbname);
***************
*** 148,157 ****
  	ng_write(db, ndb, _NG_KEYBYNAME);
  	ng_rwrite(db, udb, _NG_KEYBYUSER);
  	ng_rwrite(db, hdb, _NG_KEYBYHOST);
! 	(db->close)(db);
  	return 0;
  }
  
  
  /*
   * ng_load(): Load the netgroup database from a file
--- 161,182 ----
  	ng_write(db, ndb, _NG_KEYBYNAME);
  	ng_rwrite(db, udb, _NG_KEYBYUSER);
  	ng_rwrite(db, hdb, _NG_KEYBYHOST);
! 	if( (db->close)(db) == 0 && rename(tmp_dbname, dbname) )
! 		err(1, "rename tmp netgroup file");
! 	chmod(dbname,0644);
! 	tmp_dbname = 0;
  	return 0;
  }
  
+ /*
+  * remove_tmp_dbname(): If we are aborting, then remove tmp filename
+  */
+ 
+ static void remove_tmp_dbname()
+ {
+         if (tmp_dbname)
+ 		remove(tmp_dbname);
+ }
  
  /*
   * ng_load(): Load the netgroup database from a file
***************
*** 676,681 ****
  usage()
  {
  	extern const char *__progname;
! 	fprintf(stderr, "usage: %s [-o db] file\n", __progname);
  	exit(1);
  }
--- 701,706 ----
  usage()
  {
  	extern const char *__progname;
! 	fprintf(stderr, "usage: %s [-o db] [file]\n", __progname);
  	exit(1);
  }
*** netgroup_mkdb.8.orig	Fri Apr 14 11:35:21 1995
--- netgroup_mkdb.8	Fri Apr 14 11:51:39 1995
***************
*** 38,49 ****
  .Sh SYNOPSIS
  .Nm netgroup_mkdb 
  .Op Fl o Ar database
! .Ar file
  .Sh DESCRIPTION
  .Nm Netgroup_mkdb
  creates
  .Xr db 3
  style databases for the specified file.
  These databases are then installed into 
  .Pa /etc/netgroup.db.
  The file must be in the correct format (see
--- 38,52 ----
  .Sh SYNOPSIS
  .Nm netgroup_mkdb 
  .Op Fl o Ar database
! .Op file
  .Sh DESCRIPTION
  .Nm Netgroup_mkdb
  creates
  .Xr db 3
  style databases for the specified file.
+ If no file is specified
+ .Pa /etc/netgroup
+ is used.
  These databases are then installed into 
  .Pa /etc/netgroup.db.
  The file must be in the correct format (see
***************
*** 67,72 ****
--- 70,86 ----
  .It Pa /etc/netgroup
  The current netgroup file
  .El
+ .Sh BUGS
+ Because
+ .Nm netgroup_mkdb
+ guarantees not to install a partial destination file it must
+ build a temporary file in the same file system and if successful use
+ .Xr rename 2
+ to install over the destination file.
+ .Pp
+ If 
+ .Nm netgroup_mkdb
+ fails it will leave the previous version of the destination file intact.
  .Sh SEE ALSO
  .Xr db 3 ,
  .Xr getnetgrent 3 ,
	
>Audit-Trail:
>Unformatted: