1 /*
2  * (C) Maint Laboratory 2003-2004
3  * Author: Elohin Igor'
4  * e-mail: maint@unona.ru
5  * fido  : 2:5070/222.52
6  * URL   : http://maint.unona.ru
7  */
8 #include <stdio.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <dirent.h>
13 #include <sys/types.h>
14 #include <sys/file.h>
15 #include <pwd.h>
16 #include "../common.h"
17 #include "../config.h"
18 
19 #ifdef _BSD
20 #include <limits.h>
21 #endif
22 
23 extern FILE *inp_nntp;
24 extern FILE *out_nntp;
25 extern char *prgname;
26 extern unsigned char *verbose;
27 
listnewsgroups()28 int listnewsgroups()
29 {
30     char line[BUFSIZE];
31     char *l, *s;
32 
33     putaline("LIST");
34     if (nntpreply() != 215) {
35 	myerror("%s: reading newsgroups failed", prgname);
36 	return -1;
37     }
38     while ((l = get_line(line)) && (strcmp(l, "."))) {
39 	if (s = strpbrk(line, " \t"))
40 	    *s = '\0';
41 	printf("%s\n", l);
42     }
43     return 0;
44 }
45 
makeactivelist()46 int makeactivelist()
47 {
48     FILE *fd;
49     char *l, *l2, *l3;
50     char line[MSGBUF];
51     struct passwd *pass;
52 
53     if ((pass = getpwnam(leafnode_owner)) == NULL) {
54 	myerror("Can't get uid and guid user %", leafnode_owner);
55 	return -1;
56     }
57 
58     if ((fd = fopen(active, "w")) == NULL) {
59 	myerror("Can't open %s", active);
60 	return -1;
61     }
62 
63     putaline("LIST ACTIVE");
64     if (nntpreply() != 215) {
65 	myerror("%s: reading newsgroups failed", prgname);
66 	return -1;
67     }
68     while ((l = get_line(line)) && (strcmp(l, "."))) {
69         if(isfidogroup(line))
70             fprintf(fd, "%s\n", l);
71     }
72     fclose(fd);
73     if (chmod(active, 0664)) {
74 	myerror("Can't chmod %", active);
75 	remove(active);
76 	return 1;
77     }
78     if (chown(active, pass->pw_uid, pass->pw_gid)) {
79 	myerror("Can't chown %", active);
80 	remove(active);
81 	return 1;
82     }
83     message("Create %s ", active);
84     return 0;
85 }
86 
87 /*
88  * flag = 1 - local group
89  */
createnewsgroup(char * groupname,char * description,unsigned char flag)90 int createnewsgroup(char *groupname, char *description, unsigned char flag)
91 {
92     FILE *fd;
93     if (flag) {
94 	if ((fd = fopen(local_groupinfo, "a+")) == NULL) {
95 	    myerror("Can't open %s", local_groupinfo);
96 	    return -1;
97 	}
98 	fprintf(fd, "%s\ty\t%s\n", groupname, description);
99     } else {
100 	if ((fd = fopen(groupinfo, "a+")) == NULL) {
101 	    myerror("Can't open %s", groupinfo);
102 	    return -1;
103 	}
104 	fprintf(fd, "%s\ty\t0\t0\t0\t%s\n", groupname,
105 		description);
106     }
107     fclose(fd);
108     message("Create newsgroup: %s ", groupname);
109     return 0;
110 }
111 
activatenewsgroup(char * groupname)112 int activatenewsgroup(char *groupname)
113 {
114     FILE *fd;
115     char fname[PATH_MAX];
116     struct passwd *pass;
117 
118     if(islocalnewsgroup(groupname)) return 0;
119     if (isactivenewsgroup(groupname))
120 	return 0;
121     if ((pass = getpwnam(leafnode_owner)) == NULL) {
122 	myerror("Can't get uid and guid user %", leafnode_owner);
123 	return -1;
124     }
125     snprintf(fname, sizeof(fname), "%s/%s", interesting_groups, groupname);
126     if ((fd = fopen(fname, "w")) == NULL) {
127 	myerror("Can't create %s", fname);
128 	return -1;
129     }
130     fclose(fd);
131     if (chmod(fname, 0664)) {
132 	myerror("Can't chmod %", fname);
133 	remove(fname);
134 	return 1;
135     }
136     if (chown(fname, pass->pw_uid, pass->pw_gid)) {
137 	myerror("Can't chown %", fname);
138 	remove(fname);
139 	return 1;
140     }
141     message("Activate newsgroup: %s", groupname);
142     return 0;
143 }
144 
deactivatenewsgroup(char * groupname)145 int deactivatenewsgroup(char *groupname)
146 {
147     int rc = 0;
148     char fname[PATH_MAX];
149 
150     if(islocalnewsgroup(groupname)) return 0;
151     if (isactivenewsgroup(groupname)) {
152 	snprintf(fname, sizeof(fname), "%s/%s", interesting_groups, groupname);
153 	rc = remove(fname);
154 	if (rc)
155 	    myerror("Can't remove %s\n", fname);
156 	else
157 	    message("Deactivate newsgroup: %s", groupname);
158     }
159     return rc;
160 }
161 
islocalnewsgroup(char * groupname)162 int islocalnewsgroup(char *groupname)
163 {
164     FILE *fd;
165     char buf[4096];
166     char *s;
167     int rc = 0;
168 
169     if ((fd = fopen(local_groupinfo, "r")) == NULL) {
170 	myerror("Can't open %s", local_groupinfo);
171 	return -1;
172     }
173     while (fgets(buf, 4095, fd) != NULL) {
174 	if (s = strpbrk(buf, " \t"))
175 	    *s = '\0';
176 	if (strcmp(buf, groupname) == 0) {
177 	    rc = 2;
178 	    break;
179 	}
180     }
181     fclose(fd);
182     return rc;
183 }
184 
isactivenewsgroup(char * groupname)185 int isactivenewsgroup(char *groupname)
186 {
187     char fname[PATH_MAX];
188 
189     if(islocalnewsgroup(groupname)) return 0;
190     snprintf(fname, sizeof(fname), "%s/%s", interesting_groups, groupname);
191     if (access(fname, F_OK) == 0){
192         if(verbose) message("Group %s inactive", fname);
193 	return 1;
194     } else {
195         if(verbose) message("Group %s active, fname");
196 	return 0;
197     }
198 }
199 
removenewsgroup(char * groupname)200 int removenewsgroup(char *groupname)
201 {
202     FILE *ifd, *ofd;
203     int fd;
204     char *fname;
205     char buf[4096];
206     char tmpname[4096];
207     char *s;
208     struct passwd *pass;
209 
210     if ((pass = getpwnam(leafnode_owner)) == NULL) {
211 	myerror("Can't get uid and guid user %", leafnode_owner);
212 	return -1;
213     }
214 
215     if (!isgrouponserver(groupname) && !islocalnewsgroup(groupname)) {
216 	myerror("Group not found %s", groupname);
217 	return 1;
218     }
219     if (isactivenewsgroup(groupname)) {
220 	if (deactivatenewsgroup(groupname)) {
221 	    myerror("Can't deactivate group %s", groupname);
222 	    return 1;
223 	}
224     }
225 
226     if (islocalnewsgroup(groupname))
227 	removefromfile(local_groupinfo, groupname);
228     removefromfile(groupinfo, groupname);
229     message("Remove newsgroup: %s", groupname);
230     return 0;
231 }
removefromfile(char * fname,char * groupname)232 int removefromfile(char *fname, char *groupname)
233 {
234     FILE *ifd, *ofd;
235     int fd;
236     char buf[4096];
237     char tmpname[4096];
238     char *s;
239     struct passwd *pass;
240 
241     if ((pass = getpwnam(leafnode_owner)) == NULL) {
242 	myerror("Can't get uid and guid user %", leafnode_owner);
243 	return -1;
244     }
245     strcpy(tmpname, "/tmp/leafnodeXXXXXX");
246     if ((fd = mkstemp(tmpname)) < 0) {
247 	myerror("Can't create temporary file");
248 	return 1;
249     }
250     if ((ifd = fopen(fname, "r")) == NULL) {
251 	myerror("Can't open %s", fname);
252 	return -1;
253     }
254     if (flock(fileno(ifd), LOCK_EX)) {
255 	myerror("Can't lock file %s", fname);
256 	return 1;
257     }
258     if ((ofd = fdopen(fd, "w")) == NULL) {
259 	myerror("Can't create temporary file");
260 	return 1;
261     }
262     while (fgets(buf, 4095, ifd) != NULL) {
263 	if (s = strpbrk(buf, " \t"))
264 	    *s = '\0';
265 	if (strcmp(buf, groupname)) {
266 	    *s = '\t';
267 	    fputs(buf, ofd);
268 	}
269     }
270     flock(fileno(ifd), LOCK_UN);
271     fclose(ofd);
272     fclose(ifd);
273     movefile(tmpname, fname);
274     if (chmod(fname, 0664)) {
275 	myerror("Can't chmod %", fname);
276 	return 1;
277     }
278     if (chown(fname, pass->pw_uid, pass->pw_gid)) {
279         myerror("Can't chown %s(%d, %d) file %s", leafnode_owner,
280                 pass->pw_uid, pass->pw_gid, fname);
281 	return 1;
282     }
283     return 0;
284 }
285 
286