* Copyright (c) 1980, 1983 Regents of the University of California.
* %sccs.include.redist.c%
"@(#) Copyright (c) 1980, 1983 Regents of the University of California.\n\
static char sccsid
[] = "@(#)mkpasswd.c 5.7 (Berkeley) %G%";
static struct passwd _pw_passwd
;
#define MAXLINELENGTH 1024
static char line
[MAXLINELENGTH
];
* Mkpasswd does two things -- use the ``arg'' file to create ``arg''.{pag,dir}
* for ndbm, and, if the -p flag is on, create a password file in the original
* format. It doesn't use the getpwent(3) routines because it has to figure
* out offsets for the encrypted passwords to put in the dbm files. One other
* problem is that, since the addition of shadow passwords, getpwent(3) has to
* use the dbm databases rather than simply scanning the actual file. This
* required the addition of a flag field to the dbm database to distinguish
* between a record keyed by name, and one keyed by uid.
extern int errno
, optind
;
register char *flag
, *p
, *t
;
char buf
[8192], nbuf
[50], *strerror();
while ((ch
= getopt(argc
, argv
, "pv")) != EOF
)
case 'p': /* create ``password.orig'' */
case 'v': /* backward compatible */
if (!(_pw_fp
= fopen(*argv
, "r"))) {
"mkpasswd: %s: can't open for reading.\n", *argv
);
/* open old password format file, dbm files */
(void)sprintf(buf
, "%s.orig", *argv
);
if ((oldfd
= open(buf
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644)) < 0) {
(void)fprintf(stderr
, "mkpasswd: %s: %s\n", buf
,
if (!(oldfp
= fdopen(oldfd
, "w"))) {
(void)fprintf(stderr
, "mkpasswd: %s: fdopen failed.\n",
if (!(dp
= dbm_open(*argv
, O_WRONLY
|O_CREAT
|O_EXCL
, 0644))) {
(void)fprintf(stderr
, "mkpasswd: %s: %s\n", *argv
,
#define COMPACT(e) t = e; while (*p++ = *t++);
COMPACT(_pw_passwd
.pw_name
);
(void)sprintf(nbuf
, "%ld", offset
);
bcopy((char *)&_pw_passwd
.pw_uid
, p
, sizeof(int));
bcopy((char *)&_pw_passwd
.pw_gid
, p
, sizeof(int));
bcopy((char *)&_pw_passwd
.pw_change
, p
, sizeof(time_t));
COMPACT(_pw_passwd
.pw_class
);
COMPACT(_pw_passwd
.pw_gecos
);
COMPACT(_pw_passwd
.pw_dir
);
COMPACT(_pw_passwd
.pw_shell
);
bcopy((char *)&_pw_passwd
.pw_expire
, p
, sizeof(time_t));
(void)printf("store %s, uid %d\n", _pw_passwd
.pw_name
,
key
.dptr
= _pw_passwd
.pw_name
;
key
.dsize
= strlen(_pw_passwd
.pw_name
);
if (dbm_store(dp
, key
, content
, DBM_INSERT
) < 0)
key
.dptr
= (char *)&_pw_passwd
.pw_uid
;
if (dbm_store(dp
, key
, content
, DBM_INSERT
) < 0)
/* create original format password file entry */
fprintf(oldfp
, "%s:*:%d:%d:%s:%s:%s\n", _pw_passwd
.pw_name
,
_pw_passwd
.pw_uid
, _pw_passwd
.pw_gid
, _pw_passwd
.pw_gecos
,
_pw_passwd
.pw_dir
, _pw_passwd
.pw_shell
);
bad
: (void)fprintf(stderr
, "mkpasswd: dbm_store failed.\n");
char buf
[MAXPATHLEN
], *strcpy();
for (p
= strcpy(buf
, fname
); *p
; ++p
);
(void)fprintf(stderr
, "usage: mkpasswd [-p] passwd_file\n");
/* from libc/gen/getpwent.c */
char *fgets(), *strsep(), *index();
if (!(fgets(line
, sizeof(line
), _pw_fp
)))
/* skip lines that are too big */
if (!index(line
, '\n')) {
while ((ch
= getc(_pw_fp
)) != '\n' && ch
!= EOF
)
_pw_passwd
.pw_name
= strsep(&bp
, ":\n");
_pw_passwd
.pw_passwd
= strsep(&bp
, ":\n");
offset
+= _pw_passwd
.pw_passwd
- line
;
if (!(cp
= strsep(&bp
, ":\n")))
_pw_passwd
.pw_uid
= atoi(cp
);
if (!(cp
= strsep(&bp
, ":\n")))
_pw_passwd
.pw_gid
= atoi(cp
);
_pw_passwd
.pw_class
= strsep(&bp
, ":\n");
if (!(cp
= strsep(&bp
, ":\n")))
_pw_passwd
.pw_change
= atol(cp
);
if (!(cp
= strsep(&bp
, ":\n")))
_pw_passwd
.pw_expire
= atol(cp
);
_pw_passwd
.pw_gecos
= strsep(&bp
, ":\n");
_pw_passwd
.pw_dir
= strsep(&bp
, ":\n");
_pw_passwd
.pw_shell
= strsep(&bp
, ":\n");