const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX);
- // note: pointer seems pointless except that it is used to determine if the name was found.
+ // Pointer seems pointless except that it is used to determine if the name was found.
struct passwd password;
struct passwd *pointer = 0;
length = F_account_pwd_length_fallback_first_d;
}
- // must be set to 0 to avoid problems due to the design of getpwnam()/getpwnam_r().
+ // Must be set to 0 to avoid problems due to the design of getpwnam()/getpwnam_r().
errno = 0;
char buffer[length];
const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX);
- // note: pointer seems pointless except that it is used to determine if the name was found.
+ // Pointer seems pointless except that it is used to determine if the name was found.
struct passwd password;
struct passwd *pointer = 0;
length = F_account_pwd_length_fallback_first_d;
}
- // must be set to 0 to avoid problems due to the design of getpwuid()/getpwuid_r().
+ // Must be set to 0 to avoid problems due to the design of getpwuid()/getpwuid_r().
errno = 0;
char buffer[length];
const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX);
- // Note: pointer seems pointless except that it is used to determine if the name was found.
- struct group grp;
+ // Pointer seems pointless except that it is used to determine if the name was found.
+ struct group group_data;
struct group *pointer;
size_t length = length_max;
errno = 0;
char buffer[length];
- int result = getgrnam_r(name, &grp, buffer, length, &pointer);
+ int result = getgrnam_r(name, &group_data, buffer, length, &pointer);
if (result) {
if (errno == EINTR) return F_status_set_error(F_interrupt);
return F_exist_not;
}
- *id = grp.gr_gid;
+ *id = group_data.gr_gid;
return F_none;
}
char buffer[F_account_pwd_length_fallback_second_d];
- const int result = getgrnam_r(name, &grp, buffer, length, &pointer);
+ const int result = getgrnam_r(name, &group_data, buffer, length, &pointer);
if (result) {
if (errno == EINTR) return F_status_set_error(F_interrupt);
return F_exist_not;
}
- *id = grp.gr_gid;
+ *id = group_data.gr_gid;
return F_none;
}
const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX);
- // Note: pointer seems pointless except that it is used to determine if the name was found.
+ // Pointer seems pointless except that it is used to determine if the name was found.
struct passwd password;
struct passwd *pointer = 0;
}
#endif // _di_f_account_id_user_by_name_
+#ifndef _di_f_account_name_group_by_id_
+ f_status_t f_account_name_group_by_id(const gid_t id, f_string_dynamic_t *name) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!name) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ name->used = 0;
+
+ f_status_t status = F_none;
+
+ const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX);
+
+ // Pointer seems pointless except that it is used to determine if the name was found.
+ struct group group_data;
+ struct group *pointer = 0;
+
+ size_t length = length_max + 1;
+
+ {
+ if (length == -1) {
+ length = F_account_pwd_length_fallback_first_d;
+ }
+
+ // Must be set to 0 to avoid problems due to the design of getpwuid()/getpwuid_r().
+ errno = 0;
+
+ char buffer[length];
+ const int result = getgrgid_r(id, &group_data, buffer, length, &pointer);
+
+ if (result) {
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+ if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
+ if (errno == ENFILE) return F_status_set_error(F_file_open_max);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+
+ if (errno == ERANGE) {
+ if (length_max > 0) return F_status_set_error(F_buffer_too_small);
+ }
+ else {
+ return F_status_set_error(F_failure);
+ }
+ }
+ else {
+ if (!pointer) {
+ return F_exist_not;
+ }
+
+ const f_array_length_t name_length = strnlen(group_data.gr_name, length);
+
+ macro_f_string_dynamic_t_resize(status, (*name), name_length + 1);
+ if (F_status_is_error(status)) return status;
+
+ memcpy(name->string, group_data.gr_name, name_length);
+
+ name->string[name_length] = 0;
+ name->used = name_length;
+
+ return F_none;
+ }
+ }
+
+ length = F_account_pwd_length_fallback_second_d;
+
+ char buffer[F_account_pwd_length_fallback_second_d];
+
+ const int result = getgrgid_r(id, &group_data, buffer, length, &pointer);
+
+ if (result) {
+ if (errno == EINTR) return F_status_set_error(F_interrupt);
+ if (errno == EIO) return F_status_set_error(F_input_output);
+ if (errno == EMFILE) return F_status_set_error(F_file_descriptor_max);
+ if (errno == ENFILE) return F_status_set_error(F_file_open_max);
+ if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+ if (errno == ERANGE) return F_status_set_error(F_buffer_too_small);
+
+ return F_status_set_error(F_failure);
+ }
+
+ if (!pointer) {
+ return F_exist_not;
+ }
+
+ const f_array_length_t name_length = strnlen(group_data.gr_name, length);
+
+ macro_f_string_dynamic_t_resize(status, (*name), name_length + 1);
+ if (F_status_is_error(status)) return status;
+
+ memcpy(name->string, group_data.gr_name, name_length);
+
+ name->string[name_length] = 0;
+ name->used = name_length;
+
+ return F_none;
+ }
+#endif // _di_f_account_name_group_by_id_
+
#ifndef _di_f_account_name_user_by_id_
f_status_t f_account_name_user_by_id(const uid_t id, f_string_dynamic_t *name) {
#ifndef _di_level_0_parameter_checking_
const size_t length_max = sysconf(_SC_GETPW_R_SIZE_MAX);
- // note: pointer seems pointless except that it is used to determine if the name was found.
+ // Pointer seems pointless except that it is used to determine if the name was found.
struct passwd password;
struct passwd *pointer = 0;
length = F_account_pwd_length_fallback_first_d;
}
- // must be set to 0 to avoid problems due to the design of getpwuid()/getpwuid_r().
+ // Must be set to 0 to avoid problems due to the design of getpwuid()/getpwuid_r().
errno = 0;
char buffer[length];
#endif // _di_f_account_by_id_
/**
- * Get the group account id by the group name.
+ * Get the account group id by the group name.
*
* @param name
* The group name.
#endif // _di_f_account_id_user_by_name_
/**
+ * Get the account group name by the group id.
+ *
+ * @param id
+ * The id of the group.
+ * @param name
+ * This is replaced with by the group name.
+ * The name will be NULL terminated.
+ *
+ * @return
+ * F_none on success.
+ *
+ * F_buffer_too_small (with error bit) if the buffer is too small to store the account data.
+ * F_file_descriptor_max (with error bit) if max file descriptors is reached.
+ * F_file_open_max (with error bit) too many open files.
+ * F_input_output (with error bit) if an I/O error occurred.
+ * F_interrupt (with error bit) when program received an interrupt signal, halting operation.
+ * F_memory_not (with error bit) if out of memory.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_failure (with error bit) on any other error.
+ *
+ * @see getgrgid_r()
+ */
+#ifndef _di_f_account_name_group_by_id_
+ extern f_status_t f_account_name_group_by_id(const gid_t id, f_string_dynamic_t *name);
+#endif // _di_f_account_name_group_by_id_
+
+/**
* Get the user account name by the user id.
*
* @param id
#if !defined(_di_f_account_by_name_) || !defined(_di_f_account_by_id_)
f_status_t private_f_account_from_passwd(const struct passwd password, const f_array_length_t password_length, f_account_t *account) {
- f_status_t status = F_none;
+ f_status_t status = F_none;
// Account UID and GID.
account->id_user = password.pw_uid;
account->id_group = password.pw_gid;
-
- // account home directory.
+ // Account home directory.
f_array_length_t string_length = strnlen(password.pw_dir, password_length);
- macro_f_string_dynamic_t_resize(status, account->home, string_length + 1);
+ status = f_string_dynamic_resize(string_length + 1, &account->home);
if (F_status_is_error(status)) return status;
memcpy(account->home.string, password.pw_dir, string_length);
account->home.string[string_length] = 0;
account->home.used = string_length;
-
- // account label (gecos).
+ // Account label (gecos).
string_length = strnlen(password.pw_gecos, password_length);
- macro_f_string_dynamic_t_resize(status, account->label, string_length + 1);
+ status = f_string_dynamic_resize(string_length + 1, &account->label);
if (F_status_is_error(status)) return status;
memcpy(account->label.string, password.pw_gecos, string_length);
account->label.string[string_length] = 0;
account->label.used = string_length;
-
- // account name.
+ // Account name.
string_length = strnlen(password.pw_name, password_length);
- macro_f_string_dynamic_t_resize(status, account->name, string_length + 1);
+ status = f_string_dynamic_resize(string_length + 1, &account->name);
if (F_status_is_error(status)) return status;
memcpy(account->name.string, password.pw_name, string_length);
account->name.string[string_length] = 0;
account->name.used = string_length;
-
- // account password directory.
+ // Account password directory.
string_length = strnlen(password.pw_passwd, password_length);
- macro_f_string_dynamic_t_resize(status, account->password, string_length + 1);
+ status = f_string_dynamic_resize(string_length + 1, &account->password);
if (F_status_is_error(status)) return status;
memcpy(account->password.string, password.pw_passwd, string_length);
account->password.string[string_length] = 0;
account->password.used = string_length;
-
- // account shell directory.
+ // Account shell directory.
string_length = strnlen(password.pw_shell, password_length);
- macro_f_string_dynamic_t_resize(status, account->shell, string_length + 1);
+ status = f_string_dynamic_resize(string_length + 1, &account->shell);
if (F_status_is_error(status)) return status;
memcpy(account->shell.string, password.pw_shell, string_length);