]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/auth/uniq.c
fix ref822 again: remove uniqarray(), fix case with many entries in 'n'.
[plan9front.git] / sys / src / cmd / auth / uniq.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4
5 typedef struct Who Who;
6 struct Who
7 {
8         Who *next;
9         char *line;
10         char *name;
11 };
12
13 int cmp(void *arg1, void *arg2)
14 {
15         Who **a = arg1, **b = arg2;
16
17         return strcmp((*a)->name, (*b)->name);
18 }
19
20 void
21 main(int argc, char **argv)
22 {
23         int changed, i, n;
24         Biobuf *b;
25         char *p, *name;
26         Who *first, *last, *w, *nw, **l;
27
28         if(argc != 2){
29                 fprint(2, "usage: auth/uniq file\n");
30                 exits(0);
31         }
32
33         last = first = 0;
34         b = Bopen(argv[1], OREAD);
35         if(b == 0)
36                 exits(0);
37
38         n = 0;
39         changed = 0;
40         while(p = Brdline(b, '\n')){
41                 p[Blinelen(b)-1] = 0;
42                 name = p;
43                 while(*p && *p != '|')
44                         p++;
45                 if(*p)
46                         *p++ = 0;
47
48                 for(nw = first; nw; nw = nw->next){
49                         if(strcmp(nw->name, name) == 0){
50                                 free(nw->line);
51                                 nw->line = strdup(p);
52                                 changed = 1;
53                                 break;
54                         }
55                 }
56                 if(nw)
57                         continue;
58
59                 w = malloc(sizeof(Who));
60                 if(w == 0){
61                         fprint(2, "auth/uniq: out of memory\n");
62                         exits(0);
63                 }
64                 memset(w, 0, sizeof(Who));
65                 w->name = strdup(name);
66                 w->line = strdup(p);
67                 if(first == 0)
68                         first = w;
69                 else
70                         last->next = w;
71                 last = w;
72                 n++;
73         }
74         Bterm(b);
75
76         l = malloc(n*sizeof(Who*));
77         for(i = 0, nw = first; nw; nw = nw->next, i++)
78                 l[i] = nw;
79         qsort(l, n, sizeof(Who*), cmp);
80
81         if(!changed)
82                 exits(0);
83
84         b = Bopen(argv[1], OWRITE);
85         if(b == 0){
86                 fprint(2, "auth/uniq: can't open %s\n", argv[1]);
87                 exits(0);
88         }
89         for(i = 0; i < n; i++)
90                 Bprint(b, "%s|%s\n", l[i]->name, l[i]->line);
91         Bterm(b);
92 }