+/* This is a private API between Libinfo, Libc, and the DirectoryService daemon.
+ * Since we are trying to determine if an external provider will back group
+ * lookups, we can use this, without relying on additional APIs or tools
+ * that might not work yet */
+extern int _ds_running(void);
+
+#define NUM_GROUPS 6
+static int
+setgroups_if_single_user(void)
+{
+ int i, retval = -1;
+ struct group *grp;
+ gid_t gids[NUM_GROUPS];
+
+ if (!_ds_running()) {
+ printf("In single-user mode.\n");
+ g_is_single_user = 1;
+
+ /* We skip 'nobody' and 'anyone' */
+ getgrent();
+ getgrent();
+ for (i = 0; i < NUM_GROUPS; i++) {
+ grp = getgrent();
+ if (!grp) {
+ break;
+ }
+
+ gids[i] = grp->gr_gid;
+ }
+
+ endgrent();
+
+ /* Only succeed if we find at least NUM_GROUPS */
+ if (i == NUM_GROUPS) {
+ retval = setgroups(NUM_GROUPS, gids);
+ if (retval == 0) {
+ getgroups(NUM_GROUPS, gids);
+ printf("After single-user hack, groups are: ");
+ for (i = 0; i < NUM_GROUPS; i++) {
+ printf("%d, ", gids[i]);
+ }
+ putchar('\n');
+ } else {
+ printf("Setgroups failed.\n");
+ }
+ } else {
+ printf("Couldn't get sufficient number of groups.\n");
+ }
+ } else {
+ printf("Not in single user mode.\n");
+ retval = 0;
+ }
+
+
+ return retval;
+}
+
+static const char *current_arch( void )
+{
+ cpu_type_t cputype = _mh_execute_header.cputype;
+ cpu_subtype_t cpusubtype = _mh_execute_header.cpusubtype;
+
+ const NXArchInfo *arch = NXGetArchInfoFromCpuType(cputype, cpusubtype);
+
+ if (arch) {
+ return arch->name;
+ } else {
+ return "<unknown>";
+ }
+}
+
+#undef printf /* this makes the "-l" output easier to read */
+static void list_all_tests( void )
+{
+ int i, my_tests_count;
+
+ my_tests_count = (sizeof( g_tests ) / sizeof( g_tests[0] ));
+ printf( "\nList of all tests this tool performs... \n" );
+
+ for ( i = 0; i < (my_tests_count - 1); i++ ) {
+ printf( " %d \t %s \n", (i + 1), g_tests[ i ].test_infop );
+ }
+
+ return;
+} /* list_all_tests */