#include <sys/wait.h>
#include <string.h>
#include <limits.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "server.h"
#include "citserver.h"
#include "policy.h"
#include "database.h"
#include "msgbase.h"
-#include "tools.h"
#include "internet_addressing.h"
#include "serv_network.h"
#include "clientsocket.h"
char buf[SIZ];
FILE *fp;
- if (CtdlAccessCheck(ac_room_aide)) return;
+ if ( (CC->room.QRflags & QR_MAILBOX) && (CC->user.usernum == atol(CC->room.QRname)) ) {
+ /* users can edit the netconfigs for their own mailbox rooms */
+ }
+ else if (CtdlAccessCheck(ac_room_aide)) return;
+
assoc_file_name(filename, sizeof filename, &CC->room, ctdl_netcfg_dir);
cprintf("%d Network settings for room #%ld <%s>\n",
LISTING_FOLLOWS,
char tempfilename[SIZ];
char filename[SIZ];
char buf[SIZ];
- FILE *fp;
+ FILE *fp, *newfp;
unbuffer_output();
- if (CtdlAccessCheck(ac_room_aide)) return;
+ if ( (CC->room.QRflags & QR_MAILBOX) && (CC->user.usernum == atol(CC->room.QRname)) ) {
+ /* users can edit the netconfigs for their own mailbox rooms */
+ }
+ else if (CtdlAccessCheck(ac_room_aide)) return;
+
CtdlMakeTempFileName(tempfilename, sizeof tempfilename);
assoc_file_name(filename, sizeof filename, &CC->room, ctdl_netcfg_dir);
}
fclose(fp);
- /* Now copy the temp file to its permanent location
- * (We use /bin/mv instead of link() because they may be on
- * different filesystems)
+ /* Now copy the temp file to its permanent location.
+ * (We copy instead of link because they may be on different filesystems)
*/
- unlink(filename);
- snprintf(buf, sizeof buf, "/bin/mv %s %s", tempfilename, filename);
begin_critical_section(S_NETCONFIGS);
- system(buf);
+ fp = fopen(tempfilename, "r");
+ if (fp != NULL) {
+ newfp = fopen(filename, "w");
+ if (newfp != NULL) {
+ while (fgets(buf, sizeof buf, fp) != NULL) {
+ fprintf(newfp, "%s", buf);
+ }
+ fclose(newfp);
+ }
+ fclose(fp);
+ }
end_critical_section(S_NETCONFIGS);
+ unlink(tempfilename);
}
snprintf(buf, sizeof buf, "[%s]", CC->room.QRname);
msg->cm_fields['U'] = strdup(buf);
sprintf(buf, "room_%s@%s", CC->room.QRname, config.c_fqdn);
- for (i=0; i<strlen(buf); ++i) {
+ for (i=0; buf[i]; ++i) {
if (isspace(buf[i])) buf[i]='_';
buf[i] = tolower(buf[i]);
}
snprintf(msg->cm_fields['R'], 256,
"room_%s@%s", CC->room.QRname,
config.c_fqdn);
- for (i=0; i<strlen(msg->cm_fields['R']); ++i) {
+ for (i=0; msg->cm_fields['R'][i]; ++i) {
if (isspace(msg->cm_fields['R'][i])) {
msg->cm_fields['R'][i] = '_';
}
snprintf(msg->cm_fields['F'], SIZ,
"room_%s@%s", CC->room.QRname,
config.c_fqdn);
- for (i=0; i<strlen(msg->cm_fields['F']); ++i) {
+ for (i=0; msg->cm_fields['F'][i]; ++i) {
if (isspace(msg->cm_fields['F'][i])) {
msg->cm_fields['F'][i] = '_';
}
/* If we wrote a digest, deliver it and then close it */
snprintf(buf, sizeof buf, "room_%s@%s",
CC->room.QRname, config.c_fqdn);
- for (i=0; i<strlen(buf); ++i) {
+ for (i=0; buf[i]; ++i) {
buf[i] = tolower(buf[i]);
if (isspace(buf[i])) buf[i] = '_';
}
unsigned char firstbyte;
unsigned char lastbyte;
- /* Validate just a little bit. First byte should be FF and
- * last byte should be 00.
- */
- memcpy(&firstbyte, &buffer[0], 1);
- memcpy(&lastbyte, &buffer[size-1], 1);
+ /* Validate just a little bit. First byte should be FF and * last byte should be 00. */
+ firstbyte = buffer[0];
+ lastbyte = buffer[size-1];
if ( (firstbyte != 255) || (lastbyte != 0) ) {
- lprintf(CTDL_ERR, "Corrupt message! Ignoring.\n");
+ lprintf(CTDL_ERR, "Corrupt message ignored. Length=%ld, firstbyte = %d, lastbyte = %d\n",
+ size, firstbyte, lastbyte);
return;
}
* connected that it's inevitable.)
*/
if (network_usetable(msg) != 0) {
+ CtdlFreeMessage(msg);
return;
}
fp = fopen(filename, "rb");
if (fp == NULL) {
- lprintf(CTDL_CRIT, "Error opening %s: %s\n",
- filename, strerror(errno));
+ lprintf(CTDL_CRIT, "Error opening %s: %s\n", filename, strerror(errno));
return;
}
- lprintf(CTDL_INFO, "network: processing <%s>\n", filename);
+ fseek(fp, 0L, SEEK_END);
+ lprintf(CTDL_INFO, "network: processing %ld bytes from %s\n", ftell(fp), filename);
+ rewind(fp);
/* Look for messages in the data stream and break them out */
while (ch = getc(fp), ch >= 0) {
* receive network spool from the remote system
*/
void receive_spool(int sock, char *remote_nodename) {
- long download_len;
- long bytes_received;
+ long download_len = 0L;
+ long bytes_received = 0L;
+ long bytes_copied = 0L;
char buf[SIZ];
static char pbuf[IGNET_PACKET_SIZE];
char tempfilename[PATH_MAX];
+ char filename[PATH_MAX];
long plen;
- FILE *fp;
+ FILE *fp, *newfp;
CtdlMakeTempFileName(tempfilename, sizeof tempfilename);
if (sock_puts(sock, "NDOP") < 0) return;
- if (sock_gets(sock, buf) < 0) return;
+ if (sock_getln(sock, buf, sizeof buf) < 0) return;
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (buf[0] != '2') {
return;
unlink(tempfilename);
return;
}
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
fclose(fp);
unlink(tempfilename);
return;
}
if (buf[0] == '6') {
plen = extract_long(&buf[4], 0);
- if (sock_read(sock, pbuf, plen) < 0) {
+ if (sock_read(sock, pbuf, plen, 1) < 0) {
fclose(fp);
unlink(tempfilename);
return;
unlink(tempfilename);
return;
}
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
unlink(tempfilename);
return;
}
- if (download_len > 0)
- lprintf(CTDL_NOTICE, "Received %ld octets from <%s>",
- download_len, remote_nodename);
- lprintf(CTDL_DEBUG, "%s", buf);
- /* TODO: make move inline. forking is verry expensive. */
- snprintf(buf,
- sizeof buf,
- "mv %s %s/%s.%ld",
- tempfilename,
+ if (download_len > 0) {
+ lprintf(CTDL_NOTICE, "Received %ld octets from <%s>\n", download_len, remote_nodename);
+ }
+ lprintf(CTDL_DEBUG, "%s\n", buf);
+
+ /* Now copy the temp file to its permanent location.
+ * (We copy instead of link because they may be on different filesystems)
+ */
+ begin_critical_section(S_NETSPOOL);
+ snprintf(filename,
+ sizeof filename,
+ "%s/%s.%ld",
ctdl_netin_dir,
remote_nodename,
- (long) getpid());
- system(buf);
+ (long) getpid()
+ );
+ fp = fopen(tempfilename, "r");
+ if (fp != NULL) {
+ newfp = fopen(filename, "w");
+ if (newfp != NULL) {
+ bytes_copied = 0L;
+ while (bytes_copied < download_len) {
+ plen = download_len - bytes_copied;
+ if (plen > sizeof buf) {
+ plen = sizeof buf;
+ }
+ fread(buf, plen, 1, fp);
+ fwrite(buf, plen, 1, newfp);
+ bytes_copied += plen;
+ }
+ fclose(newfp);
+ }
+ fclose(fp);
+ }
+ end_critical_section(S_NETSPOOL);
+ unlink(tempfilename);
}
char sfname[128];
if (sock_puts(sock, "NUOP") < 0) return;
- if (sock_gets(sock, buf) < 0) return;
+ if (sock_getln(sock, buf, sizeof buf) < 0) return;
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (buf[0] != '2') {
return;
close(fd);
return;
}
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
close(fd);
return;
}
ABORTUPL:
close(fd);
if (sock_puts(sock, "UCLS 1") < 0) return;
- if (sock_gets(sock, buf) < 0) return;
+ if (sock_getln(sock, buf, sizeof buf) < 0) return;
lprintf(CTDL_NOTICE, "Sent %ld octets to <%s>\n",
bytes_written, remote_nodename);
lprintf(CTDL_DEBUG, "<%s\n", buf);
lprintf(CTDL_DEBUG, "Connected!\n");
/* Read the server greeting */
- if (sock_gets(sock, buf) < 0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
lprintf(CTDL_DEBUG, ">%s\n", buf);
/* Identify ourselves */
snprintf(buf, sizeof buf, "NETP %s|%s", config.c_nodename, secret);
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (sock_puts(sock, buf) <0) goto bail;
- if (sock_gets(sock, buf) < 0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
lprintf(CTDL_DEBUG, ">%s\n", buf);
if (buf[0] != '2') goto bail;
*/
CTDL_MODULE_INIT(network)
{
- create_spool_dirs();
- CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config");
- CtdlRegisterProtoHook(cmd_snet, "SNET", "Set network config");
- CtdlRegisterProtoHook(cmd_netp, "NETP", "Identify as network poller");
- CtdlRegisterProtoHook(cmd_nsyn, "NSYN", "Synchronize room to node");
- CtdlRegisterSessionHook(network_do_queue, EVT_TIMER);
- CtdlRegisterRoomHook(network_room_handler);
+ if (!threading)
+ {
+ create_spool_dirs();
+ CtdlRegisterProtoHook(cmd_gnet, "GNET", "Get network config");
+ CtdlRegisterProtoHook(cmd_snet, "SNET", "Set network config");
+ CtdlRegisterProtoHook(cmd_netp, "NETP", "Identify as network poller");
+ CtdlRegisterProtoHook(cmd_nsyn, "NSYN", "Synchronize room to node");
+ CtdlRegisterSessionHook(network_do_queue, EVT_TIMER);
+ CtdlRegisterRoomHook(network_room_handler);
+ CtdlRegisterCleanupHook(destroy_network_queue_room);
+ }
/* return our Subversion id for the Log */
return "$Id$";