Line data Source code
1 : /*
2 : * This file is part of rmlint.
3 : *
4 : * rmlint is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * rmlint is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with rmlint. If not, see <http://www.gnu.org/licenses/>.
16 : *
17 : * Authors:
18 : *
19 : * - Christopher <sahib> Pahl 2010-2015 (https://github.com/sahib)
20 : * - Daniel <SeeSpotRun> T. 2014-2015 (https://github.com/SeeSpotRun)
21 : *
22 : * Hosted on http://github.com/sahib/rmlint
23 : *
24 : */
25 :
26 : #include "../formats.h"
27 : #include "../preprocess.h"
28 :
29 : #include <glib.h>
30 : #include <stdio.h>
31 :
32 : static const char *RM_LINT_TYPE_TO_DESCRIPTION[] =
33 : {[RM_LINT_TYPE_UNKNOWN] = "", [RM_LINT_TYPE_BADLINK] = N_("Bad symlink(s)"),
34 : [RM_LINT_TYPE_EMPTY_DIR] = N_("Empty dir(s)"),
35 : [RM_LINT_TYPE_NONSTRIPPED] = N_("Non stripped binarie(s)"),
36 : [RM_LINT_TYPE_BADUID] = N_("Bad UID(s)"), [RM_LINT_TYPE_BADGID] = N_("Bad GID(s)"),
37 : [RM_LINT_TYPE_BADUGID] = N_("Bad UID and GID(s)"),
38 : [RM_LINT_TYPE_EMPTY_FILE] = N_("Empty file(s)"),
39 : [RM_LINT_TYPE_DUPE_CANDIDATE] = N_("Duplicate(s)"),
40 : [RM_LINT_TYPE_DUPE_DIR_CANDIDATE] = N_("Duplicate Directorie(s)")};
41 :
42 : static const char *RM_LINT_TYPE_TO_COMMAND[] =
43 : {[RM_LINT_TYPE_UNKNOWN] = "", [RM_LINT_TYPE_BADLINK] = "rm",
44 : [RM_LINT_TYPE_EMPTY_DIR] = "rmdir",
45 : [RM_LINT_TYPE_NONSTRIPPED] = "strip --strip-debug",
46 : [RM_LINT_TYPE_BADUID] = "chown %s", [RM_LINT_TYPE_BADGID] = "chgrp %s",
47 : [RM_LINT_TYPE_BADUGID] = "chown %s:%s", [RM_LINT_TYPE_EMPTY_FILE] = "rm",
48 : [RM_LINT_TYPE_DUPE_CANDIDATE] = "rm", [RM_LINT_TYPE_DUPE_DIR_CANDIDATE] = "rm -rf"};
49 :
50 114 : static const char *rm_fmt_command_color(RmSession *session, RmFile *file, FILE *out) {
51 114 : switch(file->lint_type) {
52 : case RM_LINT_TYPE_NONSTRIPPED:
53 : case RM_LINT_TYPE_BADUID:
54 : case RM_LINT_TYPE_BADGID:
55 : case RM_LINT_TYPE_BADUGID:
56 0 : return MAYBE_BLUE(out, session);
57 : case RM_LINT_TYPE_DUPE_CANDIDATE:
58 : case RM_LINT_TYPE_DUPE_DIR_CANDIDATE:
59 114 : if(file->is_original) {
60 57 : return MAYBE_GREEN(out, session);
61 : } else {
62 57 : return MAYBE_RED(out, session);
63 : }
64 : default:
65 0 : return MAYBE_RED(out, session);
66 : }
67 : }
68 :
69 : typedef struct RmFmtHandlerPretty {
70 : /* must be first */
71 : RmFmtHandler parent;
72 :
73 : /* user data */
74 : RmLintType last_lint_type;
75 :
76 : const char *user;
77 : const char *group;
78 : int elems_written;
79 : } RmFmtHandlerProgress;
80 :
81 57 : static void rm_fmt_head(_U RmSession *session, RmFmtHandler *parent, _U FILE *out) {
82 57 : RmFmtHandlerProgress *self = (RmFmtHandlerProgress *)parent;
83 :
84 57 : self->user = rm_util_get_username();
85 57 : self->group = rm_util_get_groupname();
86 57 : }
87 :
88 114 : static void rm_fmt_elem(_U RmSession *session, RmFmtHandler *parent, FILE *out,
89 : RmFile *file) {
90 114 : RmFmtHandlerProgress *self = (RmFmtHandlerProgress *)parent;
91 :
92 114 : if(file->lint_type == RM_LINT_TYPE_UNFINISHED_CKSUM) {
93 : /* pretty output should not contain this */
94 0 : return;
95 : }
96 :
97 114 : self->elems_written++;
98 :
99 114 : if(file->lint_type != self->last_lint_type) {
100 114 : fprintf(out, "\n%s#%s %s:\n", MAYBE_YELLOW(out, session),
101 57 : MAYBE_RESET(out, session),
102 57 : _(RM_LINT_TYPE_TO_DESCRIPTION[file->lint_type]));
103 57 : self->last_lint_type = file->lint_type;
104 : }
105 :
106 114 : fprintf(out, " %s", rm_fmt_command_color(session, file, out));
107 :
108 114 : const char *format = RM_LINT_TYPE_TO_COMMAND[file->lint_type];
109 114 : switch(file->lint_type) {
110 : case RM_LINT_TYPE_BADUID:
111 0 : fprintf(out, format, self->user);
112 0 : break;
113 : case RM_LINT_TYPE_BADGID:
114 0 : fprintf(out, format, self->group);
115 0 : break;
116 : case RM_LINT_TYPE_BADUGID:
117 0 : fprintf(out, format, self->user, self->group);
118 0 : break;
119 : case RM_LINT_TYPE_DUPE_CANDIDATE:
120 114 : if(file->is_original) {
121 57 : fprintf(out, "ls");
122 : } else {
123 57 : fprintf(out, "%s", format);
124 : }
125 114 : break;
126 : case RM_LINT_TYPE_DUPE_DIR_CANDIDATE:
127 0 : if(file->is_original) {
128 0 : fprintf(out, "ls -la");
129 : } else {
130 0 : fprintf(out, "%s", format);
131 : }
132 0 : break;
133 : default:
134 0 : fprintf(out, "%s", format);
135 : }
136 :
137 114 : RM_DEFINE_PATH(file);
138 114 : fprintf(out, "%s %s\n", MAYBE_RESET(out, session), file_path);
139 : }
140 :
141 855 : static void rm_fmt_prog(_U RmSession *session, RmFmtHandler *parent, FILE *out,
142 : RmFmtProgressState state) {
143 855 : RmFmtHandlerProgress *self = (RmFmtHandlerProgress *)parent;
144 :
145 855 : if(state == RM_PROGRESS_STATE_PRE_SHUTDOWN && self->elems_written) {
146 57 : fprintf(out, "\n");
147 : }
148 855 : }
149 :
150 : static RmFmtHandlerProgress PRETTY_HANDLER_IMPL = {
151 : /* Initialize parent */
152 : .parent =
153 : {
154 : .size = sizeof(PRETTY_HANDLER_IMPL),
155 : .name = "pretty",
156 : .head = rm_fmt_head,
157 : .elem = rm_fmt_elem,
158 : .prog = rm_fmt_prog,
159 : .foot = NULL,
160 : .valid_keys = {NULL},
161 : },
162 :
163 : /* Initialize own stuff */
164 : .last_lint_type = RM_LINT_TYPE_UNKNOWN,
165 : .elems_written = 0};
166 :
167 : RmFmtHandler *PRETTY_HANDLER = (RmFmtHandler *)&PRETTY_HANDLER_IMPL;
|