Subject: quick hack
To: None <current-users@NetBSD.org>
From: Manuel Bouyer <bouyer@antioche.lip6.fr>
List: current-users
Date: 05/19/1999 11:48:11
--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii

Hi,
I did a quick hack to change all inodes from an UID to another on a raw disk
device. This has several advantages over chown:
- it doesn't alter the times of the inode (so supserver doesn't think the files
  are new, for example)
- it's faster, escecially if you want to change only some inodes in a
  tree (you'd had to use find ... |xargs chown otherwise).

I just used this on a 8Gb ccd holding a NetBSD sup tree. It can be easily
changed to change gid, permissions or other inode-only attributes.
The filesystem needs to be unmounted.

To compile: drop the file in src/sbin/fsck_ffs and:
gcc -I../fsck -I. chowner.c dir.c inode.c pass1.c pass1b.c pass2.c pass3.c pass4.c pass5.c setup.c utilities.c ../fsck/fsutil.c ../../sys/ufs/ffs/ffs_bswap.c ../../sys/ufs/ffs/ffs_subr.c ../../sys/ufs/ffs/ffs_tables.c

--
Manuel Bouyer, LIP6, Universite Paris VI.           Manuel.Bouyer@lip6.fr
--

--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="chowner.c"


#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <err.h>

#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
#include <ufs/ffs/fs.h>
#include <ufs/ffs/ffs_extern.h>

#include "fsck.h"
#include "extern.h"

extern char *__progname;	/* from crt0.o */

int     returntosingle = 0;
struct dinode *curinode;
ino_t   curinum;

int olduid, newuid;
int
main(argc, argv)
	int     argc;
	char   *argv[];
{
	uid_t olduid = atoi(argv[1]);
	uid_t newuid = atoi(argv[2]);
	ino_t inum;

	if (argc != 4)
		exit(1);
	if (!setup(argv[3]))
		errx(1, "cannot set up file system `%s'", argv[3]);

	printf("olduid=%d, newuid=%d on %s OK?", olduid, newuid, argv[3]);
	fflush(stdout);
	if (getchar() != 'y')
		exit(1);

	for (inum = ROOTINO; inum < maxino; inum++) {
		curinode = ginode(inum);
		if (iswap32(curinode->di_uid) != olduid)
			continue;
		printf("%d ", inum);
		fflush(stdout);
		curinode->di_uid = iswap32(newuid);
		inodirty();
	}
	sblock->fs_clean = 0;   /* mark it dirty */
	sbdirty();
	markclean = 0;
	ckfini();
	printf("*** FILE SYSTEM MARKED DIRTY\n");
	printf("*** BE SURE TO RUN FSCK TO CLEAN UP ANY DAMAGE\n");
	printf("*** IF IT WAS MOUNTED, RE-MOUNT WITH -u -o reload\n");
	exit(0);
}

--82I3+IH0IqGh5yIs--