1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40#include "libbb.h"
41
42int uniq_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
43int uniq_main(int argc UNUSED_PARAM, char **argv)
44{
45 const char *input_filename;
46 unsigned skip_fields, skip_chars, max_chars;
47 unsigned opt;
48 char *cur_line;
49 const char *cur_compare;
50
51 enum {
52 OPT_c = 0x1,
53 OPT_d = 0x2,
54 OPT_u = 0x4,
55 OPT_f = 0x8,
56 OPT_s = 0x10,
57 OPT_w = 0x20,
58 OPT_i = 0x40,
59 };
60
61 skip_fields = skip_chars = 0;
62 max_chars = INT_MAX;
63
64 opt = getopt32(argv, "cduf:+s:+w:+i", &skip_fields, &skip_chars, &max_chars);
65 argv += optind;
66
67 input_filename = argv[0];
68 if (input_filename) {
69 const char *output;
70
71 if (input_filename[0] != '-' || input_filename[1]) {
72 close(STDIN_FILENO);
73 xopen(input_filename, O_RDONLY);
74 }
75 output = argv[1];
76 if (output) {
77 if (argv[2])
78 bb_show_usage();
79 if (output[0] != '-' || output[1]) {
80
81
82
83 xmove_fd(xopen(output, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
84 }
85 }
86 }
87
88 cur_compare = cur_line = NULL;
89
90 do {
91 unsigned i;
92 unsigned long dups;
93 char *old_line;
94 const char *old_compare;
95
96 old_line = cur_line;
97 old_compare = cur_compare;
98 dups = 0;
99
100
101 while ((cur_line = xmalloc_fgetline(stdin)) != NULL) {
102 cur_compare = cur_line;
103 for (i = skip_fields; i; i--) {
104 cur_compare = skip_whitespace(cur_compare);
105 cur_compare = skip_non_whitespace(cur_compare);
106 }
107 for (i = skip_chars; *cur_compare && i; i--) {
108 ++cur_compare;
109 }
110
111 if (!old_line)
112 break;
113 if ((opt & OPT_i)
114 ? strncasecmp(old_compare, cur_compare, max_chars)
115 : strncmp(old_compare, cur_compare, max_chars)
116 ) {
117 break;
118 }
119
120 free(cur_line);
121 ++dups;
122 }
123
124 if (old_line) {
125 if (!(opt & (OPT_d << !!dups))) {
126 if (opt & OPT_c) {
127
128 printf("%7lu ", dups + 1);
129 }
130 puts(old_line);
131 }
132 free(old_line);
133 }
134 } while (cur_line);
135
136 die_if_ferror(stdin, input_filename);
137
138 fflush_stdout_and_exit(EXIT_SUCCESS);
139}
140