citadel
About: Citadel is an advanced messaging and collaboration system for groupware and BBS applications (preferred OS: Linux).
  Fossies Dox: citadel.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

netconfig.c
Go to the documentation of this file.
1/*
2 * This module handles loading, saving, and parsing of room network configurations.
3 *
4 * Copyright (c) 2000-2021 by the citadel.org team
5 *
6 * This program is open source software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 3.
8 *
9 * This program 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 */
15
16#include "sysdep.h"
17#include <stdio.h>
18#include <sys/types.h>
19#include <dirent.h>
20
21#ifdef HAVE_SYSCALL_H
22# include <syscall.h>
23#else
24# if HAVE_SYS_SYSCALL_H
25# include <sys/syscall.h>
26# endif
27#endif
28#include <dirent.h>
29#include <assert.h>
30
31#include <libcitadel.h>
32
33#include "ctdl_module.h"
34#include "serv_extensions.h"
35#include "config.h"
36
37
38/*
39 * Create a config key for a room's netconfig entry
40 */
41void netcfg_keyname(char *keybuf, long roomnum) {
42 if (!keybuf) return;
43 sprintf(keybuf, "c_netconfig_%010ld", roomnum);
44}
45
46
47/*
48 * Given a room number and a textual netconfig, convert to base64 and write to the configdb
49 */
50void SaveRoomNetConfigFile(long roomnum, const char *raw_netconfig) {
51 char keyname[25];
52 char *enc;
53 int enc_len;
54 int len;
55
56 len = strlen(raw_netconfig);
57 netcfg_keyname(keyname, roomnum);
58 enc = malloc(len * 2);
59
60 if (enc) {
61 enc_len = CtdlEncodeBase64(enc, raw_netconfig, len, 0);
62 if ((enc_len > 1) && (enc[enc_len-2] == 13)) enc[enc_len-2] = 0;
63 if ((enc_len > 0) && (enc[enc_len-1] == 10)) enc[enc_len-1] = 0;
64 enc[enc_len] = 0;
65 syslog(LOG_DEBUG, "netconfig: writing key '%s' (length=%d)", keyname, enc_len);
66 CtdlSetConfigStr(keyname, enc);
67 free(enc);
68 }
69}
70
71
72/*
73 * Given a room number, attempt to load the netconfig configdb entry for that room.
74 * If it returns NULL, there is no netconfig.
75 * Otherwise the caller owns the returned memory and is responsible for freeing it.
76 */
77char *LoadRoomNetConfigFile(long roomnum) {
78 char keyname[25];
79 char *encoded_netconfig = NULL;
80 char *decoded_netconfig = NULL;
81
82 netcfg_keyname(keyname, roomnum);
83 encoded_netconfig = CtdlGetConfigStr(keyname);
84 if (!encoded_netconfig) return NULL;
85
86 decoded_netconfig = malloc(strlen(encoded_netconfig)); // yeah, way bigger than it needs to be, but safe
87 CtdlDecodeBase64(decoded_netconfig, encoded_netconfig, strlen(encoded_netconfig));
88 return decoded_netconfig;
89}
90
91
92/*-----------------------------------------------------------------------------*
93 * Per room network configs : exchange with client *
94 *-----------------------------------------------------------------------------*/
95
96void cmd_gnet(char *argbuf) {
97 if ( (CC->room.QRflags & QR_MAILBOX) && (CC->user.usernum == atol(CC->room.QRname)) ) {
98 /* users can edit the netconfigs for their own mailbox rooms */
99 }
100 else if (CtdlAccessCheck(ac_room_aide)) return;
101
102 cprintf("%d Network settings for room #%ld <%s>\n", LISTING_FOLLOWS, CC->room.QRnumber, CC->room.QRname);
103
104 char *c = LoadRoomNetConfigFile(CC->room.QRnumber);
105 if (c) {
106 int len = strlen(c);
107 client_write(c, len); // Can't use cprintf() here, it has a limit of 1024 bytes
108 if (c[len] != '\n') {
109 client_write(HKEY("\n"));
110 }
111 free(c);
112 }
113 cprintf("000\n");
114}
115
116
117void cmd_snet(char *argbuf) {
118 StrBuf *Line = NULL;
119 StrBuf *TheConfig = NULL;
120 int rc;
121
123 Line = NewStrBuf();
124 TheConfig = NewStrBuf();
125 cprintf("%d send new netconfig now\n", SEND_LISTING);
126
127 while (rc = CtdlClientGetLine(Line), (rc >= 0)) {
128 if ((rc == 3) && (strcmp(ChrPtr(Line), "000") == 0))
129 break;
130
131 StrBufAppendBuf(TheConfig, Line, 0);
132 StrBufAppendBufPlain(TheConfig, HKEY("\n"), 0);
133 }
134 FreeStrBuf(&Line);
135
137 SaveRoomNetConfigFile(CC->room.QRnumber, ChrPtr(TheConfig));
139 FreeStrBuf(&TheConfig);
140}
141
142
143/*
144 * Convert any legacy configuration files in the "netconfigs" directory
145 */
147{
148 DIR *dh = NULL;
149 struct dirent *dit = NULL;
150 char filename[PATH_MAX];
151 long roomnum;
152 FILE *fp;
153 long len;
154 char *v;
155
156 dh = opendir(ctdl_netcfg_dir);
157 if (!dh) return;
158
159 syslog(LOG_INFO, "netconfig: legacy netconfig files exist - converting them!");
160
161 while (dit = readdir(dh), dit != NULL) { // yes, we use the non-reentrant version; we're not in threaded mode yet
162 roomnum = atol(dit->d_name);
163 if (roomnum > 0) {
164 snprintf(filename, sizeof filename, "%s/%ld", ctdl_netcfg_dir, roomnum);
165 fp = fopen(filename, "r");
166 if (fp) {
167 fseek(fp, 0L, SEEK_END);
168 len = ftell(fp);
169 if (len > 0) {
170 v = malloc(len);
171 if (v) {
172 rewind(fp);
173 if (fread(v, len, 1, fp)) {
174 SaveRoomNetConfigFile(roomnum, v);
175 unlink(filename);
176 }
177 free(v);
178 }
179 }
180 else {
181 unlink(filename); // zero length netconfig, just delete it
182 }
183 fclose(fp);
184 }
185 }
186 }
187
188 closedir(dh);
189 rmdir(ctdl_netcfg_dir);
190}
191
192
193/*
194 * Module entry point
195 */
197{
198 if (!threading)
199 {
201 CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config");
202 CtdlRegisterProtoHook(cmd_snet, "SNET", "Set network config");
203 }
204 return "netconfig";
205}
#define ctdl_netcfg_dir
Definition: citadel_dirs.h:18
char * CtdlGetConfigStr(char *key)
Definition: config.c:384
void CtdlSetConfigStr(char *key, char *value)
Definition: config.c:317
#define CC
Definition: context.h:140
int CtdlAccessCheck(int)
Definition: user_ops.c:387
@ ac_room_aide
Definition: ctdl_module.h:245
void CtdlRegisterProtoHook(void(*handler)(char *), char *cmd, char *desc)
#define CTDL_MODULE_INIT(module_name)
Definition: ctdl_module.h:50
#define LISTING_FOLLOWS
Definition: ipcdef.h:5
#define QR_MAILBOX
Definition: ipcdef.h:53
#define SEND_LISTING
Definition: ipcdef.h:8
void convert_legacy_netcfg_files(void)
Definition: netconfig.c:146
void SaveRoomNetConfigFile(long roomnum, const char *raw_netconfig)
Definition: netconfig.c:50
void cmd_gnet(char *argbuf)
Definition: netconfig.c:96
char * LoadRoomNetConfigFile(long roomnum)
Definition: netconfig.c:77
void netcfg_keyname(char *keybuf, long roomnum)
Definition: netconfig.c:41
void cmd_snet(char *argbuf)
Definition: netconfig.c:117
void * malloc(size_t)
void free(void *)
@ S_NETCONFIGS
Definition: server.h:146
int snprintf(char *buf, size_t max, const char *fmt,...)
Definition: snprintf.c:69
int CtdlClientGetLine(StrBuf *Target)
Definition: sysdep.c:518
void cprintf(const char *format,...)
Definition: sysdep.c:381
int client_write(const char *buf, int nbytes)
Definition: sysdep.c:307
void unbuffer_output(void)
Definition: sysdep.c:276
void begin_critical_section(int which_one)
Definition: threads.c:67
void end_critical_section(int which_one)
Definition: threads.c:85