xref: /plan9/sys/src/cmd/auth/uniq.c (revision d854de5991c7e0df387efa3ede5edcfdd69b65da)
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 
cmp(void * arg1,void * arg2)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
main(int argc,char ** argv)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 }
93