📄 grpck.c
字号:
/* Check, if we saw this user name already. */ if (in_blacklist (res.gr_name, strlen (res.gr_name), &blacklist)) { result = E_BAD_ENTRY; printf (_("Duplicate group entry\n")); printf (_("Delete line `%s'? "), cp); if (answer_yes ()) { modified = 1; free (cp); continue; } else goto write_gr; } /* Mark the username as seen, but after checking for duplicate! */ blacklist_store_name (res.gr_name, &blacklist); /* Check, if members exist and that this is not the primary group of the member. */ for (i = 0; res.gr_mem[i]; i++) { struct passwd *pw; pw = getpwnam (res.gr_mem[i]); if (pw == NULL) pw = files_getpwnam (res.gr_mem[i]); /* Check if member exist. */ if (pw == NULL) { result = E_BAD_ENTRY; printf (_("Group `%s': unknown user `%s'\n"), res.gr_name, res.gr_mem[i]); } else if (pw->pw_gid == res.gr_gid) { result = E_BAD_ENTRY; printf (_("Group `%s': Duplicate user entry `%s', already primary group.\n"), res.gr_name, res.gr_mem[i]); } } write_gr: fprintf (output, "%s\n", cp); free (cp); } fclose (input); fclose (output); if (modified) { char *oldname = alloca (strlen (files_etc_dir) + 20); strcpy (oldname, files_etc_dir); strcat (oldname, "/group.old"); unlink (oldname); if (link (inputname, oldname) < 0) fprintf (stderr, _("Warning: cannot create backup file `%s': %m\n"), oldname); rename (outputname, inputname); } else unlink (outputname); return result;}/* XXX move n library. */static struct group *files_getgrent (void){ enum nss_status status; int buflen = 512; char *buffer = NULL; struct group *resultbuf = malloc (sizeof (struct group)); if (buffer == NULL) buffer = malloc (buflen); while ((status = files_getgrent_r (resultbuf, buffer, buflen, &errno)) == NSS_STATUS_TRYAGAIN && errno == ERANGE) { errno = 0; buflen *= 2; buffer = realloc (buffer, buflen); } if (status == NSS_STATUS_SUCCESS) return resultbuf; else return NULL;}struct group_list { struct group *grp; struct group_list *next;};static intsort_group_file (void){ struct group *grp; struct group_list *ptr = NULL; int retval = 0; while ((grp = files_getgrent ())) { if (grp->gr_name[0] == '+' || grp->gr_name[0] == '-') break; if (ptr == NULL) { ptr = malloc (sizeof (struct group_list)); if (ptr == NULL) { fputs ("running out of memory!\n", stderr); exit (E_FAILURE); } ptr->grp = grp; ptr->next = NULL; } else { struct group_list *next = ptr; while (next->next && next->grp->gr_gid < grp->gr_gid) next = next->next; if (next->next == NULL) { next->next = malloc (sizeof (struct group_list)); if (next->next == NULL) { fputs ("running out of memory!\n", stderr); exit (E_FAILURE); } next->next->next = NULL; if (grp->gr_gid > next->grp->gr_gid) next->next->grp = grp; else { next->next->grp = next->grp; next->grp = grp; } } else { struct group_list *tmp; tmp = malloc (sizeof (struct group_list)); if (tmp == NULL) { fputs ("running out of memory!\n", stderr); exit (E_FAILURE); } tmp->next = next->next; next->next = tmp; tmp->grp = next->grp; next->grp = grp; } } } const char *file_tmp = "/group.tmpXXXXXX"; char *group_tmp = alloca (strlen (files_etc_dir) + strlen (file_tmp) + 1); char *group_orig = alloca (strlen (files_etc_dir) + 8); char *group_old = alloca (strlen (files_etc_dir) + 12); struct stat group_stat; FILE *oldgf, *newgf; int newgf_fd; char *cp; cp = stpcpy (group_tmp, files_etc_dir); strcpy (cp, file_tmp); cp = stpcpy (group_orig, files_etc_dir); strcpy (cp, "/group"); cp = stpcpy (group_old, group_orig); strcpy (cp, ".old"); if ((oldgf = fopen (group_orig, "r")) == NULL) { fprintf (stderr, _("Can't open `%s': %m\n"), group_orig); retval = -1; goto error_group; } if (fstat (fileno (oldgf), &group_stat) < 0) { fprintf (stderr, _("Can't stat `%s': %m\n"), group_orig); fclose (oldgf); retval = -1; goto error_group; }#ifdef WITH_SELINUX security_context_t prev_context; if (set_default_context (group_orig, &prev_context) < 0) { fclose (oldgf); retval = -1; goto error_group; }#endif /* Open a temp group file */ newgf_fd = mkstemp (group_tmp);#ifdef WITH_SELINUX if (restore_default_context (prev_context) < 0) { if (newgf_fd >= 0) close (newgf_fd); fclose (oldgf); retval = -1; goto error_group; }#endif if (newgf_fd == -1) { fprintf (stderr, _("Can't create `%s': %m\n"), group_orig); fclose (oldgf); retval = -1; goto error_group; } if (fchmod (newgf_fd, group_stat.st_mode) < 0) { fprintf (stderr, _("Cannot change permissions for `%s': %s\n"), group_tmp, strerror (errno)); fclose (oldgf); close (newgf_fd); unlink (group_tmp); retval = -1; goto error_group; } if (fchown (newgf_fd, group_stat.st_uid, group_stat.st_gid) < 0) { fprintf (stderr, _("Cannot change owner/group for `%s': %s\n"), group_tmp, strerror (errno)); fclose (oldgf); close (newgf_fd); unlink (group_tmp); retval = -1; goto error_group; } if (copy_xattr (group_orig, group_tmp) != 0) { fclose (oldgf); close (newgf_fd); unlink (group_tmp); retval = -1; goto error_group; } newgf = fdopen (newgf_fd, "w+"); if (newgf == NULL) { fprintf (stderr, _("Can't open `%s': %m\n"), group_tmp); fclose (oldgf); close (newgf_fd); unlink (group_tmp); retval = -1; goto error_group; } while (ptr != NULL) { /* write the group entry to tmp file */ if (putgrent (ptr->grp, newgf) < 0) goto write_error_group; ptr = ptr->next; } /* Check if we have entries starting with +/- and copy the rest of the group file without sorting it. */ if (grp != NULL) { /* write the group entry to tmp file */ if (putgrent (grp, newgf) < 0) goto write_error_group; while ((grp = files_getgrent ())) /* write the group entry to tmp file */ if (putgrent (grp, newgf) < 0) { write_error_group: fprintf (stderr, _("Error while writing `%s': %m\n"), group_tmp); fclose (oldgf); fclose (newgf); retval = -1; goto error_group; } } if (fclose (oldgf) != 0) { fprintf (stderr, _("Error while closing `%s': %m\n"), group_orig); fclose (newgf); retval = -1; goto error_group; } if (fclose (newgf) != 0) { fprintf (stderr, _("Error while closing `%s': %m\n"), group_tmp); retval = -1; goto error_group; } unlink (group_old); if (link (group_orig, group_old) < 0) fprintf (stderr, _("Warning: cannot create backup file `%s': %m\n"), group_old); rename (group_tmp, group_orig); error_group: unlink (group_tmp); return retval;}intmain (int argc, char *argv[]){ const char *program = "grpck"; int quiet = 0; int sort = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); while (1) { int c; int option_index = 0; static struct option long_options[] = { {"path", required_argument, NULL, 'P'}, {"quiet", no_argument, NULL, 'q' }, {"readonly", no_argument, NULL, 'r' }, {"sort", no_argument, NULL, 's' }, {"version", no_argument, NULL, 'v' }, {"usage", no_argument, NULL, 'u' }, {"help", no_argument, NULL, '\255' }, {NULL, 0, NULL, '\0'} }; c = getopt_long (argc, argv, "P:qrsvu", long_options, &option_index); if (c == (-1)) break; switch (c) { case 'P': files_etc_dir = strdup (optarg); break; case 'q': quiet = 1; break; case 'r': readonly = 1; break; case 's': sort = 1; break; case '\255': print_help (program); return 0; case 'v': print_version (program, "2005"); return 0; case 'u': print_usage (stdout, program); return 0; default: print_error (program); return E_USAGE; } } argc -= optind; argv += optind; if (argc > 0) { fprintf (stderr, _("%s: Too many arguments.\n"), program); print_error (program); return E_USAGE; } else if (readonly && sort) { fprintf (stderr, _("%s: -s and -r are incompatibile.\n"), program); return E_USAGE; } if (lock_database () != 0) { fprintf (stderr, _("Cannot lock group file: already locked.\n")); return E_PWDBUSY; } if (sort) return sort_group_file (); else return loop_over_group_file (quiet);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -