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)  

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