summaryrefslogtreecommitdiffstats
path: root/pw/grupd.c
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2012-10-30 08:00:53 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2012-10-30 08:00:53 +0000
commit530ff00378e7fc235e5ea51067c77398d575141e (patch)
tree3abb99e7579c92aa1f2dcc367f65dac3918dfad9 /pw/grupd.c
parent6844cbad609c7fe499b4e759a0157ae704c84ccc (diff)
downloadpw-darwin-530ff00378e7fc235e5ea51067c77398d575141e.tar.gz
pw-darwin-530ff00378e7fc235e5ea51067c77398d575141e.tar.zst
pw-darwin-530ff00378e7fc235e5ea51067c77398d575141e.zip
Teach pw(8) about how to use pw/gr API to reduce code duplication
MFC after: 2 months
Diffstat (limited to 'pw/grupd.c')
-rw-r--r--pw/grupd.c120
1 files changed, 39 insertions, 81 deletions
diff --git a/pw/grupd.c b/pw/grupd.c
index edff76d..e9f6b5e 100644
--- a/pw/grupd.c
+++ b/pw/grupd.c
@@ -29,6 +29,9 @@ static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
+#include <grp.h>
+#include <libutil.h>
+#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -65,107 +68,62 @@ getgrpath(const char * file)
return pathbuf;
}
-int
-grdb(char *arg,...)
-{
- /*
- * This is a stub for now, but maybe eventually be functional
- * if ever an indexed version of /etc/groups is implemented.
- */
- arg=arg;
- return 0;
-}
-
-int
-fmtgrentry(char **buf, int * buflen, struct group * grp, int type)
+static int
+gr_update(struct group * grp, char const * group)
{
- int i, l;
-
- /*
- * Since a group line is of arbitrary length,
- * we need to calculate up-front just how long
- * it will need to be...
- */
- /* groupname : password : gid : */
- l = strlen(grp->gr_name) + 1 + strlen(grp->gr_passwd) + 1 + 5 + 1;
- /* group members + comma separator */
- for (i = 0; grp->gr_mem[i] != NULL; i++) {
- l += strlen(grp->gr_mem[i]) + 1;
- }
- l += 2; /* For newline & NUL */
- if (extendline(buf, buflen, l) == -1)
- l = -1;
- else{
- /*
- * Now we can safely format
- */
- if (type == PWF_STANDARD)
- l = sprintf(*buf, "%s:*:%ld:", grp->gr_name, (long) grp->gr_gid);
- else
- l = sprintf(*buf, "%s:%s:%ld:", grp->gr_name, grp->gr_passwd, (long) grp->gr_gid);
-
- /*
- * List members
- */
- for (i = 0; grp->gr_mem[i] != NULL; i++) {
- l += sprintf(*buf + l, "%s%s", i ? "," : "", grp->gr_mem[i]);
- }
-
- (*buf)[l++] = '\n';
- (*buf)[l] = '\0';
- }
- return l;
-}
+ int pfd, tfd;
+ struct group *gr = NULL;
+ struct group *old_gr = NULL;
+ if (grp != NULL)
+ gr = gr_dup(grp);
-int
-fmtgrent(char **buf, int * buflen, struct group * grp)
-{
- return fmtgrentry(buf, buflen, grp, PWF_STANDARD);
-}
+ if (group != NULL)
+ old_gr = GETGRNAM(group);
+ if (gr_init(grpath, NULL))
+ err(1, "gr_init()");
-static int
-gr_update(struct group * grp, char const * group, int mode)
-{
- int l;
- char pfx[64];
- int grbuflen = 0;
- char *grbuf = NULL;
-
- ENDGRENT();
- l = snprintf(pfx, sizeof pfx, "%s:", group);
-
- /*
- * Update the group file
- */
- if (grp != NULL && fmtgrentry(&grbuf, &grbuflen, grp, PWF_PASSWD) == -1)
- l = -1;
- else {
- l = fileupdate(getgrpath(_GROUP), 0644, grbuf, pfx, l, mode);
- if (l == 0)
- l = grdb(NULL);
+ if ((pfd = gr_lock()) == -1) {
+ gr_fini();
+ err(1, "gr_lock()");
+ }
+ if ((tfd = gr_tmp(-1)) == -1) {
+ gr_fini();
+ err(1, "gr_tmp()");
}
- if (grbuf != NULL)
- free(grbuf);
- return l;
+ if (gr_copy(pfd, tfd, gr, old_gr) == -1) {
+ gr_fini();
+ err(1, "gr_copy()");
+ }
+ if (gr_mkdb() == -1) {
+ gr_fini();
+ err(1, "gr_mkdb()");
+ }
+ free(gr);
+ gr_fini();
+ return 0;
}
int
addgrent(struct group * grp)
{
- return gr_update(grp, grp->gr_name, UPD_CREATE);
+ return gr_update(grp, NULL);
}
int
chggrent(char const * login, struct group * grp)
{
- return gr_update(grp, login, UPD_REPLACE);
+ return gr_update(grp, login);
}
int
delgrent(struct group * grp)
{
- return gr_update(NULL, grp->gr_name, UPD_DELETE);
+ char group[MAXLOGNAME];
+
+ strlcpy(group, grp->gr_name, MAXLOGNAME);
+
+ return gr_update(NULL, group);
}