Explorar el Código

utils: Add utils_get_group_gid

Signed-off-by: Jan Friesse <jfriesse@redhat.com>
Jan Friesse hace 4 meses
padre
commit
7825fc37e0
Se han modificado 3 ficheros con 114 adiciones y 3 borrados
  1. 29 3
      qdevices/test-utils.c
  2. 83 0
      qdevices/utils.c
  3. 2 0
      qdevices/utils.h

+ 29 - 3
qdevices/test-utils.c

@@ -32,11 +32,13 @@
  * THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <stdio.h>
 #include <assert.h>
-#include <string.h>
-#include <math.h>
 #include <errno.h>
+#include <grp.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
 #include "utils.h"
 
@@ -50,6 +52,9 @@ main(void)
 	char buf[32];
 	int set_umask;
 	mode_t umask;
+	gid_t gid;
+	struct group *grp;
+	char *s;
 
 	assert(utils_strtonum("0", 0, 100, &ll) == 0);
 	assert(ll == 0);
@@ -198,6 +203,27 @@ main(void)
 	assert(utils_parse_umask("8", &set_umask, &umask) == -1);
 	assert(utils_parse_umask("unset", &set_umask, &umask) == -1);
 
+	assert(utils_get_group_gid("0", &gid) == 0);
+	assert(gid == 0);
+
+	assert(utils_get_group_gid("", &gid) == 0);
+	assert(gid == -1);
+
+	assert(utils_get_group_gid("1000", &gid) == 0);
+	assert(gid == 1000);
+
+	assert(utils_get_group_gid("-1", &gid) == 0);
+	assert(gid == -1);
+
+	assert((grp = getgrgid(0)) != NULL);
+	assert((s = strdup(grp->gr_name)) != NULL);
+
+	assert(utils_get_group_gid(s, &gid) == 0);
+	assert(gid == 0);
+
+	free(s);
+
+	assert(utils_get_group_gid("qdevicetestnonexistinggroup", &gid) == -1);
 
 	return (0);
 }

+ 83 - 0
qdevices/utils.c

@@ -40,8 +40,10 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <grp.h>
 #include <inttypes.h>
 #include <libgen.h>
+#include <limits.h>
 #include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -51,6 +53,8 @@
 
 #include "utils.h"
 
+#define UTILS_GID_DETERMINE_MAX_SIZE	65536
+
 /*
  * Check string to value on, off, yes, no, 0, 1. Return 1 if value is on, yes or 1, 0 if
  * value is off, no or 0 and -1 otherwise.
@@ -302,3 +306,82 @@ utils_parse_umask(const char *str, int *set_umask, mode_t *umask)
 
 	return (0);
 }
+
+/*
+ * Get gid of group with grp_name name. On success, 0 is returned and
+ * gid contains valid group id or -1 if grp_name is empty string or -1.
+ * In case of error including group doesn't exist -1 is returned and
+ * gid is not changed.
+ */
+int
+utils_get_group_gid(const char *grp_name, gid_t *gid)
+{
+	long long int tmpll;
+	char *grp_buf, *tmp_buf;
+	long int grp_buf_size;
+	int res;
+	struct group grp, *grp_res;
+	int ret;
+
+	ret = 0;
+
+	if (strcmp(grp_name, "") == 0) {
+		*gid = (gid_t)-1;
+
+		return (0);
+	}
+
+	if (utils_strtonum(grp_name, -1, UINT_MAX, &tmpll) == 0) {
+		*gid = (gid_t)tmpll;
+
+		return (0);
+	}
+
+	grp_buf_size = sysconf(_SC_GETGR_R_SIZE_MAX);
+	if (grp_buf_size == -1) {
+		grp_buf_size = 4096;
+	}
+
+	grp_buf = malloc(grp_buf_size);
+	if (grp_buf == NULL) {
+		return (-1);
+	}
+
+	while ((res = getgrnam_r(grp_name, &grp, grp_buf, grp_buf_size, &grp_res)) == ERANGE) {
+		grp_buf_size *= 2;
+
+		if (grp_buf_size > UTILS_GID_DETERMINE_MAX_SIZE) {
+			ret = -1;
+
+			goto exit_free_grp_buf;
+		}
+
+		tmp_buf = realloc(grp_buf, grp_buf_size);
+		if (tmp_buf == NULL) {
+			ret = -1;
+
+			goto exit_free_grp_buf;
+		}
+
+		grp_buf = tmp_buf;
+	}
+
+	if (res != 0) {
+		ret = -1;
+
+		goto exit_free_grp_buf;
+	}
+
+	if (grp_res == NULL) {
+		ret = -1;
+
+		goto exit_free_grp_buf;
+	} else {
+		*gid = grp.gr_gid;
+	}
+
+exit_free_grp_buf:
+	free(grp_buf);
+
+	return (ret);
+}

+ 2 - 0
qdevices/utils.h

@@ -74,6 +74,8 @@ extern int		utils_strtod(const char *str, double min_val, double max_val,
 extern int		utils_parse_umask(const char *str, int *set_umask,
     mode_t *umask);
 
+extern int		utils_get_group_gid(const char *grp_name, gid_t *gid);
+
 #ifdef __cplusplus
 }
 #endif