Sync branch with HEAD of trunk
This commit is contained in:
@@ -682,6 +682,7 @@ src/libs/nmap/Makefile
|
||||
src/libs/python/Makefile
|
||||
src/libs/python/bongo-python-wrapper
|
||||
src/libs/python/libbongo/Makefile
|
||||
src/libs/python/bongo/Makefile
|
||||
src/libs/python/bongo/Xpl.py
|
||||
src/libs/bongoutil/Makefile
|
||||
src/libs/bongoutil/tests/Makefile
|
||||
|
||||
@@ -62,8 +62,14 @@
|
||||
|
||||
#define LOGIP(X) inet_ntoa(X.sin_addr)
|
||||
|
||||
#define LogFailure(message) Log(LOG_ERROR, "Internal Failure (%s:%d) " message, __FILE__, __LINE__)
|
||||
#define LogFailureF(message, ...) Log(LOG_ERROR, "Internal Failure (%s:%d) " message, __FILE__, __LINE__, __VA_ARGS__)
|
||||
#define LogAssert(test, message) if (!(test)) { Log(LOG_ERROR, "Internal Failure (%s:%d) " message, __FILE__, __LINE__); }
|
||||
#define LogAssertF(test, message, ...) if(!(test)) { Log(LOG_ERROR, "Assert:%s:%d " message, __FILE__, __LINE__, __VA_ARGS__); }
|
||||
|
||||
#define Log(...) LogMsg(LOGGERNAME, 0, __VA_ARGS__)
|
||||
#define LogWithID(...) LogMsg(LOGGERNAME, __VA_ARGS__)
|
||||
#define LogStart() LoggerOpen(LOGGERNAME);
|
||||
#define LogStartup() log4c_init()
|
||||
#define LogShutdown() log4c_fini()
|
||||
|
||||
|
||||
+1
-1
@@ -70,7 +70,7 @@ AC_LANG(C++)
|
||||
fi
|
||||
|
||||
CLUCENE_BONGO_API=`echo "$clucene_ver" | $AWK -F. '{
|
||||
if ($ 1 > 0 || $ 2 > 9 || ($ 2 == 9 && $ 3 > 18)) {
|
||||
if ($ 1 > 0 || $ 2 > 9 || ($ 2 == 9 && $ 3 >= 17)) {
|
||||
print 2;
|
||||
} else {
|
||||
print 1;
|
||||
|
||||
@@ -103,25 +103,6 @@ static ProtocolCommand ImapProtocolCommands[] = {
|
||||
|
||||
void *IMAPConnectionPool = NULL;
|
||||
|
||||
/* Management Client Declarations */
|
||||
BOOL ReadIMAPVariable(unsigned int Variable, unsigned char *Data, size_t *DataLength);
|
||||
BOOL WriteIMAPVariable(unsigned int Variable, unsigned char *Data, size_t DataLength);
|
||||
|
||||
ManagementVariables IMAPManagementVariables[] = {
|
||||
/* 0 #define PRODUCT_VERSION */ { DMCMV_REVISIONS, DMCMV_REVISIONS_HELP, ReadIMAPVariable, NULL },
|
||||
/* 1 unsigned long Imap.session.threads.max */ { DMCMV_MAX_CONNECTION_COUNT, DMCMV_MAX_CONNECTION_COUNT_HELP, ReadIMAPVariable, WriteIMAPVariable },
|
||||
/* 2 XplAtomic IMAPServerThreads */ { DMCMV_SERVER_THREAD_COUNT, DMCMV_SERVER_THREAD_COUNT_HELP, ReadIMAPVariable, NULL },
|
||||
/* 3 XplAtomic Imap.session.threads.inUse */ { DMCMV_CONNECTION_COUNT, DMCMV_CONNECTION_COUNT_HELP, ReadIMAPVariable, NULL },
|
||||
/* 4 XplAtomic Imap.session.threads.idle */ { DMCMV_IDLE_CONNECTION_COUNT, DMCMV_IDLE_CONNECTION_COUNT_HELP, ReadIMAPVariable, NULL },
|
||||
/* 5 BOOL Imap.command.capability.acl.enabled */ { IMAPMV_ACL_ENABLED, IMAPMV_ACL_ENABLED_HELP, ReadIMAPVariable, NULL },
|
||||
/* 6 BOOL Imap.server.disabled */ { DMCMV_RECEIVER_DISABLED, DMCMV_RECEIVER_DISABLED_HELP, ReadIMAPVariable, WriteIMAPVariable },
|
||||
/* 7 unsigned char Imap.server.hostname[256] */ { DMCMV_HOSTNAME, DMCMV_HOSTNAME_HELP, ReadIMAPVariable, NULL },
|
||||
/* 8 unsigned char Imap.server.postmaster[MAXEMAILNAMESIZE + 1] */ { DMCMV_POSTMASTER, DMCMV_POSTMASTER_HELP, ReadIMAPVariable, NULL },
|
||||
/* 9 XplAtomic Imap.session.served */ { DMCMV_TOTAL_CONNECTIONS, DMCMV_TOTAL_CONNECTIONS_HELP, ReadIMAPVariable, WriteIMAPVariable },
|
||||
/* 10 XplAtomic Imap.session.badPassword */ { DMCMV_BAD_PASSWORD_COUNT, DMCMV_BAD_PASSWORD_COUNT_HELP, ReadIMAPVariable, WriteIMAPVariable },
|
||||
/* 11 unsigned char DMC Version */ { DMCMV_VERSION, DMCMV_VERSION_HELP, ReadIMAPVariable, NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
FreeReturnValueIndex(unsigned long *index)
|
||||
{
|
||||
@@ -214,389 +195,6 @@ IMAPShutdown(unsigned char *Arguments, unsigned char **Response, BOOL *CloseConn
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
IMAPDMCCommandHelp(unsigned char *Arguments, unsigned char **Response, BOOL *CloseConnection)
|
||||
{
|
||||
BOOL responded = FALSE;
|
||||
|
||||
if (Response) {
|
||||
if (Arguments) {
|
||||
switch(toupper(Arguments[0])) {
|
||||
case 'M': {
|
||||
if (XplStrNCaseCmp(Arguments, DMCMC_DUMP_MEMORY_USAGE, sizeof(DMCMC_DUMP_MEMORY_USAGE) - 1) == 0) {
|
||||
if ((*Response = MemStrdup(DMCMC_DUMP_MEMORY_USAGE_HELP)) != NULL) {
|
||||
responded = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 'C': {
|
||||
if (XplStrNCaseCmp(Arguments, DMCMC_CONN_TRACE_USAGE, sizeof(DMCMC_CONN_TRACE_USAGE) - 1) == 0) {
|
||||
if ((*Response = MemStrdup(DMCMC_CONN_TRACE_USAGE_HELP)) != NULL) {
|
||||
responded = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 'S': {
|
||||
if (XplStrNCaseCmp(Arguments, DMCMC_STATS, sizeof(DMCMC_STATS) - 1) == 0) {
|
||||
if ((*Response = MemStrdup(DMCMC_STATS_HELP)) != NULL) {
|
||||
responded = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
} else if (XplStrNCaseCmp(Arguments, DMCMC_SHUTDOWN, sizeof(DMCMC_SHUTDOWN) - 1) == 0) {
|
||||
if ((*Response = MemStrdup(DMCMC_SHUTDOWN_HELP)) != NULL) {
|
||||
responded = TRUE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if ((*Response = MemStrdup(DMCMC_HELP_HELP)) != NULL) {
|
||||
responded = TRUE;
|
||||
}
|
||||
|
||||
if (responded || ((*Response = MemStrdup(DMCMC_UNKOWN_COMMAND)) != NULL)) {
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
SendIMAPStatistics(unsigned char *Arguments, unsigned char **Response, BOOL *CloseConnection)
|
||||
{
|
||||
MemStatistics poolStats;
|
||||
|
||||
if (!Arguments && Response) {
|
||||
memset(&poolStats, 0, sizeof(MemStatistics));
|
||||
|
||||
*Response = MemMalloc(sizeof(PRODUCT_NAME) /* Long Name */
|
||||
+ sizeof(PRODUCT_SHORT_NAME) /* Short Name */
|
||||
+ 10 /* PRODUCT_MAJOR_VERSION */
|
||||
+ 10 /* PRODUCT_MINOR_VERSION */
|
||||
+ 10 /* PRODUCT_LETTER_VERSION */
|
||||
+ 10 /* Connection Pool Alloc Count */
|
||||
+ 10 /* Connection Pool Memory Usage */
|
||||
+ 10 /* Connection Pool Pitches */
|
||||
+ 10 /* Connection Pool Strikes */
|
||||
+ 10 /* DMCMV_SERVER_THREAD_COUNT */
|
||||
+ 10 /* DMCMV_CONNECTION_COUNT */
|
||||
+ 10 /* DMCMV_IDLE_CONNECTION_COUNT */
|
||||
+ 10 /* DMCMV_MAX_CONNECTION_COUNT */
|
||||
+ 10 /* DMCMV_TOTAL_CONNECTIONS */
|
||||
+ 10 /* DMCMV_BAD_PASSWORD_COUNT */
|
||||
+ 28); /* Formatting */
|
||||
|
||||
MemPrivatePoolStatistics(IMAPConnectionPool, &poolStats);
|
||||
|
||||
if (*Response) {
|
||||
sprintf(*Response, "%s (%s: v%d.%d.%d)\r\n%lu:%lu:%lu:%lu:%d:%d:%d:%lu:%d:%d\r\n",
|
||||
PRODUCT_NAME,
|
||||
PRODUCT_SHORT_NAME,
|
||||
PRODUCT_MAJOR_VERSION,
|
||||
PRODUCT_MINOR_VERSION,
|
||||
PRODUCT_LETTER_VERSION,
|
||||
poolStats.totalAlloc.count,
|
||||
poolStats.totalAlloc.size,
|
||||
poolStats.pitches,
|
||||
poolStats.strikes,
|
||||
XplSafeRead(Imap.server.active),
|
||||
XplSafeRead(Imap.session.threads.inUse),
|
||||
XplSafeRead(Imap.session.threads.idle),
|
||||
Imap.session.threads.max,
|
||||
XplSafeRead(Imap.session.served),
|
||||
XplSafeRead(Imap.session.badPassword));
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
if ((*Response = MemStrdup("Out of memory.\r\n")) != NULL) {
|
||||
return(TRUE);
|
||||
}
|
||||
} else if ((Arguments) && ((*Response = MemStrdup("Arguments not allowed.\r\n")) != NULL)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
ManagementCommands IMAPManagementCommands[] = {
|
||||
/* 0 HELP[ <IMAPCommand>] */ { DMCMC_HELP, IMAPDMCCommandHelp },
|
||||
/* 1 SHUTDOWN */ { DMCMC_SHUTDOWN, IMAPShutdown },
|
||||
/* 2 STATS */ { DMCMC_STATS, SendIMAPStatistics },
|
||||
/* 3 MEMORY */ { DMCMC_DUMP_MEMORY_USAGE, ManagementMemoryStats },
|
||||
/* 4 CONNTRACEFLAGS */ { DMCMC_CONN_TRACE_USAGE, ManagementConnTrace },
|
||||
};
|
||||
|
||||
/* Management Client Read Function */
|
||||
BOOL ReadIMAPVariable(unsigned int Variable, unsigned char *Data, size_t *DataLength)
|
||||
{
|
||||
unsigned long count;
|
||||
unsigned char *ptr;
|
||||
|
||||
switch (Variable) {
|
||||
case 0: { /* #define PRODUCT_VERSION */
|
||||
unsigned char version[30];
|
||||
|
||||
PVCSRevisionToVersion(PRODUCT_VERSION, version);
|
||||
count = strlen(version) + 11;
|
||||
|
||||
if (Data && (*DataLength > count)) {
|
||||
ptr = Data;
|
||||
|
||||
PVCSRevisionToVersion(PRODUCT_VERSION, version);
|
||||
ptr += sprintf(ptr, "imapd.c: %s\r\n", version);
|
||||
|
||||
*DataLength = ptr - Data;
|
||||
} else {
|
||||
*DataLength = count;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: { /* unsigned long Imap.session.threads.max */
|
||||
if (Data && (*DataLength > 12)) {
|
||||
sprintf(Data, "%010lu\r\n", Imap.session.threads.max);
|
||||
}
|
||||
|
||||
*DataLength = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: { /* XplAtomic IMAPServerThreads */
|
||||
if (Data && (*DataLength > 12)) {
|
||||
sprintf(Data, "%010lu\r\n", (long unsigned int)XplSafeRead(Imap.server.active));
|
||||
}
|
||||
|
||||
*DataLength = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: { /* XplAtomic Imap.session.threads.inUse */
|
||||
if (Data && (*DataLength > 12)) {
|
||||
sprintf(Data, "%010lu\r\n", (long unsigned int)XplSafeRead(Imap.session.threads.inUse));
|
||||
}
|
||||
|
||||
*DataLength = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: { /* XplAtomic Imap.session.threads.idle */
|
||||
if (Data && (*DataLength > 12)) {
|
||||
sprintf(Data, "%010lu\r\n", (long unsigned int)XplSafeRead(Imap.session.threads.idle));
|
||||
}
|
||||
|
||||
*DataLength = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: { /* BOOL Imap.command.capability.acl.enabled */
|
||||
if (Imap.command.capability.acl.enabled == FALSE) {
|
||||
ptr = "FALSE\r\n";
|
||||
count = 7;
|
||||
} else {
|
||||
ptr = "TRUE\r\n";
|
||||
count = 6;
|
||||
}
|
||||
|
||||
if (Data && (*DataLength > count)) {
|
||||
strcpy(Data, ptr);
|
||||
}
|
||||
|
||||
*DataLength = count;
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: { /* BOOL Imap.server.disabled */
|
||||
if (Imap.server.disabled == FALSE) {
|
||||
ptr = "FALSE\r\n";
|
||||
count = 7;
|
||||
} else {
|
||||
ptr = "TRUE\r\n";
|
||||
count = 6;
|
||||
}
|
||||
|
||||
if (Data && (*DataLength > count)) {
|
||||
strcpy(Data, ptr);
|
||||
}
|
||||
|
||||
*DataLength = count;
|
||||
break;
|
||||
}
|
||||
|
||||
case 7: { /* unsigned char Imap.server.hostname[256] */
|
||||
count = strlen(Imap.server.hostname) + 2;
|
||||
if (Data && (*DataLength > count)) {
|
||||
sprintf(Data, "%s\r\n", Imap.server.hostname);
|
||||
}
|
||||
|
||||
*DataLength = count;
|
||||
break;
|
||||
}
|
||||
|
||||
case 8: { /* unsigned char Imap.server.postmaster[MAXEMAILNAMESIZE + 1] */
|
||||
count = strlen(Imap.server.postmaster) + 2;
|
||||
if (Data && (*DataLength > count)) {
|
||||
sprintf(Data, "%s\r\n", Imap.server.postmaster);
|
||||
}
|
||||
|
||||
*DataLength = count;
|
||||
break;
|
||||
}
|
||||
|
||||
case 9: { /* XplAtomic Imap.session.served */
|
||||
if (Data && (*DataLength > 12)) {
|
||||
sprintf(Data, "%010lu\r\n", (long unsigned int)XplSafeRead(Imap.session.served));
|
||||
}
|
||||
|
||||
*DataLength = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
case 10: { /* XplAtomic Imap.session.badPassword */
|
||||
if (Data && (*DataLength > 12)) {
|
||||
sprintf(Data, "%010lu\r\n", (long unsigned int)XplSafeRead(Imap.session.badPassword));
|
||||
}
|
||||
|
||||
*DataLength = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
case 11: { /* unsigned char */
|
||||
DMC_REPORT_PRODUCT_VERSION(Data, *DataLength);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/* Management Client Write Function */
|
||||
BOOL WriteIMAPVariable(unsigned int Variable, unsigned char *Data, size_t DataLength)
|
||||
{
|
||||
unsigned char *ptr;
|
||||
unsigned char *ptr2;
|
||||
BOOL result = TRUE;
|
||||
|
||||
if (!Data || !DataLength) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
switch (Variable) {
|
||||
case 1: { /* unsigned long Imap.session.threads.max */
|
||||
ptr = strchr(Data, '\n');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
ptr2 = strchr(Data, '\r');
|
||||
if (ptr2) {
|
||||
ptr2 = '\0';
|
||||
}
|
||||
|
||||
Imap.session.threads.max = atol(Data);
|
||||
|
||||
if (ptr) {
|
||||
*ptr = '\n';
|
||||
}
|
||||
|
||||
if (ptr2) {
|
||||
*ptr2 = 'r';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 6: { /* BOOL Imap.server.disabled */
|
||||
if ((toupper(Data[0]) == 'T') || (atol(Data) != 0)) {
|
||||
Imap.server.disabled = TRUE;
|
||||
} else if ((toupper(Data[0] == 'F')) || (atol(Data) == 0)) {
|
||||
Imap.server.disabled = FALSE;
|
||||
} else {
|
||||
result = FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 9: { /* XplAtomic Imap.session.served */
|
||||
ptr = strchr(Data, '\n');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
ptr2 = strchr(Data, '\r');
|
||||
if (ptr2) {
|
||||
ptr2 = '\0';
|
||||
}
|
||||
|
||||
XplSafeWrite(Imap.session.served, atol(Data));
|
||||
|
||||
if (ptr) {
|
||||
*ptr = '\n';
|
||||
}
|
||||
|
||||
if (ptr2) {
|
||||
*ptr2 = 'r';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 10: { /* XplAtomic Imap.session.badPassword */
|
||||
ptr = strchr(Data, '\n');
|
||||
if (ptr) {
|
||||
*ptr = '\0';
|
||||
}
|
||||
|
||||
ptr2 = strchr(Data, '\r');
|
||||
if (ptr2) {
|
||||
ptr2 = '\0';
|
||||
}
|
||||
|
||||
XplSafeWrite(Imap.session.badPassword, atol(Data));
|
||||
|
||||
if (ptr) {
|
||||
*ptr = '\n';
|
||||
}
|
||||
|
||||
if (ptr2) {
|
||||
*ptr2 = 'r';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 0: /* #define PRODUCT_VERSION */
|
||||
case 2: /* XplAtomic IMAPServerThreads */
|
||||
case 3: /* XplAtomic Imap.session.threads.inUse */
|
||||
case 4: /* XplAtomic Imap.session.threads.idle */
|
||||
case 5: /* BOOL Imap.command.capability.acl.enabled */
|
||||
case 7: /* unsigned char Imap.server.hostname[256] */
|
||||
case 8: /* unsigned char Imap.server.postmaster[MAXEMAILNAMESIZE + 1] */
|
||||
case 11: /* DMC Version */
|
||||
default: {
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static BOOL
|
||||
IMAPSessionAllocCB(void *Buffer, void *ClientData)
|
||||
{
|
||||
@@ -4263,14 +3861,6 @@ XplServiceMain(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Management Client Startup */
|
||||
if ((ManagementInit(MSGSRV_AGENT_IMAP, Imap.directory.handle))
|
||||
&& (ManagementSetVariables(IMAPManagementVariables, sizeof(IMAPManagementVariables) / sizeof(ManagementVariables)))
|
||||
&& (ManagementSetCommands(IMAPManagementCommands, sizeof(IMAPManagementCommands) / sizeof(ManagementCommands)))) {
|
||||
XplBeginThread(&id, ManagementServer, DMC_MANAGEMENT_STACKSIZE, NULL, ccode);
|
||||
}
|
||||
|
||||
|
||||
XplStartMainThread(PRODUCT_SHORT_NAME, &id, IMAPServer, 8192, NULL, ccode);
|
||||
|
||||
XplUnloadApp(XplGetThreadID());
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "queue.h"
|
||||
|
||||
#include <xpl.h>
|
||||
#include <memmgr.h>
|
||||
#include <logger.h>
|
||||
@@ -33,7 +35,6 @@
|
||||
#include <connio.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "queue.h"
|
||||
#include "domain.h"
|
||||
#include "messages.h"
|
||||
|
||||
|
||||
+193
-155
@@ -65,6 +65,49 @@ static int HandleDSN(FILE *data, FILE *control);
|
||||
|
||||
#define MAX_CHARS_IN_PDBSEARCH 512
|
||||
|
||||
#define FOPEN_CHECK(handle, path, mode) fopen_check(&(handle), (path), (mode), __LINE__)
|
||||
FILE *
|
||||
fopen_check(FILE **handle, char *path, char *mode, int line)
|
||||
{
|
||||
LogAssertF(*handle == NULL, "File handle already open on line %d", line);
|
||||
*handle = fopen(path, mode);
|
||||
return *handle;
|
||||
}
|
||||
|
||||
#define FCLOSE_CHECK(f) fclose_check(&(f), __LINE__)
|
||||
int
|
||||
fclose_check(FILE **fh, int line)
|
||||
{
|
||||
int ret;
|
||||
ret = fclose(*fh);
|
||||
if (ret == 0) {
|
||||
*fh = NULL;
|
||||
} else {
|
||||
LogFailureF("File close failed on line %d: %d", line, errno);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define UNLINK_CHECK(path) unlink_check((path), __LINE__)
|
||||
int
|
||||
unlink_check(char *path, int line)
|
||||
{
|
||||
int ret;
|
||||
ret = unlink(path);
|
||||
LogAssertF(ret == 0, "Unable to delete file %s on line %d: %d", path, line, errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define RENAME_CHECK(oldpath, newpath) rename_check((oldpath), (newpath), __LINE__)
|
||||
int
|
||||
rename_check(const char *oldpath, const char *newpath, int line)
|
||||
{
|
||||
int ret;
|
||||
ret = rename(oldpath, newpath);
|
||||
LogAssertF(ret == 0, "Unable to rename %s to %s on line %d: %d", oldpath, newpath, line, errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
PDBSearch(char *doc, char *searchString)
|
||||
{
|
||||
@@ -236,9 +279,7 @@ SpoolEntryIDLock(unsigned long id)
|
||||
|
||||
XplSignalLocalSemaphore(Queue.spoolLocks.semaphores[SPOOL_LOCK_ARRAY_MASK & id]);
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_PQE_LOCK_FULL, LOG_INFO, 0, NULL, NULL, id, 0, NULL, 0);
|
||||
|
||||
XplConsolePrintf("bongoqueue: Unable to lock spool entry %x; table full.\r\n", (unsigned int)id);
|
||||
Log(LOG_INFO, "Unable to lock spool entry %x, table full", (unsigned int) id);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
@@ -300,7 +341,7 @@ AddPushAgent(QueueClient *client,
|
||||
int count;
|
||||
QueuePushClient *temp;
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_ADD_QUEUE_AGENT, LOG_INFO, 0, NULL, NULL, XplHostToLittle(client->conn->socketAddress.sin_addr.s_addr), queue, &port, sizeof(port));
|
||||
Log(LOG_INFO, "Adding client on host %s:%d to queue %d", LOGIP(client->conn->socketAddress), port, queue);
|
||||
|
||||
XplMutexLock(Queue.pushClients.lock);
|
||||
|
||||
@@ -317,10 +358,7 @@ AddPushAgent(QueueClient *client,
|
||||
Queue.pushClients.array = temp;
|
||||
Queue.pushClients.allocated += PUSHCLIENTALLOC;
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_NMAP_OUT_OF_MEMORY, LOG_CRITICAL, 0, "Queue", identifier, (Queue.pushClients.allocated + PUSHCLIENTALLOC) * sizeof(QueuePushClient), 0, NULL, 0);
|
||||
|
||||
XplConsolePrintf("bongoqueue: Out of memory processing user %s, mailbox %s; request size: %d bytes\r\n", "bongoqueue:AddPushAgent",
|
||||
identifier, (int)((Queue.pushClients.allocated + PUSHCLIENTALLOC) * sizeof(QueuePushClient)));
|
||||
LogFailureF("Out of memory processing mailbox %s", identifier);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
@@ -360,9 +398,9 @@ RemovePushAgentIndex(int index, BOOL force)
|
||||
|
||||
if ((Queue.pushClients.array[index].errorCount > MAX_PUSHCLIENTS_ERRORS) || force) {
|
||||
if (force) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_REREGISTER_QUEUE_AGENT, LOG_INFO, 0, NULL, NULL, XplHostToLittle(Queue.pushClients.array[index].address), Queue.pushClients.array[index].queue, &(Queue.pushClients.array[index].port), sizeof(Queue.pushClients.array[index].port));
|
||||
Log(LOG_INFO, "Reregistered queue agent");
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_REMOVED_QUEUE_AGENT, LOG_INFO, 0, NULL, NULL, XplHostToLittle(Queue.pushClients.array[index].address), Queue.pushClients.array[index].queue, &(Queue.pushClients.array[index].port), sizeof(Queue.pushClients.array[index].port));
|
||||
Log(LOG_INFO, "Removed queue agent");
|
||||
}
|
||||
|
||||
if (index < (Queue.pushClients.count - 1)) {
|
||||
@@ -520,7 +558,7 @@ DeliverToStore(NMAPConnections *list,
|
||||
(ccode = ConnFlush(nmap->conn)) == -1) {
|
||||
nmap->error = TRUE;
|
||||
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
|
||||
return DELIVER_TRY_LATER;
|
||||
}
|
||||
@@ -620,9 +658,9 @@ ProcessQueueEntry(unsigned char *entryIn)
|
||||
time_t date;
|
||||
struct sockaddr_in saddr;
|
||||
struct stat sb;
|
||||
FILE *fh;
|
||||
FILE *data;
|
||||
FILE *newFH;
|
||||
FILE *fh = NULL;
|
||||
FILE *data = NULL;
|
||||
FILE *newFH = NULL;
|
||||
MIMEReportStruct *report = NULL;
|
||||
MDBValueStruct *vs;
|
||||
QueueClient *client;
|
||||
@@ -647,12 +685,12 @@ StartOver:
|
||||
|
||||
entryID = strtol(entry, NULL, 16);
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_START, LOG_DEBUG, entryID, NULL, NULL, queue, entryID, NULL, 0);
|
||||
Log(LOG_DEBUG, "Processing entry %ld on queue %d", entryID, queue);
|
||||
|
||||
idLock = SpoolEntryIDLock(entryID);
|
||||
if (idLock) {
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
fh = fopen(path, "r+b");
|
||||
FOPEN_CHECK(fh, path, "r+b");
|
||||
} else {
|
||||
ProcessQueueEntryCleanUp(NULL, report);
|
||||
return(FALSE);
|
||||
@@ -661,7 +699,7 @@ StartOver:
|
||||
if (fh) {
|
||||
fgets(line, CONN_BUFSIZE, fh);
|
||||
date = atoi(line + 1);
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
} else {
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
return(FALSE);
|
||||
@@ -670,6 +708,7 @@ StartOver:
|
||||
/* We've got pre and post processing off queue entries - this is pre */
|
||||
switch(queue) {
|
||||
case Q_INCOMING: {
|
||||
FILE *temp = NULL;
|
||||
sb.st_size = -1;
|
||||
qDate = NULL;
|
||||
qFlags = NULL;
|
||||
@@ -678,15 +717,15 @@ StartOver:
|
||||
qFrom = NULL;
|
||||
|
||||
sprintf(path, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
newFH = fopen(path, "wb");
|
||||
FOPEN_CHECK(newFH, path, "wb");
|
||||
|
||||
sprintf(path, "%s/c%s.%03d",Conf.spoolPath, entry, queue);
|
||||
if (newFH
|
||||
&& (stat(path, &sb) == 0)
|
||||
&& (sb.st_size > 8)
|
||||
&& ((qEnvelope = (unsigned char *)MemMalloc(sb.st_size + 1)) != NULL)
|
||||
&& ((fh = fopen(path, "rb")) != NULL)
|
||||
&& (fread(qEnvelope, sizeof(unsigned char), sb.st_size, fh) == (size_t)sb.st_size)) {
|
||||
&& ((temp = fopen(path, "rb")) != NULL)
|
||||
&& (fread(qEnvelope, sizeof(unsigned char), sb.st_size, temp) == (size_t)sb.st_size)) {
|
||||
/* Sort the control file as follows:
|
||||
QUEUE_DATE
|
||||
QUEUE_FLAGS
|
||||
@@ -702,7 +741,7 @@ StartOver:
|
||||
QUEUE_RECIP_REMOTE
|
||||
QUEUE_THIRD_PARTY
|
||||
*/
|
||||
fclose(fh);
|
||||
fclose(temp);
|
||||
|
||||
qEnvelope[sb.st_size] = '\0';
|
||||
|
||||
@@ -799,15 +838,15 @@ StartOver:
|
||||
/* fixme - if a new queue entry has at least QUEUE_FROM
|
||||
but no recipients we should bounce the message rather
|
||||
than consuming it! */
|
||||
fclose(newFH);
|
||||
FCLOSE_CHECK(newFH);
|
||||
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(path, "%s/w%s.%03d",Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(path, "%s/d%s.msg",Conf.spoolPath, entry);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
MemFree(qEnvelope);
|
||||
|
||||
@@ -868,7 +907,7 @@ StartOver:
|
||||
|
||||
MDBFreeValues(vs);
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_FIND_OBJECT_FAILED, LOG_INFO, entryID, cur + 1, "", queue, 0, NULL, 0);
|
||||
Log(LOG_INFO, "Entry %ld queue %d, can't find %s", entryID, queue, cur + 1);
|
||||
|
||||
if (ptr2) {
|
||||
*ptr2 = ' ';
|
||||
@@ -925,25 +964,25 @@ StartOver:
|
||||
|
||||
MemFree(qEnvelope);
|
||||
|
||||
fclose(newFH);
|
||||
FCLOSE_CHECK(newFH);
|
||||
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(path2, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
rename(path2, path);
|
||||
RENAME_CHECK(path2, path);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!newFH) {
|
||||
sprintf(path, "%s/w%s.%03d",Conf.spoolPath, entry, queue);
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_FILE_OPEN_FAILURE, LOG_CRITICAL, entryID, path, __FILE__, __LINE__, 0, NULL, 0);
|
||||
LogFailureF("File open failure. Entry %ld, path %s", entryID, path);
|
||||
} else if (!qEnvelope) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_NMAP_OUT_OF_MEMORY, LOG_CRITICAL, entryID, __FILE__, NULL, sb.st_size, 0, NULL, 0);
|
||||
LogFailureF("Out of memory. Entry %ld, size %ld", entryID, sb.st_size);
|
||||
} else if (!fh) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_FILE_OPEN_FAILURE, LOG_CRITICAL, entryID, path, __FILE__, __LINE__, 0, NULL, 0);
|
||||
LogFailureF("File open failure. Entry %ld, path %s", entryID, path);
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_FILE_OPEN_FAILURE, LOG_CRITICAL, entryID, path, __FILE__, __LINE__, 0, NULL, 0);
|
||||
LogFailureF("Event file open failure. Entry %ld, path %s", entryID, path);
|
||||
}
|
||||
|
||||
if (qEnvelope) {
|
||||
@@ -951,17 +990,17 @@ StartOver:
|
||||
}
|
||||
|
||||
if (fh) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
|
||||
if (newFH) {
|
||||
fclose(newFH);
|
||||
FCLOSE_CHECK(newFH);
|
||||
}
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_WRITE_ERROR, LOG_WARNING, 0, "Spool", "Queue", __LINE__, 0, NULL, 0);
|
||||
Log(LOG_WARNING, "Write error in queue");
|
||||
|
||||
sprintf(path, "%s/w%s.%03d",Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
return(TRUE);
|
||||
@@ -974,7 +1013,7 @@ StartOver:
|
||||
/* We move it to the Q_RTS queue and the linger code there will bounce it for us */
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
sprintf(path2, "%s/c%s.%03d", Conf.spoolPath, entry, Q_RTS);
|
||||
rename(path, path2);
|
||||
RENAME_CHECK(path, path2);
|
||||
|
||||
sprintf(path, "%03d%s", Q_RTS, entry);
|
||||
SpoolEntryIDUnlock(idLock);
|
||||
@@ -1022,21 +1061,22 @@ StartOver:
|
||||
bounce = FALSE;
|
||||
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
fh = fopen(path, "rb");
|
||||
FOPEN_CHECK(fh, path, "rb");
|
||||
|
||||
sprintf(path, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
newFH = fopen(path, "wb");
|
||||
FOPEN_CHECK(newFH, path, "wb");
|
||||
|
||||
if (!fh || !newFH) {
|
||||
if (fh) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
|
||||
if (newFH) {
|
||||
fclose(newFH);
|
||||
FCLOSE_CHECK(newFH);
|
||||
}
|
||||
|
||||
sprintf(path, "%s/w%s.%03d",Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
return(TRUE);
|
||||
@@ -1075,8 +1115,6 @@ StartOver:
|
||||
authenticatedSender[1]='\0';
|
||||
}
|
||||
|
||||
/* LoggerEvent(NMAP.handle.logging, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_FROM, LOG_DEBUG, entryID, entry, sender, queue, 0, MIME_TEXT_PLAIN, authenticatedSender? strlen(authenticatedSender) + 1: 1, authenticatedSender? (char *)authenticatedSender: "", NULL, 0); */
|
||||
|
||||
fprintf(newFH, "%s\r\n", line);
|
||||
break;
|
||||
}
|
||||
@@ -1085,12 +1123,12 @@ StartOver:
|
||||
struct sockaddr_in siaddr;
|
||||
|
||||
if (!data) {
|
||||
data = fopen(path, "rb");
|
||||
FOPEN_CHECK(data, path, "rb");
|
||||
if (!data) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
sprintf(path, "%s/w%s.%03d",Conf.spoolPath, entry, queue);
|
||||
fclose(newFH);
|
||||
unlink(path);
|
||||
FCLOSE_CHECK(newFH);
|
||||
UNLINK_CHECK(path);
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
return(TRUE);
|
||||
}
|
||||
@@ -1117,11 +1155,10 @@ StartOver:
|
||||
|
||||
vs = MDBCreateValueStruct(Agent.agent.directoryHandle, NULL);
|
||||
if (!MsgFindObject(recipient, NULL, NULL, &siaddr, vs)) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_FIND_OBJECT_FAILED, LOG_WARNING, entryID, recipient, "", queue, 0, NULL, 0);
|
||||
|
||||
Log(LOG_WARNING, "User %s unknown, entry %ld", recipient, entryID);
|
||||
status = DELIVER_USER_UNKNOWN;
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_REMOTE_NMAP, LOG_DEBUG, entryID, entry, line + 1, queue, XplHostToLittle(siaddr.sin_addr.s_addr), NULL, 0);
|
||||
Log(LOG_DEBUG, "Delivering %s on queue %d to %s", entry, queue, line+1);
|
||||
status = DeliverToStore(&list, &siaddr, NMAP_DOCTYPE_CAL, sender, authenticatedSender, dataFilename, data, dSize, recipient, mailbox, flags);
|
||||
if (Agent.agent.state == BONGO_AGENT_STATE_STOPPING) {
|
||||
status = DELIVER_TRY_LATER;
|
||||
@@ -1135,7 +1172,7 @@ StartOver:
|
||||
}
|
||||
|
||||
if (status<DELIVER_SUCCESS) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_DELIVERY_FAILED, LOG_NOTICE, entryID, entry, NULL, queue, status, NULL, 0);
|
||||
Log(LOG_NOTICE, "Delivery failed: entry %ld, queue %d, status %d", entryID, queue, status);
|
||||
if (status==DELIVER_USER_UNKNOWN || status==DELIVER_INTERNAL_ERROR || status==DELIVER_QUOTA_EXCEEDED) {
|
||||
XplSafeIncrement(Queue.localDeliveryFailed);
|
||||
if (flags & DSN_FAILURE) {
|
||||
@@ -1191,13 +1228,13 @@ StartOver:
|
||||
struct sockaddr_in siaddr;
|
||||
if (!data) {
|
||||
sprintf(path, "%s/d%s.msg", Conf.spoolPath, entry);
|
||||
data = fopen(path, "rb");
|
||||
FOPEN_CHECK(data, path, "rb");
|
||||
if (!data) {
|
||||
fclose(fh);
|
||||
fclose(newFH);
|
||||
FCLOSE_CHECK(fh);
|
||||
FCLOSE_CHECK(newFH);
|
||||
|
||||
sprintf(path, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
return(TRUE);
|
||||
@@ -1224,7 +1261,7 @@ StartOver:
|
||||
/* Attempt delivery, check if local or remote */
|
||||
vs = MDBCreateValueStruct(Agent.agent.directoryHandle, NULL);
|
||||
if (MsgFindObject(recipient, NULL, NULL, &siaddr, vs)) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_REMOTE_NMAP, LOG_DEBUG, entryID, entry, line + 1, queue, XplHostToLittle(siaddr.sin_addr.s_addr), NULL, 0);
|
||||
Log(LOG_DEBUG, "Deliver to store entry %s in queue %d for host %s", entry, queue, LOGIP(siaddr));
|
||||
status = DeliverToStore(&list, &siaddr, NMAP_DOCTYPE_MAIL, sender, authenticatedSender, dataFilename, data, dSize, recipient, mailbox, messageFlags);
|
||||
|
||||
if (Agent.agent.state == BONGO_AGENT_STATE_STOPPING) {
|
||||
@@ -1256,7 +1293,7 @@ StartOver:
|
||||
flags = 0;
|
||||
keep = TRUE; /* recipient prevent it from getting removed */
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_FIND_OBJECT_FAILED, LOG_INFO, entryID, recipient, (authenticatedSender && (authenticatedSender[0] != '-') && (authenticatedSender[1] != ' '))? authenticatedSender: sender, queue, saddr.sin_addr.s_addr, NULL, 0);
|
||||
Log(LOG_INFO, "Can't forward undeliverable entry %ld in queue %d for user %s on host %s", entry, queue, sender, LOGIP(saddr));
|
||||
|
||||
XplRWReadLockRelease(&Conf.lock);
|
||||
}
|
||||
@@ -1265,7 +1302,7 @@ StartOver:
|
||||
MDBDestroyValueStruct(vs);
|
||||
|
||||
if (status < DELIVER_SUCCESS) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_DELIVERY_FAILED, LOG_WARNING, entryID, entry, NULL, queue, status, NULL, 0);
|
||||
Log(LOG_WARNING, "Couldn't deliver entry %s on queue %d, status %d", entry, queue, status);
|
||||
if ((status == DELIVER_USER_UNKNOWN) || (status == DELIVER_INTERNAL_ERROR) || (status == DELIVER_QUOTA_EXCEEDED)) {
|
||||
XplSafeIncrement(Queue.localDeliveryFailed);
|
||||
if (flags & DSN_FAILURE) {
|
||||
@@ -1360,7 +1397,7 @@ StartOver:
|
||||
}
|
||||
|
||||
default:
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_FIND_OBJECT_FAILED, LOG_INFO, entryID, line, entry, queue, 0, NULL, 0);
|
||||
Log(LOG_INFO, "Unknown command: %s (entry: %ld)", line, entryID);
|
||||
fprintf(newFH, "%s\r\n", line);
|
||||
break;
|
||||
}
|
||||
@@ -1370,33 +1407,33 @@ StartOver:
|
||||
EndStoreDelivery(&list);
|
||||
memset(&list, 0, sizeof(NMAPConnections));
|
||||
}
|
||||
fclose(newFH);
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(newFH);
|
||||
FCLOSE_CHECK(fh);
|
||||
if (bounce) {
|
||||
unsigned char Path2[XPL_MAX_PATH+1];
|
||||
|
||||
/* First, rename the work file into a control file */
|
||||
sprintf(path, "%s/c%s.%03d",Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
sprintf(Path2, "%s/w%s.%03d",Conf.spoolPath, entry, queue);
|
||||
rename(Path2, path);
|
||||
RENAME_CHECK(Path2, path);
|
||||
|
||||
if (!data) {
|
||||
sprintf(path, "%s/d%s.msg",Conf.spoolPath, entry);
|
||||
data=fopen(path,"rb");
|
||||
FOPEN_CHECK(data, path, "rb");
|
||||
} else {
|
||||
fseek(data, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
sprintf(path, "%s/c%s.%03d",Conf.spoolPath, entry, queue);
|
||||
fh=fopen(path,"rb");
|
||||
FOPEN_CHECK(fh, path, "rb");
|
||||
|
||||
if (fh && data && 0 == HandleDSN(data, fh)) {
|
||||
/* Now bounce the thing */
|
||||
fseek(fh, 0, SEEK_SET);
|
||||
|
||||
sprintf(path, "%s/w%s.%03d",Conf.spoolPath, entry, queue);
|
||||
newFH=fopen(path, "wb");
|
||||
FOPEN_CHECK(newFH, path, "wb");
|
||||
if (newFH) {
|
||||
/* Now remove the bounced entries */
|
||||
while (!feof(fh) && !ferror(fh)) {
|
||||
@@ -1411,42 +1448,42 @@ StartOver:
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(newFH);
|
||||
FCLOSE_CHECK(newFH);
|
||||
}
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
} else {
|
||||
if (fh) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
if (data) {
|
||||
fclose(data);
|
||||
FCLOSE_CHECK(data);
|
||||
}
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_FILE_OPEN_FAILURE, LOG_CRITICAL, entryID, path, __FILE__, __LINE__, 0, NULL, 0);
|
||||
Log(LOG_CRITICAL, "File open error for entry %ld, path: %s", entryID, path);
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
return(FALSE);
|
||||
}
|
||||
}
|
||||
if (data) {
|
||||
fclose(data);
|
||||
FCLOSE_CHECK(data);
|
||||
}
|
||||
if (keep) {
|
||||
unsigned char Path2[XPL_MAX_PATH+1];
|
||||
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(Path2, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
rename(Path2, path);
|
||||
RENAME_CHECK(Path2, path);
|
||||
} else {
|
||||
sprintf(path, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(path, "%s/d%s.msg", Conf.spoolPath, entry);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
XplSafeDecrement(Queue.queuedLocal);
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
@@ -1476,14 +1513,17 @@ StartOver:
|
||||
for (used = 0; (used < (unsigned long)Queue.pushClients.count) && (Agent.agent.state < BONGO_AGENT_STATE_STOPPING); used++) {
|
||||
if ((Queue.pushClients.array[used].queue == queue) && (Queue.pushClients.array[used].errorCount <= MAX_PUSHCLIENTS_ERRORS)) {
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
if ((stat(path, &sb) == 0) && ((fh = fopen(path, "rb")) != NULL)) {
|
||||
/* Count the number of lines */
|
||||
do {
|
||||
if (fgets(line, CONN_BUFSIZE, fh)
|
||||
&& ((line[0] == QUEUE_RECIP_REMOTE) || (line[0] == QUEUE_RECIP_LOCAL) || (line[0] == QUEUE_RECIP_MBOX_LOCAL))) {
|
||||
lines++;
|
||||
}
|
||||
} while (!feof(fh) && !ferror(fh));
|
||||
if (stat(path, &sb) == 0) {
|
||||
FOPEN_CHECK(fh, path, "rb");
|
||||
if (fh) {
|
||||
/* Count the number of lines */
|
||||
do {
|
||||
if (fgets(line, CONN_BUFSIZE, fh)
|
||||
&& ((line[0] == QUEUE_RECIP_REMOTE) || (line[0] == QUEUE_RECIP_LOCAL) || (line[0] == QUEUE_RECIP_MBOX_LOCAL))) {
|
||||
lines++;
|
||||
}
|
||||
} while (!feof(fh) && !ferror(fh));
|
||||
}
|
||||
} else {
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
return(TRUE);
|
||||
@@ -1501,9 +1541,9 @@ StartOver:
|
||||
QueueClientFree(client);
|
||||
}
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_OUT_OF_MEMORY, LOG_ERROR, entryID, __FILE__, NULL, sizeof(QueueClient), __LINE__, NULL, 0);
|
||||
LogFailureF("Cannot allocate %d bytes memory (entry %ld)", sizeof(QueueClient), entryID);
|
||||
if (fh) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
|
||||
fh = NULL;
|
||||
@@ -1536,7 +1576,7 @@ StartOver:
|
||||
QueueClientFree(client);
|
||||
|
||||
if (fh) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
|
||||
fh = NULL;
|
||||
@@ -1560,7 +1600,7 @@ StartOver:
|
||||
|
||||
Queue.pushClients.array[used].errorCount = 0;
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_FAILED_CONNECT, LOG_WARNING, entryID, entry, NULL, queue, XplHostToLittle(saddr.sin_addr.s_addr), &(Queue.pushClients.array[used].port), sizeof(Queue.pushClients.array[used].port));
|
||||
LogFailureF("Couldn't connect client %s", LOGIP(saddr));
|
||||
|
||||
ConnClose(client->conn, 0);
|
||||
ConnFree(client->conn);
|
||||
@@ -1573,7 +1613,7 @@ StartOver:
|
||||
QueueClientFree(client);
|
||||
|
||||
if (fh) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
|
||||
fh = NULL;
|
||||
@@ -1586,7 +1626,7 @@ StartOver:
|
||||
ConnWriteF(client->conn, "6020 %03d-%s %ld %ld %ld\r\n", queue, entry, (unsigned long)sb.st_size, dSize, lines);
|
||||
ConnWriteFile(client->conn, fh);
|
||||
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
fh = NULL;
|
||||
|
||||
sprintf(client->entry.workQueue, "%03d-%s", queue, entry);
|
||||
@@ -1598,7 +1638,7 @@ StartOver:
|
||||
client->entry.report = report;
|
||||
|
||||
if (!HandleCommand(client)) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_QUEUE, LOGGER_EVENT_PQE_FAILED, LOG_WARNING, entryID, entry, NULL, queue, XplHostToLittle(saddr.sin_addr.s_addr), &(Queue.pushClients.array[used].port), sizeof(Queue.pushClients.array[used].port));
|
||||
LogFailureF("Couldn't handle command on entry %s for host %s", entry, LOGIP(saddr));
|
||||
}
|
||||
|
||||
/* fixme - evaluate this section.
|
||||
@@ -1673,7 +1713,7 @@ StartOver:
|
||||
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
sprintf(path2, "%s/c%s.%03d", Conf.spoolPath, entry, i);
|
||||
rename(path, path2);
|
||||
RENAME_CHECK(path, path2);
|
||||
|
||||
sprintf(path, "%03d%s", i, entry);
|
||||
SpoolEntryIDUnlock(idLock);
|
||||
@@ -1693,7 +1733,7 @@ StartOver:
|
||||
QDBHandleRelease(handle);
|
||||
}
|
||||
|
||||
fh = fopen(path,"rb");
|
||||
FOPEN_CHECK(fh, path, "rb");
|
||||
keep = FALSE;
|
||||
if (fh) {
|
||||
do {
|
||||
@@ -1723,9 +1763,7 @@ StartOver:
|
||||
if (ptr2) {
|
||||
if ((handle = QDBHandleAlloc()) != NULL) {
|
||||
ccode = QDBAdd(handle, ptr2 + 1, entryID, queue);
|
||||
if (ccode == -1) {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_DATABASE, LOGGER_EVENT_DATABASE_INSERT_ERROR, LOG_ERROR, 0, ptr2 + 1, NULL, ccode, 0, NULL, 0);
|
||||
}
|
||||
LogAssertF(ccode != -1, "Database insert error: %s", ptr2 + 1);
|
||||
|
||||
QDBHandleRelease(handle);
|
||||
}
|
||||
@@ -1741,7 +1779,7 @@ StartOver:
|
||||
}
|
||||
}
|
||||
} while (!feof(fh) && !ferror(fh));
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
} else {
|
||||
keep = TRUE;
|
||||
}
|
||||
@@ -1750,16 +1788,16 @@ StartOver:
|
||||
if (bounce) {
|
||||
/* Call the bouncing code */
|
||||
sprintf(path2, "%s/d%s.msg", Conf.spoolPath, entry);
|
||||
data = fopen(path2, "rb");
|
||||
fh = fopen(path, "rb");
|
||||
FOPEN_CHECK(data, path2, "rb");
|
||||
FOPEN_CHECK(fh, path, "rb");
|
||||
|
||||
if (fh && data && 0 == HandleDSN(data, fh)) {
|
||||
fclose(data);
|
||||
FCLOSE_CHECK(data);
|
||||
|
||||
/* If we're not keeping the file, we can ignore its contents */
|
||||
if (keep) {
|
||||
sprintf(path2, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
newFH = fopen(path2, "wb");
|
||||
FOPEN_CHECK(newFH, path2, "wb");
|
||||
if (newFH) {
|
||||
/* Now remove the bounced entries */
|
||||
while (!feof(fh) && !ferror(fh)) {
|
||||
@@ -1777,27 +1815,27 @@ StartOver:
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fh);
|
||||
fclose(newFH);
|
||||
FCLOSE_CHECK(fh);
|
||||
FCLOSE_CHECK(newFH);
|
||||
|
||||
unlink(path);
|
||||
rename(path2, path);
|
||||
UNLINK_CHECK(path);
|
||||
RENAME_CHECK(path2, path);
|
||||
} else {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
} else {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
} else {
|
||||
if (fh) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
|
||||
if (data) {
|
||||
fclose(data);
|
||||
FCLOSE_CHECK(data);
|
||||
}
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_FILE_OPEN_FAILURE, LOG_CRITICAL, entryID, path, __FILE__, __LINE__, 0, NULL, 0);
|
||||
LogFailureF("File open failure: entry %ld, path %s", entryID, path);
|
||||
|
||||
ProcessQueueEntryCleanUp(idLock, report);
|
||||
return(TRUE);
|
||||
@@ -1807,10 +1845,10 @@ StartOver:
|
||||
if (!keep) {
|
||||
XplSafeDecrement(Queue.queuedLocal);
|
||||
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(path, "%s/d%s.msg",Conf.spoolPath, entry);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1827,13 +1865,13 @@ StartOver:
|
||||
}
|
||||
|
||||
sprintf(path, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
newFH = fopen(path, "wb");
|
||||
FOPEN_CHECK(newFH, path, "wb");
|
||||
|
||||
sprintf(path, "%s/d%s.msg", Conf.spoolPath, entry);
|
||||
data = fopen(path, "rb");
|
||||
FOPEN_CHECK(data, path, "rb");
|
||||
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
fh = fopen(path, "rb");
|
||||
FOPEN_CHECK(fh, path, "rb");
|
||||
|
||||
if (fh && newFH && data) {
|
||||
XplSafeIncrement(Queue.remoteDeliveryFailed);
|
||||
@@ -1878,42 +1916,42 @@ StartOver:
|
||||
}
|
||||
}
|
||||
|
||||
fclose(newFH);
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(newFH);
|
||||
FCLOSE_CHECK(fh);
|
||||
|
||||
/* Still got path from above */
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
sprintf(path2, "%s/w%s.%03d", Conf.spoolPath, entry, queue);
|
||||
rename(path2, path);
|
||||
RENAME_CHECK(path2, path);
|
||||
|
||||
fh = fopen(path, "rb");
|
||||
FOPEN_CHECK(fh, path, "rb");
|
||||
if (fh) {
|
||||
HandleDSN(data, fh);
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_FILE_OPEN_FAILURE, LOG_CRITICAL, entryID, path, __FILE__, __LINE__, 0, NULL, 0);
|
||||
LogFailureF("Couldn't open path %s (%ld)", path, entryID);
|
||||
}
|
||||
|
||||
fclose(data);
|
||||
FCLOSE_CHECK(data);
|
||||
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, queue);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(path, "%s/d%s.msg", Conf.spoolPath, entry);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
XplSafeDecrement(Queue.queuedLocal);
|
||||
} else {
|
||||
if (data) {
|
||||
fclose(data);
|
||||
FCLOSE_CHECK(data);
|
||||
}
|
||||
|
||||
if (fh) {
|
||||
fclose(fh);
|
||||
FCLOSE_CHECK(fh);
|
||||
}
|
||||
|
||||
if (newFH) {
|
||||
fclose(newFH);
|
||||
FCLOSE_CHECK(newFH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1923,7 +1961,7 @@ StartOver:
|
||||
count = 0;
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, entry, Q_RTS);
|
||||
sprintf(path2, "%s/c%s.%03d", Conf.spoolPath, entry, Q_INCOMING);
|
||||
rename(path, path2);
|
||||
RENAME_CHECK(path, path2);
|
||||
|
||||
sprintf(path, "%03d%s", Q_INCOMING, entry);
|
||||
}
|
||||
@@ -2443,7 +2481,7 @@ HandleDSN(FILE *data, FILE *control)
|
||||
fprintf (stderr, "could not open rtsData\n");
|
||||
fclose(rtsControl);
|
||||
sprintf(path, "%s/d%07lx.msg", Conf.spoolPath, id);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -2452,10 +2490,10 @@ HandleDSN(FILE *data, FILE *control)
|
||||
fclose(rtsData);
|
||||
|
||||
sprintf(path, "%s/d%07lx.msg", Conf.spoolPath, id);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
sprintf(path, "%s/c%07lx.%03d", Conf.spoolPath, id, Q_INCOMING);
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
SpoolEntryIDUnlock(idLock);
|
||||
return 0;
|
||||
@@ -2797,7 +2835,7 @@ CreateQueueThreads(BOOL failed)
|
||||
current++;
|
||||
CHOP_NEWLINE(path);
|
||||
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2805,7 +2843,7 @@ CreateQueueThreads(BOOL failed)
|
||||
}
|
||||
|
||||
sprintf(path, "%s/killfile", MsgGetDBFDir(NULL));
|
||||
unlink(path);
|
||||
UNLINK_CHECK(path);
|
||||
|
||||
XplCloseDir(dirP);
|
||||
|
||||
@@ -3032,7 +3070,7 @@ CommandQabrt(void *param)
|
||||
client->entry.control = NULL;
|
||||
|
||||
sprintf(client->path,"%s/c%07lx.in", Conf.spoolPath, client->entry.id);
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
}
|
||||
|
||||
if (client->entry.data) {
|
||||
@@ -3040,7 +3078,7 @@ CommandQabrt(void *param)
|
||||
client->entry.data = NULL;
|
||||
|
||||
sprintf(client->path,"%s/d%07lx.msg",Conf.spoolPath, client->entry.id);
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
}
|
||||
if (client->entry.work) {
|
||||
fclose(client->entry.work);
|
||||
@@ -3048,7 +3086,7 @@ CommandQabrt(void *param)
|
||||
|
||||
if (client->entry.workQueue[0] != '\0') {
|
||||
sprintf(client->path,"%s/w%s.%s",Conf.spoolPath, client->entry.workQueue + 4, client->entry.workQueue);
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3333,7 +3371,7 @@ CommandQcrea(void *param)
|
||||
} else {
|
||||
fclose(client->entry.control);
|
||||
sprintf(client->path, "%s/c%07lx.in", Conf.spoolPath, id);
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
|
||||
return(ConnWrite(client->conn, MSG5221SPACELOW, sizeof(MSG5221SPACELOW) - 1));
|
||||
}
|
||||
@@ -3368,10 +3406,10 @@ CommandQdele(void *param)
|
||||
LockQueueEntry(ptr+4, atoi(ptr)); */
|
||||
|
||||
sprintf(client->path, "%s/c%s.%s", Conf.spoolPath, ptr + 4, ptr);
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
|
||||
sprintf(client->path, "%s/d%s.msg", Conf.spoolPath, ptr + 4);
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
|
||||
/* FIXME: close out the file handles? */
|
||||
|
||||
@@ -3400,15 +3438,15 @@ CommandQdone(void *param)
|
||||
sprintf(client->path, "%s/w%s.%s", Conf.spoolPath, client->entry.workQueue + 4, client->entry.workQueue);
|
||||
sprintf(path, "%s/c%s.%s", Conf.spoolPath, client->entry.workQueue + 4, client->entry.workQueue);
|
||||
if ((stat(client->path, &sb1) == 0) && (stat(path, &sb2) == 0)) {
|
||||
unlink(path);
|
||||
rename(client->path, path);
|
||||
UNLINK_CHECK(path);
|
||||
RENAME_CHECK(client->path, path);
|
||||
} else {
|
||||
if (stat(client->path, &sb) == 0) {
|
||||
/* Our new queue file exists, everything still ok */
|
||||
rename(client->path, path);
|
||||
RENAME_CHECK(client->path, path);
|
||||
} else {
|
||||
/* got to keep the old one */
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3883,12 +3921,12 @@ CommandQmove(void *param)
|
||||
if (stat(client->path, &sb) == 0) {
|
||||
sprintf(path, "%s/c%s.%03d", Conf.spoolPath, ptr + 4, atoi(ptr));
|
||||
|
||||
rename(client->path, path);
|
||||
RENAME_CHECK(client->path, path);
|
||||
|
||||
ccode = ConnWrite(client->conn, MSG1000OK, sizeof(MSG1000OK) - 1);
|
||||
} else {
|
||||
sprintf(client->path, "%s/d%s.msg", Conf.spoolPath, ptr + 4);
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
|
||||
ccode = ConnWrite(client->conn, MSG4224NOENTRY, sizeof(MSG4224NOENTRY) - 1);
|
||||
}
|
||||
@@ -3953,7 +3991,7 @@ CommandQrcp(void *param)
|
||||
|
||||
sprintf(client->path,"%s/c%07lx.in",Conf.spoolPath, client->entry.id);
|
||||
sprintf(path, "%s/c%07lx.%03ld", Conf.spoolPath, client->entry.id, client->entry.target);
|
||||
rename(client->path, path);
|
||||
RENAME_CHECK(client->path, path);
|
||||
|
||||
sprintf(client->path, "%03ld%lx", client->entry.target, client->entry.id);
|
||||
|
||||
@@ -3982,7 +4020,7 @@ CommandQrcp(void *param)
|
||||
client->entry.control = NULL;
|
||||
|
||||
sprintf(client->path, "%s/c%07lx.in", Conf.spoolPath, id);
|
||||
unlink(client->path);
|
||||
UNLINK_CHECK(client->path);
|
||||
}
|
||||
|
||||
sprintf(client->path, "%s/c%07lx.in", Conf.spoolPath, client->entry.id);
|
||||
@@ -4143,7 +4181,7 @@ CommandQrun(void *param)
|
||||
|
||||
sprintf(client->path,"%s/c%07lx.in",Conf.spoolPath, client->entry.id);
|
||||
sprintf(path, "%s/c%07lx.%03ld", Conf.spoolPath, client->entry.id, client->entry.target);
|
||||
rename(client->path, path);
|
||||
RENAME_CHECK(client->path, path);
|
||||
|
||||
XplSafeIncrement(Queue.queuedLocal);
|
||||
|
||||
@@ -4213,11 +4251,11 @@ CommandQsrchDomain(void *param)
|
||||
ccode = ConnWrite(client->conn, MSG1000OK, sizeof(MSG1000OK) - 1);
|
||||
}
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_DATABASE, LOGGER_EVENT_DATABASE_FIND_ERROR, LOG_ERROR, 0, ptr, NULL, ccode, 0, NULL, 0);
|
||||
LogFailureF("Couldn't find %s in QDB", ptr);
|
||||
ccode = ConnWrite(client->conn, MSG4261NODOMAIN, sizeof(MSG4261NODOMAIN) - 1);
|
||||
}
|
||||
} else {
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_NMAP_OUT_OF_MEMORY, LOG_CRITICAL, 0, client->buffer, NULL, sizeof(MDBValueStruct), 0, NULL, 0);
|
||||
LogFailure("Out of memory");
|
||||
ccode = ConnWrite(client->conn, MSG5230NOMEMORYERR, sizeof(MSG5230NOMEMORYERR) - 1);
|
||||
}
|
||||
|
||||
@@ -4776,6 +4814,6 @@ CommandQflush(void *param)
|
||||
QueueClient *client = (QueueClient *)param;
|
||||
|
||||
Queue.flushNeeded = TRUE;
|
||||
|
||||
|
||||
return (ConnWrite(client->conn, MSG1000OK, sizeof(MSG1000OK) - 1));
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
|
||||
#include "conf.h"
|
||||
#include "queued.h"
|
||||
#include "conf.h"
|
||||
|
||||
#define SPOOL_LOCK_ARRAY_SIZE 256
|
||||
#define SPOOL_LOCK_IDARRAY_SIZE 64
|
||||
@@ -92,6 +92,11 @@ typedef struct _Queue {
|
||||
|
||||
extern MessageQueue Queue;
|
||||
|
||||
FILE * fopen_check(FILE **handle, char *path, char *mode, int line);
|
||||
int fclose_check(FILE **handle, int line);
|
||||
int unlink_check(char *path, int line);
|
||||
int rename_check(const char *oldpath, const char *newpath, int line);
|
||||
|
||||
BOOL QueueInit(void);
|
||||
void QueueShutdown(void);
|
||||
|
||||
|
||||
+16
-11
@@ -21,9 +21,11 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "queue.h"
|
||||
#include "queued.h"
|
||||
|
||||
#include <xpl.h>
|
||||
#include <memmgr.h>
|
||||
#include <logger.h>
|
||||
#include <bongoutil.h>
|
||||
#include <bongoagent.h>
|
||||
#include <mdb.h>
|
||||
@@ -32,9 +34,7 @@
|
||||
#include <msgapi.h>
|
||||
#include <connio.h>
|
||||
|
||||
#include "queued.h"
|
||||
#include "conf.h"
|
||||
#include "queue.h"
|
||||
#include "domain.h"
|
||||
#include "messages.h"
|
||||
|
||||
@@ -122,7 +122,7 @@ CommandAuth(void *param)
|
||||
return(ConnWrite(client->conn, MSG1000OK, sizeof(MSG1000OK) - 1));
|
||||
}
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_AUTH, LOGGER_EVENT_WRONG_SYSTEM_AUTH, LOG_NOTICE, 0, NULL, NULL, XplHostToLittle(client->conn->socketAddress.sin_addr.s_addr), 0, NULL, 0);
|
||||
Log(LOG_NOTICE, "SYSTEM AUTH failed from host %s", LOGIP(client->conn->socketAddress));
|
||||
|
||||
ConnWrite(client->conn, MSG3242BADAUTH, sizeof(MSG3242BADAUTH) - 1);
|
||||
|
||||
@@ -162,7 +162,7 @@ CommandPass(void *param)
|
||||
return(ConnWrite(client->conn, MSG4120USERLOCKED, sizeof(MSG4120USERLOCKED) - 1));
|
||||
}
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_AUTH, LOGGER_EVENT_WRONG_USER_AUTH, LOG_NOTICE, 0, ptr, NULL, XplHostToLittle(client->conn->socketAddress.sin_addr.s_addr), 0, NULL, 0);
|
||||
Log(LOG_NOTICE, "PASS USER failed for user from host %s", LOGIP(client->conn->socketAddress));
|
||||
} else if ( (toupper(ptr[0]) == 'S')
|
||||
&& (toupper(ptr[1]) == 'Y')
|
||||
&& (toupper(ptr[2]) == 'S')
|
||||
@@ -180,7 +180,7 @@ CommandPass(void *param)
|
||||
}
|
||||
#endif
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_AUTH, LOGGER_EVENT_WRONG_SYSTEM_AUTH, LOG_NOTICE, 0, NULL, NULL, XplHostToLittle(client->conn->socketAddress.sin_addr.s_addr), 0, NULL, 0);
|
||||
Log(LOG_NOTICE, "PASS SYSTEM failed from host %s", LOGIP(client->conn->socketAddress));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,8 +296,7 @@ HandleCommand(QueueClient *client)
|
||||
ccode = ConnWrite(client->conn, MSG3240NOAUTH, sizeof(MSG3240NOAUTH) - 1);
|
||||
}
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_UNHANDLED, LOGGER_EVENT_UNHANDLED_REQUEST, LOG_INFO, 0, "Queue",
|
||||
client->buffer, XplHostToLittle(client->conn->socketAddress.sin_addr.s_addr), 0, NULL, 0);
|
||||
Log(LOG_INFO, "Handled command from %s", LOGIP(client->conn->socketAddress));
|
||||
}
|
||||
} else if (ccode == -1) {
|
||||
break;
|
||||
@@ -444,24 +443,26 @@ CheckDiskspace(BongoAgent *agent)
|
||||
{
|
||||
unsigned long freeBlocks;
|
||||
unsigned long bytesPerBlock;
|
||||
unsigned long wantFree;
|
||||
|
||||
bytesPerBlock = XplGetDiskBlocksize(Conf.spoolPath);
|
||||
freeBlocks = XplGetDiskspaceFree(Conf.spoolPath);
|
||||
|
||||
wantFree = (Conf.minimumFree / bytesPerBlock) + 1;
|
||||
if (freeBlocks != 0x7f000000) {
|
||||
if (freeBlocks < ((Conf.minimumFree / bytesPerBlock) + 1)) {
|
||||
if (freeBlocks < wantFree) {
|
||||
/* BUG ALERT: */
|
||||
/* With a block size of 4KB, freeBlocks could */
|
||||
/* overflow if a volume had more than 16 TB. */
|
||||
|
||||
Agent.flags |= QUEUE_AGENT_DISK_SPACE_LOW;
|
||||
|
||||
LoggerEvent(Agent.agent.loggingHandle, LOGGER_SUBSYSTEM_GENERAL, LOGGER_EVENT_DISKSPACE_LOW, LOG_ERROR, 0, Conf.spoolPath, NULL, freeBlocks, (Conf.minimumFree/bytesPerBlock)+1, NULL, 0);
|
||||
Log(LOG_ERROR, "Disk space for %s low: have %ld free, want %ld.", Conf.spoolPath, freeBlocks, wantFree);
|
||||
} else {
|
||||
Agent.flags &= ~QUEUE_AGENT_DISK_SPACE_LOW;
|
||||
}
|
||||
} else {
|
||||
XplConsolePrintf("bongoqueue: The OS failed to respond to a disk space query\r\n");
|
||||
Log(LOG_NOTICE, "Couldn't work out disk space free for %s", Conf.spoolPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,6 +524,8 @@ XplServiceMain(int argc, char *argv[])
|
||||
int ccode;
|
||||
int startupOpts;
|
||||
|
||||
LogStart();
|
||||
|
||||
if (XplSetRealUser(MsgGetUnprivilegedUser()) < 0) {
|
||||
XplConsolePrintf(AGENT_NAME ": Could not drop to unprivileged user '%s'\r\n" AGENT_NAME ": exiting.\n", MsgGetUnprivilegedUser());
|
||||
return -1;
|
||||
@@ -579,6 +582,8 @@ XplServiceMain(int argc, char *argv[])
|
||||
|
||||
/* Start the server thread */
|
||||
XplStartMainThread(AGENT_NAME, &id, QueueServer, 8192, NULL, ccode);
|
||||
|
||||
LogShutdown();
|
||||
|
||||
XplUnloadApp(XplGetThreadID());
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#ifndef QUEUED_H
|
||||
#define QUEUED_H
|
||||
|
||||
#define LOGGERNAME "queue"
|
||||
|
||||
#include <xpl.h>
|
||||
#include <connio.h>
|
||||
#include <mdb.h>
|
||||
|
||||
+14
-24
@@ -1697,8 +1697,8 @@ DeliverSMTPMessage (ConnectionStruct * Client, unsigned char *Sender,
|
||||
else {
|
||||
/* The other server supports ESMTP */
|
||||
|
||||
/* Should we deliver via SSL? */
|
||||
if (AllowClientSSL && (Extensions & EXT_TLS)) {
|
||||
// SSL delivery disabled per bug #9536
|
||||
if (0 && AllowClientSSL && (Extensions & EXT_TLS)) {
|
||||
snprintf (Answer, sizeof (Answer), "STARTTLS\r\n");
|
||||
if (ConnWrite(Client->remotesmtp.conn, Answer, strlen(Answer)) < 1) {
|
||||
DELIVER_ERROR (DELIVER_TRY_LATER);
|
||||
@@ -2165,22 +2165,22 @@ DeliverRemoteMessage (ConnectionStruct * Client, unsigned char *Sender,
|
||||
|
||||
/* Clean up a potential ip address in the host name (e.g. jdoe@[1.1.1.1] ) */
|
||||
if (Host[0] == '[') {
|
||||
int host;
|
||||
ptr = strchr (Host, ']');
|
||||
if (ptr)
|
||||
*ptr = '\0';
|
||||
memmove (Host, Host + 1, strlen (Host + 1) + 1);
|
||||
/* Check for an IP address */
|
||||
int host;
|
||||
Client->remotesmtp.conn->socketAddress.sin_addr.s_addr = host;
|
||||
if ((host = inet_addr (Host)) != -1) {
|
||||
GoByAddr = TRUE;
|
||||
UsingMX = FALSE;
|
||||
}
|
||||
Client->remotesmtp.conn->socketAddress.sin_addr.s_addr = host;
|
||||
}
|
||||
|
||||
if (!GoByAddr && UseRelayHost) {
|
||||
int relayhost;
|
||||
Client->remotesmtp.conn->socketAddress.sin_addr.s_addr=relayhost;
|
||||
int relayhost = inet_addr(RelayHost);
|
||||
Client->remotesmtp.conn->socketAddress.sin_addr.s_addr = relayhost;
|
||||
if (relayhost == -1) {
|
||||
status=XplDnsResolve(RelayHost, &DNSARec, XPL_RR_A);
|
||||
/*fprintf (stderr, "%s:%d Looked up relay host %s: %d\n", __FILE__, __LINE__, RelayHost, status);*/
|
||||
@@ -3697,7 +3697,7 @@ ProcessLocalEntry (ConnectionStruct * Client, unsigned long Size,
|
||||
static void
|
||||
HandleQueueConnection (void *ClientIn)
|
||||
{
|
||||
int ReplyInt, Queue;
|
||||
int ReplyInt, Queue = Q_INCOMING;
|
||||
unsigned char Reply[1024];
|
||||
ConnectionStruct *Client = (ConnectionStruct *) ClientIn;
|
||||
unsigned char *ptr;
|
||||
@@ -5026,11 +5026,10 @@ int XplServiceMain (int argc, char *argv[])
|
||||
int ccode;
|
||||
XplThreadID ID;
|
||||
|
||||
LogStart();
|
||||
/* Done binding to ports, drop privs permanently */
|
||||
if (XplSetEffectiveUser (MsgGetUnprivilegedUser ()) < 0) {
|
||||
XplConsolePrintf
|
||||
("bongosmtp: Could not drop to unprivileged user '%s', exiting.\n",
|
||||
MsgGetUnprivilegedUser ());
|
||||
Log(LOG_ERROR, "Could not drop to unprivileged user %s", MsgGetUnprivilegedUser());
|
||||
return 1;
|
||||
}
|
||||
XplInit();
|
||||
@@ -5055,15 +5054,12 @@ int XplServiceMain (int argc, char *argv[])
|
||||
}
|
||||
else {
|
||||
MemoryManagerClose (MSGSRV_AGENT_SMTP);
|
||||
|
||||
XplConsolePrintf
|
||||
("SMTPD: Unable to create connection pool; shutting down.\r\n");
|
||||
Log(LOG_ERROR, "Unable to create connection pool, shutting down");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
XplConsolePrintf
|
||||
("SMTPD: Unable to initialize memory manager; shutting down.\r\n");
|
||||
Log(LOG_ERROR, "Unable to initialize memory manager, shutting down");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@@ -5071,10 +5067,7 @@ int XplServiceMain (int argc, char *argv[])
|
||||
|
||||
MDBInit ();
|
||||
if ((SMTPDirectoryHandle = (MDBHandle) MsgInit ()) == NULL) {
|
||||
XplBell ();
|
||||
XplConsolePrintf
|
||||
("\rSMTPD: Invalid directory credentials; exiting!\n");
|
||||
XplBell ();
|
||||
Log(LOG_ERROR, "Invalid directory credentials, shutting down");
|
||||
|
||||
MemoryManagerClose (MSGSRV_AGENT_SMTP);
|
||||
|
||||
@@ -5085,7 +5078,6 @@ int XplServiceMain (int argc, char *argv[])
|
||||
|
||||
XplRWLockInit (&ConfigLock);
|
||||
|
||||
LogStartup ();
|
||||
|
||||
for (ccode = 1; argc && (ccode < argc); ccode++) {
|
||||
if (XplStrNCaseCmp (argv[ccode], "--forwarder=", 12) == 0) {
|
||||
@@ -5097,7 +5089,7 @@ int XplServiceMain (int argc, char *argv[])
|
||||
ReadConfiguration ();
|
||||
|
||||
if (ServerSocketInit () < 0) {
|
||||
XplConsolePrintf ("bongosmtp: Exiting.\n");
|
||||
Log(LOG_WARN, "Can't open ports, exiting");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5124,9 +5116,7 @@ int XplServiceMain (int argc, char *argv[])
|
||||
|
||||
/* Done binding to ports, drop privs permanently */
|
||||
if (XplSetRealUser (MsgGetUnprivilegedUser ()) < 0) {
|
||||
XplConsolePrintf
|
||||
("bongosmtp: Could not drop to unprivileged user '%s', exiting.\n",
|
||||
MsgGetUnprivilegedUser ());
|
||||
Log(LOG_ERROR, "Could not drop to unprivileged user %s", MsgGetUnprivilegedUser());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
# -*- Makefile -*-
|
||||
sbin_PROGRAMS += bongo-config
|
||||
|
||||
conf_defaults = \
|
||||
src/apps/config/config/manager \
|
||||
src/apps/config/config/antivirus \
|
||||
src/apps/config/config/imap \
|
||||
src/apps/config/config/pop3 \
|
||||
src/apps/config/config/mailproxy \
|
||||
src/apps/config/config/antispam
|
||||
|
||||
bongo_config_SOURCES := \
|
||||
$(conf_defaults) \
|
||||
src/apps/config/config.h \
|
||||
src/apps/config/config.c
|
||||
|
||||
@@ -19,18 +28,8 @@ bongo_config_LDADD := \
|
||||
$(GNUTLS_LIBS) \
|
||||
$(ALL_LIBS)
|
||||
|
||||
conf_defaults = \
|
||||
src/apps/config/config/manager \
|
||||
src/apps/config/config/antivirus \
|
||||
src/apps/config/config/imap \
|
||||
src/apps/config/config/pop3 \
|
||||
src/apps/config/config/mailproxy \
|
||||
src/apps/config/config/antispam
|
||||
|
||||
confdir = $(pkgdatadir)/conf
|
||||
|
||||
conf_SOURCES = $(conf_defaults)
|
||||
|
||||
conf_DATA := \
|
||||
src/apps/config/default.set
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@ pkgpythonstoretool_PYTHON := \
|
||||
src/apps/storetool/bongo/storetool/CalendarCommands.py \
|
||||
src/apps/storetool/bongo/storetool/ContactCommands.py \
|
||||
src/apps/storetool/bongo/storetool/InteractiveCommands.py \
|
||||
src/apps/storetool/bongo/storetool/MailCommands.py
|
||||
src/apps/storetool/bongo/storetool/MailCommands.py \
|
||||
src/apps/storetool/bongo/storetool/ExportMailbox.py
|
||||
|
||||
src/apps/storetool/bongo-storetool: $(top_builddir)/src/libs/python/bongo-python-wrapper
|
||||
$(INSTALL) -m 755 $< $@
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
import errno
|
||||
import cStringIO
|
||||
import mailbox
|
||||
import email, email.Generator
|
||||
import sys
|
||||
|
||||
from time import time, mktime, strptime, ctime, sleep
|
||||
from rfc822 import Message, parsedate_tz, mktime_tz
|
||||
|
||||
class MboxMailbox(mailbox.PortableUnixMailbox):
|
||||
def __init__(self,file):
|
||||
mailbox.PortableUnixMailbox.__init__(self, file, email.message_from_file)
|
||||
self.boxname = file
|
||||
self.content = ""
|
||||
|
||||
def add(self, msg):
|
||||
fp = cStringIO.StringIO()
|
||||
g = email.Generator.Generator(fp, mangle_from_=False)
|
||||
envelope = email.message_from_string(msg)
|
||||
g.flatten(envelope, unixfrom=True)
|
||||
self.content += "%s" % fp.getvalue()
|
||||
|
||||
def write(self):
|
||||
outfile=file(self.boxname, "wb")
|
||||
outfile.write("%s\n" % self.content)
|
||||
outfile.close()
|
||||
|
||||
class MaildirMailbox(mailbox.Maildir):
|
||||
def __init__(self,file):
|
||||
if file[-1] == "/":
|
||||
self.boxname = file
|
||||
else:
|
||||
self.boxname = file + "/"
|
||||
|
||||
while 1:
|
||||
try:
|
||||
os.makedirs(self.boxname + "cur")
|
||||
os.makedirs(self.boxname + "new")
|
||||
os.makedirs(self.boxname + "tmp")
|
||||
except OSError, err:
|
||||
if err.errno == errno.EEXIST:
|
||||
break
|
||||
mailbox.Maildir.__init__(self, file, email.message_from_file)
|
||||
|
||||
def tmp_open(self):
|
||||
hostname = socket.gethostname()
|
||||
pid = os.getpid()
|
||||
while 1:
|
||||
name = "tmp/%.6f%05d.%s" % (time(), pid, hostname)
|
||||
try:
|
||||
os.stat(name)
|
||||
except OSError, err:
|
||||
if err.errno == errno.ENOENT:
|
||||
break
|
||||
|
||||
fd = os.open(name, os.O_WRONLY|os.O_EXCL|os.O_CREAT, 0600)
|
||||
return (name, fd)
|
||||
|
||||
|
||||
def status(self, message):
|
||||
status = message.get("Status")
|
||||
if status == "O":
|
||||
dir = "cur"
|
||||
info = ""
|
||||
elif status == "RO":
|
||||
dir = "cur"
|
||||
info = ":2,S"
|
||||
else:
|
||||
dir = "new"
|
||||
info = ""
|
||||
|
||||
return (dir, info)
|
||||
|
||||
def get_delivery_time(self, message):
|
||||
dtime = None
|
||||
if message.has_key("Date"):
|
||||
dtime = mktime_tz(parsedate_tz(message["Date"]))
|
||||
|
||||
return dtime
|
||||
|
||||
def write_message(self, raw_msg, fd, tmp):
|
||||
try:
|
||||
os.write(fd, raw_msg)
|
||||
os.fsync(fd)
|
||||
os.close(fd)
|
||||
except OSError, err:
|
||||
os.unlink(tmp)
|
||||
raise Error("unable to fsync() or close() temp file: %s" % err)
|
||||
|
||||
|
||||
def finish_message(self, tmp, dir, info, dtime):
|
||||
base_name = os.path.basename(tmp)
|
||||
dst_name = os.path.join(dir, base_name + info)
|
||||
os.link(tmp, dst_name)
|
||||
|
||||
if dtime is not None:
|
||||
atime = os.stat(dst_name).st_atime
|
||||
os.utime(dst_name, (atime, dtime))
|
||||
|
||||
return dst_name
|
||||
|
||||
def add(self, raw_msg):
|
||||
start_dir = os.getcwd()
|
||||
os.chdir(self.boxname)
|
||||
(tmp, fd) = self.tmp_open()
|
||||
|
||||
try:
|
||||
fp = cStringIO.StringIO(raw_msg)
|
||||
message = Message(fp)
|
||||
(dir, info) = self.status(message)
|
||||
dtime = self.get_delivery_time(message)
|
||||
self.write_message(raw_msg, fd, tmp)
|
||||
dst_name = self.finish_message(tmp, dir, info, dtime)
|
||||
finally:
|
||||
os.unlink(tmp)
|
||||
os.chdir(start_dir)
|
||||
@@ -3,37 +3,50 @@ import logging
|
||||
import mailbox
|
||||
import sys
|
||||
|
||||
from gettext import gettext as _
|
||||
|
||||
from bongo.cmdparse import Command
|
||||
from bongo.BongoError import BongoError
|
||||
from libbongo.libs import bongojson, msgapi
|
||||
from bongo.store.StoreClient import DocTypes, StoreClient
|
||||
from bongo.storetool.ExportMailbox import MboxMailbox, MaildirMailbox
|
||||
|
||||
class MailStoreCommand(Command):
|
||||
class MailImportCommand(Command):
|
||||
log = logging.getLogger("Bongo.StoreTool")
|
||||
|
||||
def __init__(self):
|
||||
Command.__init__(self, "mail-store", aliases=["ms"],
|
||||
summary="Store individual mail messages",
|
||||
Command.__init__(self, "mail-import", aliases=["mi"],
|
||||
summary="Import mail into the store",
|
||||
usage="%prog %cmd <file1> [<file2> ...]")
|
||||
|
||||
def ImportFile(self, store, file):
|
||||
if file == "-":
|
||||
import tempfile
|
||||
fd = tempfile.TemporaryFile(mode="w+b")
|
||||
try:
|
||||
for line in sys.stdin: fd.write(line)
|
||||
except StopIteration: pass
|
||||
fd.seek(0)
|
||||
else:
|
||||
fd = open(file)
|
||||
self.add_option("-t", "--type", type="string", default="mbox", help=_("Type of mail source [mbox or maildir], defaults to mbox"))
|
||||
self.add_option("-f", "--folder", type="string", default="INBOX", help=_("Folder to import to, defaults to INBOX"))
|
||||
|
||||
mbox = mailbox.PortableUnixMailbox(fd, email.message_from_file)
|
||||
def ImportFile(self, store, file, type, folder):
|
||||
collection = "/mail/" + folder
|
||||
store.Create(collection, existingOk=True)
|
||||
|
||||
for msg in mbox:
|
||||
if type == "mbox":
|
||||
if file == "-":
|
||||
import tempfile
|
||||
fd = tempfile.TemporaryFile(mode="w+b")
|
||||
try:
|
||||
for line in sys.stdin: fd.write(line)
|
||||
except StopIteration: pass
|
||||
fd.seek(0)
|
||||
else:
|
||||
fd = open(file)
|
||||
|
||||
mailstore = mailbox.PortableUnixMailbox(fd, email.message_from_file)
|
||||
elif type == "maildir":
|
||||
mailstore = mailbox.Maildir(file, email.message_from_file)
|
||||
|
||||
for msg in mailstore:
|
||||
data = msg.as_string(True)
|
||||
store.Write("/mail/INBOX", DocTypes.Mail, data)
|
||||
store.Write(collection, DocTypes.Mail, data)
|
||||
|
||||
fd.close()
|
||||
if fd:
|
||||
fd.close()
|
||||
|
||||
def Run(self, options, args):
|
||||
if len(args) == 0:
|
||||
@@ -45,7 +58,56 @@ class MailStoreCommand(Command):
|
||||
try:
|
||||
for file in args:
|
||||
try:
|
||||
self.ImportFile(store, file)
|
||||
self.ImportFile(store, file, options.type, options.folder)
|
||||
except IOError, e:
|
||||
print str(e)
|
||||
finally:
|
||||
store.Quit()
|
||||
|
||||
|
||||
class MailExportCommand(Command):
|
||||
log = logging.getLogger("Bongo.StoreTool")
|
||||
|
||||
def __init__(self):
|
||||
Command.__init__(self, "mail-export", aliases=["me"],
|
||||
summary="Export mail from the store",
|
||||
usage="%prog %cmd <file1> [<file2> ...]")
|
||||
|
||||
self.add_option("-t", "--type", type="string", default="mbox", help=_("Type of mail destination [mbox or maildir], defaults to mbox"))
|
||||
self.add_option("-f", "--folder", type="string", default="INBOX", help=_("Folder to export from, defaults to INBOX"))
|
||||
|
||||
def ExportFile(self, store, file, type, folder):
|
||||
collection = "/mail/" + folder
|
||||
mail_list = list(store.List(collection, ["nmap.guid"]))
|
||||
|
||||
if type == "mbox":
|
||||
mbox = MboxMailbox(file)
|
||||
for mail in mail_list:
|
||||
if mail.type != DocTypes.Mail:
|
||||
continue
|
||||
msg = store.Read(mail.props["nmap.guid"])
|
||||
mbox.add(msg)
|
||||
mbox.write()
|
||||
elif type == "maildir":
|
||||
maildir = MaildirMailbox(file)
|
||||
for mail in mail_list:
|
||||
if mail.type != DocTypes.Mail:
|
||||
continue
|
||||
msg = store.Read(mail.props["nmap.guid"])
|
||||
maildir.add(msg)
|
||||
|
||||
|
||||
def Run(self, options, args):
|
||||
if len(args) == 0:
|
||||
self.print_help()
|
||||
self.exit()
|
||||
|
||||
store = StoreClient(options.user, options.store)
|
||||
|
||||
try:
|
||||
for file in args:
|
||||
try:
|
||||
self.ExportFile(store, file, options.type, options.folder)
|
||||
except IOError, e:
|
||||
print str(e)
|
||||
finally:
|
||||
|
||||
@@ -223,7 +223,7 @@ BongoHashtableCreateFull(int buckets,
|
||||
DeleteFunction keydeletefunc, DeleteFunction valuedeletefunc)
|
||||
{
|
||||
BongoHashtable *table;
|
||||
const int size = sizeof(BongoHashtable) + buckets * sizeof(struct BongoHashtableEntry *);
|
||||
const int size = ALIGN_SIZE(sizeof(BongoHashtable), ALIGNMENT) + buckets * ALIGN_SIZE(sizeof(struct BongoHashtableEntry *), ALIGNMENT);
|
||||
|
||||
table = MemMalloc(size);
|
||||
if (!table) {
|
||||
@@ -237,7 +237,7 @@ BongoHashtableCreateFull(int buckets,
|
||||
table->keydeletefunc = keydeletefunc;
|
||||
table->valuedeletefunc = valuedeletefunc;
|
||||
|
||||
memset(&(table->buckets[0]), 0, buckets * sizeof(struct BongoHashtableEntry *));
|
||||
//memset(&(table->buckets[0]), 0, buckets * ALIGN_SIZE(sizeof(struct BongoHashtableEntry *), ALIGNMENT));
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
@@ -383,7 +383,8 @@ MdbToLdap(char *MdbDn)
|
||||
if (obj) {
|
||||
if (obj == MdbDn) {
|
||||
*obj++ = '\0';
|
||||
base = "";
|
||||
base = malloc(MDB_MAX_OBJECT_CHARS + 1);
|
||||
base[0] = '\0';
|
||||
scope = LDAP_SCOPE_BASE;
|
||||
} else {
|
||||
*obj++ = '\0';
|
||||
|
||||
@@ -145,14 +145,13 @@ pkgpythonstore_PYTHON := \
|
||||
src/libs/python/bongo/store/StoreConnection.py
|
||||
|
||||
CLEANFILES += \
|
||||
src/libs/python/bongo-python-wrapper \
|
||||
src/libs/python/bongo/*.pyc \
|
||||
src/libs/python/bongo/external/*.pyc \
|
||||
src/libs/python/bongo/external/simplejson/*.pyc \
|
||||
src/libs/python/bongo/nmap/*.pyc \
|
||||
src/libs/python/bongoy/store/*.pyc
|
||||
|
||||
src/libs/python/bongo/Xpl.py: $(top_builddir)/config.status src/libs/python/bongo/Xpl.py.in
|
||||
src/libs/python/bongo/Xpl.py: $(top_builddir)/config.status $(srcdir)/src/libs/python/bongo/Xpl.py.in
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||
|
||||
src/libs/python/bongo-python-wrapper: $(top_builddir)/config.status $(srcdir)/src/libs/python/bongo-python-wrapper.in
|
||||
|
||||
@@ -23,7 +23,8 @@ import urllib
|
||||
import traceback
|
||||
|
||||
class ConversationsHandler(ResourceHandler):
|
||||
pageSize = 30
|
||||
## Default number of items shown in a mail list view.
|
||||
defaultPageSize = 30
|
||||
|
||||
def _UpdateComposer(self, composer, jsob) :
|
||||
composer.SetAddressLine("From", jsob.get("from"))
|
||||
@@ -541,16 +542,6 @@ class ConversationsHandler(ResourceHandler):
|
||||
if resourceLen > 2 :
|
||||
rp.handlerData["attachment"] = resource.pop(0)
|
||||
|
||||
if not rp.handlerData.has_key("conversation") :
|
||||
if rp.page is None:
|
||||
start = end = -1
|
||||
else:
|
||||
start = self.pageSize * (rp.page - 1)
|
||||
end = start + self.pageSize - 1
|
||||
|
||||
rp.handlerData["start"] = start
|
||||
rp.handlerData["end"] = end
|
||||
|
||||
def ParsePath(self, rp) :
|
||||
if (rp.resource) :
|
||||
self._ParseResource(rp, rp.resource.split("/"))
|
||||
@@ -569,9 +560,18 @@ class ConversationsHandler(ResourceHandler):
|
||||
elif rp.handlerData.has_key("conversation") :
|
||||
return self._SendJson(req, self._GetConversation(store, rp, [ 1, 1, 1, 1 ]))
|
||||
else :
|
||||
if not rp.handlerData.has_key("conversation") :
|
||||
# We have to work out what IDs to start and end on with the Mail List view.
|
||||
# This involves trying to get the user's preferred pageSize, set in the DF prefs.
|
||||
if rp.page is None:
|
||||
start = end = -1
|
||||
else:
|
||||
pageSize = self._GetPageSize(store)
|
||||
start = pageSize * (rp.page - 1)
|
||||
end = start + pageSize - 1
|
||||
return self._SendJson (req, self._GetConversationList(store, rp,
|
||||
[rp.handlerData["start"], rp.handlerData["end"],
|
||||
rp.handlerData["start"], rp.handlerData["end"],
|
||||
[start, end,
|
||||
start, end,
|
||||
True]))
|
||||
finally :
|
||||
store.Quit()
|
||||
@@ -790,7 +790,7 @@ class ConversationsHandler(ResourceHandler):
|
||||
ret = {}
|
||||
if showTotal:
|
||||
ret["total"] = storeConvsIter.total
|
||||
ret["pageSize"] = self.pageSize
|
||||
ret["pageSize"] = self._GetPageSize(store)
|
||||
ret["conversations"] = convs
|
||||
|
||||
if propsStart == -1:
|
||||
@@ -931,6 +931,18 @@ class ConversationsHandler(ResourceHandler):
|
||||
|
||||
return self._SendJson(req, ret)
|
||||
|
||||
## Returns the optimum number of items to show for the mail list view.
|
||||
# @brief Looks at the Dragonfly preferences for a user-defined pageSize. If one exists, try to use it. If not, use self.defaultPageSize. This then defines how many mail items are shown per page in the mail list view.
|
||||
# @param self The object pointer.
|
||||
# @param store The store object.
|
||||
# @return Number of items to show.
|
||||
def _GetPageSize(self, store):
|
||||
try:
|
||||
prefs = self._JsonToObj(store.Read("/preferences/dragonfly"))
|
||||
return int(prefs['mail']['pageSize'])
|
||||
except:
|
||||
return self.defaultPageSize
|
||||
|
||||
class ContactsHandler(ConversationsHandler):
|
||||
groupSize = 8
|
||||
def ParsePath (self, rp) :
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from mod_python import apache, util
|
||||
from bongo.commonweb.ApacheLogHandler import ApacheLogHandler, RequestLogProxy
|
||||
from ResourcePath import ResourcePath
|
||||
from HttpError import HttpError
|
||||
from bongo.commonweb.HttpError import HttpError
|
||||
|
||||
import Auth
|
||||
import bongo.commonweb.BongoFieldStorage
|
||||
|
||||
+160
-86
@@ -280,83 +280,6 @@ Dragonfly.AddressBook.ContactPicker.prototype.newContactHandler = function (evt)
|
||||
this.popup.edit (evt, contact, this.newContactId);
|
||||
};
|
||||
|
||||
// The FakeFriendPopup manages the interaction for unknown contacts.
|
||||
Dragonfly.AddressBook.FakeFriendPopup = function (elem)
|
||||
{
|
||||
Dragonfly.PopupBuble.apply (this, arguments);
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.FakeFriendPopup.prototype = clone (Dragonfly.PopupBuble.prototype)
|
||||
Dragonfly.AddressBook.FakeFriendPopup.prototype.dispose =
|
||||
Dragonfly.AddressBook.FakeFriendPopup.prototype.disposeZone = function ()
|
||||
{
|
||||
this.hide();
|
||||
delete this.contact;
|
||||
delete this.formNames;
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.FakeFriendPopup.prototype.summarize = function (contact, elem)
|
||||
{
|
||||
var d = Dragonfly;
|
||||
|
||||
this.hide ();
|
||||
this.setClosable (true);
|
||||
this.contact = contact = (contact) ? contact : this.contact;
|
||||
|
||||
var editId = d.nextId ('person-add');
|
||||
|
||||
var html = new d.HtmlBuilder();
|
||||
html.push ('<p><b>' + contact.fn + '</b>');
|
||||
html.push ('<table><tr>');
|
||||
html.push ('<td><ul>');
|
||||
var i;
|
||||
if (contact.email) {
|
||||
html.push ('<li><a href="mailto:', contact.email, '">');
|
||||
html.push (contact.email.value, '</a>');
|
||||
}
|
||||
html.push ('</ul></td></tr></table>');
|
||||
|
||||
var loc = new d.Location ({ tab: 'mail', set:'all', handler:'contacts',
|
||||
contact: contact.bongoId });
|
||||
html.push ('<div class="actions">',
|
||||
'<a href="#', loc.getClientUrl(), '">', _('Show Conversations'), '</a>',
|
||||
'<a id="', editId, '">', _('Add'), '</a></div>');
|
||||
html.set (this.contentId);
|
||||
|
||||
Event.observe (editId, 'click', this.add.bindAsEventListener (this));
|
||||
this.showVertical (elem);
|
||||
}
|
||||
|
||||
Dragonfly.AddressBook.FakeFriendPopup.prototype.add = function ()
|
||||
{
|
||||
var AB = Dragonfly.AddressBook;
|
||||
this.serializeContact();
|
||||
this.elem.innerHTML = this.contact.fn;
|
||||
|
||||
Dragonfly.notify (_('Saving changes...'), true);
|
||||
AB.saveContact (this.contact).addCallbacks (bind (
|
||||
function (result) {
|
||||
// update preferences with contact ID
|
||||
if (this.setMyContact) {
|
||||
var id = (this.myId == '') ? result.bongoId : this.myId;
|
||||
AB.Preferences.setMyContactId (id);
|
||||
}
|
||||
|
||||
// Create sidebox element if this is a new contact
|
||||
if (result.bongoId) {
|
||||
this.contact.bongoId = result.bongoId;
|
||||
this.setElem (AB.sideboxPicker.addItem (this.contact.fn, result.bongoId));
|
||||
$(this.elem).scrollIntoView();
|
||||
}
|
||||
|
||||
Dragonfly.notify (_('Changes saved.'));
|
||||
this.summarize ();
|
||||
this.shouldAutohide = true;
|
||||
callLater (2, bind ('autohide', this));
|
||||
return result;
|
||||
}, this), bind ('showError', this));
|
||||
};
|
||||
|
||||
// The ContactPopup manages the interaction for creating and editing contacts
|
||||
Dragonfly.AddressBook.ContactPopup = function (elem)
|
||||
{
|
||||
@@ -482,14 +405,14 @@ Dragonfly.AddressBook.ContactPopup.prototype.loadContact = function ()
|
||||
|
||||
var form = $(this.formId);
|
||||
form.fn.value = this.contact.fn;
|
||||
var myId = AB.Preferences.getMyContactId();
|
||||
//var myId = AB.Preferences.getMyContactId();
|
||||
|
||||
logDebug('myID: ' + myId);
|
||||
//logDebug('myID: ' + myId);
|
||||
logDebug('form id: ' + form);
|
||||
logDebug('this.contact: ' + this.contact);
|
||||
logDebug('this.contact.fn: ' + this.contact.fn);
|
||||
|
||||
form.isMyContact.checked = myId && (myId == this.contact.bongoId);
|
||||
//form.isMyContact.checked = myId && (myId == this.contact.bongoId);
|
||||
|
||||
for (var i = 0; i < Fields.props.length; i++) {
|
||||
var prop = Fields.props[i];
|
||||
@@ -515,13 +438,13 @@ Dragonfly.AddressBook.ContactPopup.prototype.serializeContact = function ()
|
||||
var form = $(this.formId);
|
||||
contact.fn = form.fn.value;
|
||||
|
||||
if (form.isMyContact.checked) {
|
||||
/*if (form.isMyContact.checked) {
|
||||
this.setMyContact = true;
|
||||
this.myId = this.contact.bongoId || '';
|
||||
} else if (this.contact.bongoId == AB.Preferences.getMyContactId()) {
|
||||
this.setMyContact = true;
|
||||
this.myId = null;
|
||||
}
|
||||
}*/
|
||||
|
||||
// clear out existing properties
|
||||
forEach (props, function (prop) { delete contact[prop]; });
|
||||
@@ -602,8 +525,7 @@ Dragonfly.AddressBook.ContactPopup.prototype.edit = function (evt, contact, elem
|
||||
|
||||
var form = [
|
||||
'<form id="', this.formId, '"><img style="float:left; margin-right:5px;" align="middle" ',
|
||||
'src="img/contact-unknown.png"><div><p><input style="width:75%;" name="fn"><p><label>',
|
||||
'<input type="checkbox" name="isMyContact">', _('This is Me'), '</label></div>', notebook, '</form>'];
|
||||
'src="img/contact-unknown.png"><div><p><input style="width:75%;" name="fn"></div>', notebook, '</form>'];
|
||||
|
||||
var actions = [{ value: _('Cancel'), onclick: 'dispose'}, { value: _('Save'), onclick: 'save'}];
|
||||
if (this.contact.bongoId) { // only add delete for pre-existing contacts
|
||||
@@ -642,10 +564,10 @@ Dragonfly.AddressBook.ContactPopup.prototype.save = function ()
|
||||
AB.saveContact (this.contact).addCallbacks (bind (
|
||||
function (result) {
|
||||
// update preferences with contact ID
|
||||
if (this.setMyContact) {
|
||||
/*if (this.setMyContact) {
|
||||
var id = (this.myId == '') ? result.bongoId : this.myId;
|
||||
AB.Preferences.setMyContactId (id);
|
||||
}
|
||||
}*/
|
||||
|
||||
// Create sidebox element if this is a new contact
|
||||
if (result.bongoId) {
|
||||
@@ -666,6 +588,7 @@ Dragonfly.AddressBook.ContactPopup.prototype.save = function ()
|
||||
|
||||
Dragonfly.AddressBook.ContactPopup.prototype.delConfirm = function ()
|
||||
{
|
||||
var d = Dragonfly;
|
||||
this.hide();
|
||||
var text = [
|
||||
'<p>', d.format(_('Are you sure you want to delete the contact "{0}"? This cannot be undone.'),
|
||||
@@ -677,3 +600,154 @@ Dragonfly.AddressBook.ContactPopup.prototype.delConfirm = function ()
|
||||
this.show();
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.UserProfile = function (elem)
|
||||
{
|
||||
this.formId = elem;
|
||||
this.bongoId = null;
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.UserProfile.prototype = {};
|
||||
|
||||
Dragonfly.AddressBook.UserProfile.prototype.build = function (contact)
|
||||
{
|
||||
var d = Dragonfly;
|
||||
|
||||
this.contact = contact;
|
||||
|
||||
this.formNames = { };
|
||||
|
||||
var notebook = new d.Notebook();
|
||||
for (var i = 0; i < Dragonfly.AddressBook.ContactPopup.prototype.Form.length; i++) {
|
||||
var tab = d.AddressBook.ContactPopup.prototype.Form[i];
|
||||
var page = notebook.appendPage (tab.category);
|
||||
this.buildTab (new d.HtmlBuilder(), tab).set(page);
|
||||
}
|
||||
|
||||
var html = new d.HtmlBuilder ();
|
||||
html.push ('<img style="float:left; margin-right:5px;" align="middle" ',
|
||||
'src="img/contact-unknown.png"><div><p><input style="width:75%;" name="fn"></div>');
|
||||
d.HtmlBuilder.buildChild(html, notebook);
|
||||
|
||||
html.set(this.formId);
|
||||
|
||||
//var actions = [{ value: _('Save'), onclick: 'save'}];
|
||||
//Dragonfly.Preferences.Editor.buildInterface (form, actions, this.belement);
|
||||
|
||||
if (this.contact != null)
|
||||
{
|
||||
this.loadContact();
|
||||
}
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.UserProfile.prototype.loadContact = function ()
|
||||
{
|
||||
var AB = Dragonfly.AddressBook;
|
||||
var Fields = AB.ContactPopup.prototype.FieldTypes;
|
||||
|
||||
var form = $(this.formId);
|
||||
form.fn.value = this.contact.fn;
|
||||
|
||||
//logDebug('myID: ' + myId);
|
||||
|
||||
//form.isMyContact.checked = myId && (myId == this.contact.bongoId);
|
||||
|
||||
for (var i = 0; i < Fields.props.length; i++) {
|
||||
var prop = Fields.props[i];
|
||||
var values = this.contact[prop];
|
||||
if (!values) {
|
||||
continue;
|
||||
}
|
||||
for (var j = 0; j < values.length; j++) {
|
||||
var value = values[j];
|
||||
var input = this.getFreeField (AB.ContactPopup.prototype.getName (prop, value.type), false);
|
||||
if (input) {
|
||||
input.value = $V(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.UserProfile.prototype.getFreeField = function (name, asString)
|
||||
{
|
||||
if (asString) {
|
||||
var n = this.formNames[name];
|
||||
n = (n == undefined) ? 0 : n + 1;
|
||||
this.formNames[name] = n;
|
||||
return name + String (n);
|
||||
}
|
||||
return $(this.formId)[name+'0'];
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.UserProfile.prototype.buildTab = function (html, tab)
|
||||
{
|
||||
var fields = tab.fields;
|
||||
var formFields = this.formFields;
|
||||
|
||||
html.push ('<ul class="form-list">');
|
||||
for (var i = 0; i < fields.length; i++) {
|
||||
var field = fields[i];
|
||||
|
||||
var name = Dragonfly.AddressBook.ContactPopup.prototype.getName (field.prop, [tab.type, field.type]);
|
||||
name = this.getFreeField (name, true);
|
||||
html.push ('<li><label>', _(field.label), '</label>');
|
||||
if (field.longtext) {
|
||||
html.push ('<textarea name="', name, '"></textarea>');
|
||||
} else {
|
||||
html.push ('<input name="', name, '">');
|
||||
}
|
||||
html.push ('</li>');
|
||||
}
|
||||
html.push ('</ul>');
|
||||
return html;
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.UserProfile.prototype.save = function ()
|
||||
{
|
||||
var AB = Dragonfly.AddressBook;
|
||||
this.name = this.contact.fn;
|
||||
this.serializeContact();
|
||||
//this.elem.innerHTML = this.contact.fn;
|
||||
|
||||
AB.saveContact (this.contact).addCallbacks (bind (
|
||||
function (result) {
|
||||
// update preferences with contact ID
|
||||
if (result.bongoId)
|
||||
{
|
||||
this.bongoId = result.bongoId;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.bongoId = AB.Preferences.getMyContactId();
|
||||
}
|
||||
|
||||
return result;
|
||||
}, this));
|
||||
};
|
||||
|
||||
Dragonfly.AddressBook.UserProfile.prototype.serializeContact = function ()
|
||||
{
|
||||
var AB = Dragonfly.AddressBook;
|
||||
var props = AB.ContactPopup.prototype.FieldTypes.props;
|
||||
var contact = this.contact;
|
||||
var form = $(this.formId);
|
||||
contact.fn = form.fn.value;
|
||||
|
||||
// clear out existing properties
|
||||
forEach (props, function (prop) { delete contact[prop]; });
|
||||
|
||||
for (var name in this.formNames) { // for each type of field
|
||||
var count = this.formNames[name];
|
||||
var components = name.split ('-');
|
||||
var prop = components[0];
|
||||
var types = components.slice(1);
|
||||
|
||||
for (var i = 0; i <= count; i++) { // for each field
|
||||
var value = form[name+String(i)].value;
|
||||
if (value && value != '') {
|
||||
var proparray = contact[prop] || [ ];
|
||||
proparray.push ({value:value, type:types});
|
||||
contact[prop] = proparray;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -65,17 +65,11 @@ Dragonfly.Calendar.BongoCalendar.prototype.parseJSON = function (jsob)
|
||||
{
|
||||
var d = Dragonfly;
|
||||
|
||||
// TODO: This is really nasty.
|
||||
function calColor (calname)
|
||||
{
|
||||
return {
|
||||
'Personal': 'blue',
|
||||
'Red Sox': 'red',
|
||||
'US Holidays': 'orange',
|
||||
'Holidays': 'orange',
|
||||
'The Moon': 'gray',
|
||||
'Novell': 'red',
|
||||
'openSUSE': 'green',
|
||||
'Meetings': 'brown'
|
||||
}[calname] || d.getRandomColor();
|
||||
}
|
||||
@@ -95,7 +89,6 @@ Dragonfly.Calendar.BongoCalendar.prototype.parseJSON = function (jsob)
|
||||
|
||||
this.subscriptionUrl = "/user/" + d.userName + "/calendar/" + d.escapeHTML(this.cal.name) + "/events";
|
||||
|
||||
/*
|
||||
// this should probably trust the server...
|
||||
switch (this.type) {
|
||||
case 'personal':
|
||||
@@ -112,7 +105,6 @@ Dragonfly.Calendar.BongoCalendar.prototype.parseJSON = function (jsob)
|
||||
this.cal.username = jsob.username;
|
||||
break;
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
Dragonfly.Calendar.BongoCalendar.prototype.refresh = function ()
|
||||
|
||||
@@ -1038,7 +1038,7 @@ Dragonfly.Calendar.CalendarInvitationPopup.prototype.deleteClicked = function (e
|
||||
var d = Dragonfly;
|
||||
|
||||
var loc = new d.Location ({ tab: 'mail', conversation: this.invite.convId, message: this.invite.bongoId });
|
||||
d.notify (_('genericSavingChanges'), true);
|
||||
d.notify (_('Saving changes...'), true);
|
||||
d.request ('POST', loc, { method: 'delete' }).addCallbacks (
|
||||
bind ('disposeAndReload', this),
|
||||
bind ('showError', this));
|
||||
@@ -1049,7 +1049,7 @@ Dragonfly.Calendar.CalendarInvitationPopup.prototype.junkClicked = function (evt
|
||||
var d = Dragonfly;
|
||||
|
||||
var loc = new d.Location ({ tab: 'mail', conversation: this.invite.convId, message: this.invite.bongoId });
|
||||
d.notify (_('genericSavingChanges'), true);
|
||||
d.notify (_('Saving changes...'), true);
|
||||
d.request ('POST', loc, { method: 'junk' }).addCallbacks (
|
||||
bind ('disposeAndReload', this),
|
||||
bind ('showError', this));
|
||||
@@ -1059,7 +1059,7 @@ Dragonfly.Calendar.CalendarInvitationPopup.prototype.ignoreClicked = function (e
|
||||
{
|
||||
var d = Dragonfly;
|
||||
var loc = new d.Location ({ tab: 'mail', conversation: this.invite.convId, message: this.invite.bongoId });
|
||||
d.notify (_('genericSavingChanges'), true);
|
||||
d.notify (_('Saving changes...'), true);
|
||||
var req = d.request ('POST', loc, { method: 'archive' }).addCallbacks (
|
||||
bind ('disposeAndReload', this),
|
||||
bind ('showError', this));
|
||||
|
||||
+18
-18
@@ -130,7 +130,7 @@ Dragonfly.Mail.Composer.prototype.buildHtml = function (html)
|
||||
'<input id="', this.bcc, '" class="bcc" type="text" value="', escapeRecips (this.msg.bcc), '">',
|
||||
'<div id="autocomplete-', this.bcc, '" class="autocompletions"></td></tr>',
|
||||
|
||||
'<tr><th>', _('Subject:'), '</th><td><input id="', this.subject, '" class="subject" value="', d.escapeHTML (this.msg.subject || ''), '"></td></tr>',
|
||||
'<tr><th>', _('Subject:'), '</th><td><input id="', this.subject, '" class="subject" value="', d.escapeHTML (this.msg.subject || _('Untitled')), '"></td></tr>',
|
||||
'<tr><th>', _('From:'), '</th><td id="', this.from, '" class="from">', d.escapeHTML (this.msg.from), '</td></tr>',
|
||||
'<tr><th>', _('Attachments:'), '</th><td class="attachments"><ul>');
|
||||
|
||||
@@ -154,7 +154,7 @@ Dragonfly.Mail.Composer.prototype.buildHtml = function (html)
|
||||
}
|
||||
}
|
||||
|
||||
html.push ('<li><a id="', this.addAttachment, '">', _('mailAttachLabel'), '</a></li></ul>',
|
||||
html.push ('<li><a id="', this.addAttachment, '">', _('Attach file...'), '</a></li></ul>',
|
||||
'<tr><td colspan="2"><textarea id="', this.body, '" class="body" cols="75" rows="15" wrap="on">',
|
||||
d.escapeHTML (this.msg.body), '</textarea></td></tr>',
|
||||
'<tr class="action"><td id="', this.toolbar, '" colspan="2">',
|
||||
@@ -284,9 +284,13 @@ Dragonfly.Mail.Composer.prototype.saveDraft = function (evt, msg)
|
||||
return false;
|
||||
}
|
||||
|
||||
//msg = msg || this.getCurrentMessage ();
|
||||
msg = this.getCurrentMessage();
|
||||
|
||||
msg = msg;
|
||||
if (!msg || !msg.from)
|
||||
{
|
||||
logDebug('Arg passed was an event, not a real message.');
|
||||
msg = this.getCurrentMessage();
|
||||
}
|
||||
|
||||
if (!this.hasChanges (msg)) {
|
||||
logDebug ('No changes to save');
|
||||
return true;
|
||||
@@ -302,6 +306,13 @@ Dragonfly.Mail.Composer.prototype.saveDraft = function (evt, msg)
|
||||
conversation: this.conversation,
|
||||
message: this.bongoId
|
||||
};
|
||||
|
||||
/*if (!msg.subject)
|
||||
{
|
||||
var untitled = _('Untitled');
|
||||
this.subject = untitled;
|
||||
msg.subject = untitled
|
||||
}*/
|
||||
|
||||
loc = new d.Location (loc);
|
||||
this.def = d.requestJSONRPC ((this.draftSavedAlready ? 'update' : 'create') + 'Draft', loc,
|
||||
@@ -310,23 +321,12 @@ Dragonfly.Mail.Composer.prototype.saveDraft = function (evt, msg)
|
||||
this.forward || null,
|
||||
this.calendarInvitationFor || null,
|
||||
this.useAuthUrls || false);
|
||||
|
||||
var displaysubject = '';
|
||||
if (msg.subject)
|
||||
{
|
||||
displaysubject = d.escapeHTML (msg.subject);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg.subject = _('Untitled');
|
||||
displaysubject = d.escapeHTML (msg.subject);
|
||||
}
|
||||
|
||||
d.notify (d.format (_('Saving draft "{0}"...'), displaysubject), true);
|
||||
d.notify (d.format (_('Saving draft "{0}"...'), d.escapeHTML (msg.subject)), true);
|
||||
|
||||
return this.def.addCallbacks (
|
||||
bind (function (jsob) {
|
||||
d.notify (_('Saved draft') + ' "' + displaysubject + '".');
|
||||
d.notify (_('Saved draft') + ' "' + d.escapeHTML (msg.subject) + '".');
|
||||
this.draftSavedAlready = true;
|
||||
this.lastSavedMsg = msg;
|
||||
|
||||
|
||||
+44
-15
@@ -1,6 +1,6 @@
|
||||
Dragonfly = {
|
||||
title: 'Bongo',
|
||||
version: 'SVN r2483+',
|
||||
version: 'M3',
|
||||
userName: '',
|
||||
tabs: { },
|
||||
NAME: 'Dragonfly'
|
||||
@@ -342,11 +342,13 @@ Dragonfly.go = function (path)
|
||||
}
|
||||
d.contentIFrameZone.disposeZone();
|
||||
|
||||
//logDebug (startDate + ': Loading ', path, ':', serializeJSON (loc));
|
||||
//logDebug (' from: ', d.currentView);
|
||||
//logDebug (' location: ', window.location);
|
||||
//logDebug (' hash: ', window.location.hash);
|
||||
//logDebug (' loc: ', serializeJSON(loc));
|
||||
/*logDebug (startDate + ': Loading ', path, ':', serializeJSON (loc));
|
||||
logDebug (' from: ', d.currentView);
|
||||
logDebug (' location: ', window.location);
|
||||
logDebug (' hash: ', window.location.hash);
|
||||
logDebug (' loc: ', serializeJSON(loc));*/
|
||||
|
||||
logDebug('curLoc: ', loc);
|
||||
|
||||
if (!loc || !loc.valid) {
|
||||
logError ('invalid path: ' + path);
|
||||
@@ -368,10 +370,22 @@ Dragonfly.go = function (path)
|
||||
}
|
||||
|
||||
prof.toggle ('request');
|
||||
logDebug('checking if ' + loc.handler + ' contains function getData(loc)...');
|
||||
if (h.getData) {
|
||||
logDebug('Yup!');
|
||||
self.def = h.getData (loc);
|
||||
} else {
|
||||
self.def = d.requestJSON ('GET', loc);
|
||||
logDebug('Nope! Checking if ' + loc.tab + ' contains function getData(loc)...');
|
||||
if (v.getData)
|
||||
{
|
||||
logDebug('Yup!');
|
||||
self.def = v.getData(loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
logDebug('Nope!');
|
||||
self.def = d.requestJSON ('GET', loc);
|
||||
}
|
||||
}
|
||||
|
||||
self.def.loc = loc;
|
||||
@@ -923,16 +937,13 @@ Dragonfly.start = function ()
|
||||
d.translateElements();
|
||||
|
||||
d.setLoginMessage (_('Logged in: loading contacts and calendars...'));
|
||||
|
||||
// setup the preferences dialog tabs
|
||||
//d.setupPrefs();
|
||||
|
||||
|
||||
// set current timezone to default and build timezone selector
|
||||
d.curTzid = c.Preferences.getDefaultTimezone();
|
||||
//d.tzselector = new d.TzSelector (d.curTzid, 'tzselect', true);
|
||||
//d.tzselector.setChangeListener (function () { d.setCurrentTzid (d.tzselector.getTzid()); });
|
||||
|
||||
var def = new d.MultiDeferred ([ c.loadCalendars(),
|
||||
/*var def = new d.MultiDeferred ([ c.loadCalendars(),
|
||||
d.AddressBook.sideboxPicker.load() ]);*/
|
||||
var def = new DeferredList ([ c.loadCalendars(),
|
||||
d.AddressBook.sideboxPicker.load() ]);
|
||||
return def.addCallbacks (
|
||||
function (res) {
|
||||
@@ -950,9 +961,13 @@ Dragonfly.start = function ()
|
||||
$('login-user').value = '';
|
||||
$('login-password').value = '';
|
||||
Element.setText ('user-name', d.userName);
|
||||
Element.setHTML ('logout-text', _('Log out') + ' ' + d.userName);
|
||||
Element.setHTML ('logout-text', d.format(_('Log out {0}...'), d.userName));
|
||||
Dragonfly.logoutMessage = _('You have logged out successfully.');
|
||||
showElement ('content');
|
||||
|
||||
// Listen for clicks to main content thing, so we can hide popups.
|
||||
Event.observe ('content', 'click', Dragonfly.hidePopups.bindAsEventListener(this));
|
||||
|
||||
// Add administration link if we're admin
|
||||
if (d.userName == 'admin')
|
||||
{
|
||||
@@ -1016,6 +1031,20 @@ Dragonfly.initHtmlZones = function ()
|
||||
Event.observe (window, 'unload', bind ('disposeZone', d.contentZone));
|
||||
};
|
||||
|
||||
Dragonfly.hidePopups = function ()
|
||||
{
|
||||
if (Dragonfly.lastPopup)
|
||||
{
|
||||
Dragonfly.lastPopup.dispose();
|
||||
logDebug('Attempted popup dispose complete.');
|
||||
Dragonfly.lastPopup = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
logDebug('Nothing to dispose');
|
||||
}
|
||||
}
|
||||
|
||||
Dragonfly.main = function ()
|
||||
{
|
||||
Dragonfly.browserDetect();
|
||||
|
||||
+1
-1
@@ -110,7 +110,6 @@ Dragonfly.translateLogin = function ()
|
||||
Element.setHTML ('login-language-label', _('Language'));
|
||||
Element.setHTML ('login-default-label', _('Remember me'));
|
||||
$('login-button').value = _('Login');
|
||||
Dragonfly.logoutMessage = _('You have logged out successfully.');
|
||||
};
|
||||
|
||||
Dragonfly.languageSuccess = function ()
|
||||
@@ -193,6 +192,7 @@ Dragonfly.showLoginPane = function ()
|
||||
|
||||
if (location.hash == '#LoggedOut') {
|
||||
Dragonfly.setLoginMessage (Dragonfly.logoutMessage);
|
||||
Dragonfly.langFaliure = true; // Stops us from removing the 'You have logged out' message when we load the lang.
|
||||
location.hash = (Dragonfly.isWebkit) ? '' : '#';
|
||||
$('login-user').focus();
|
||||
} else {
|
||||
|
||||
+98
-13
@@ -8,15 +8,34 @@ Dragonfly.tabs['mail'] = Dragonfly.Mail;
|
||||
Dragonfly.Mail.handlers = { };
|
||||
Dragonfly.Mail.sets = [ 'all', 'inbox', 'starred', 'sent', 'drafts', 'trash', 'junk' ];
|
||||
Dragonfly.Mail.setLabels = {
|
||||
'all': 'All',
|
||||
'inbox': 'Inbox',
|
||||
'starred': 'Starred',
|
||||
'sent': 'Sent',
|
||||
'drafts': 'Drafts',
|
||||
'trash': 'Trash',
|
||||
'junk': 'Junk'
|
||||
'all': N_('All'),
|
||||
'inbox': N_('Inbox'),
|
||||
'starred': N_('Starred'),
|
||||
'sent': N_('Sent'),
|
||||
'drafts': N_('Drafts'),
|
||||
'trash': N_('Trash'),
|
||||
'junk': N_('Junk')
|
||||
};
|
||||
|
||||
Dragonfly.Mail.getData = function (loc)
|
||||
{
|
||||
logDebug('Dragonfly.Mail.getData(loc) called.');
|
||||
var d = Dragonfly;
|
||||
var m = d.Mail;
|
||||
|
||||
var view = m.getView(loc);
|
||||
if (view.getData)
|
||||
{
|
||||
logDebug('loc ', loc, ' has a getView function.');
|
||||
return view.getData(loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
logDebug('No getView function - falling back to requestJSON.');
|
||||
return d.requestJSON ('GET', loc);
|
||||
}
|
||||
}
|
||||
|
||||
Dragonfly.Mail.getView = function (loc)
|
||||
{
|
||||
logDebug('Dragonfly.Mail.getView(loc) called.');
|
||||
@@ -82,8 +101,11 @@ Dragonfly.Mail.Preferences.getFromAddress = function ()
|
||||
{
|
||||
var d = Dragonfly;
|
||||
var p = d.Preferences;
|
||||
|
||||
return p.prefs.mail.from;
|
||||
|
||||
var emailfrom = p.prefs.mail.from;
|
||||
var namefrom = p.prefs.mail.sender;
|
||||
|
||||
return d.format("{0} <{1}>", namefrom, emailfrom);
|
||||
};
|
||||
|
||||
Dragonfly.Mail.Preferences.setFromAddress = function (address)
|
||||
@@ -411,7 +433,7 @@ Dragonfly.Mail.joinParticipants = function (parts)
|
||||
}, parts).join (', ');
|
||||
};
|
||||
|
||||
Dragonfly.Mail.Conversations = { label: 'Conversations' };
|
||||
Dragonfly.Mail.Conversations = { label: N_('Conversations') };
|
||||
Dragonfly.Mail.handlers['conversations'] = Dragonfly.Mail.Conversations;
|
||||
|
||||
Dragonfly.Mail.Conversations.parseArgs = function (loc, args)
|
||||
@@ -561,7 +583,7 @@ Dragonfly.Mail.Messages.load = function (loc, jsob)
|
||||
};
|
||||
*/
|
||||
|
||||
Dragonfly.Mail.Contacts = { label: 'Contacts' };
|
||||
Dragonfly.Mail.Contacts = { label: N_('Contacts') };
|
||||
Dragonfly.Mail.handlers['contacts'] = Dragonfly.Mail.Contacts;
|
||||
|
||||
Dragonfly.Mail.Contacts.parseArgs = function (loc, args)
|
||||
@@ -664,7 +686,7 @@ Dragonfly.Mail.Contacts.getBreadCrumbs = function (loc)
|
||||
}
|
||||
};
|
||||
|
||||
Dragonfly.Mail.Subscriptions = { label: 'Mailing Lists' };
|
||||
Dragonfly.Mail.Subscriptions = { label: N_('Mailing Lists') };
|
||||
Dragonfly.Mail.handlers['subscriptions'] = Dragonfly.Mail.Subscriptions;
|
||||
|
||||
Dragonfly.Mail.Subscriptions.parseArgs = function (loc, args)
|
||||
@@ -777,7 +799,7 @@ Dragonfly.Mail.Subscriptions.getBreadCrumbs = function (loc)
|
||||
}
|
||||
};
|
||||
|
||||
Dragonfly.Mail.ToMe = { label: 'To Me' };
|
||||
Dragonfly.Mail.ToMe = { label: N_('To Me') };
|
||||
Dragonfly.Mail.handlers['tome'] = Dragonfly.Mail.ToMe;
|
||||
|
||||
Dragonfly.Mail.ToMe.parseArgs = function (loc, args)
|
||||
@@ -855,3 +877,66 @@ Dragonfly.Mail.ToMe.load = function (loc, jsob)
|
||||
|
||||
return v.load (loc, jsob);
|
||||
};
|
||||
|
||||
Dragonfly.Mail.yeahBaby = function (msg)
|
||||
{
|
||||
var d = Dragonfly;
|
||||
|
||||
if (!d.Preferences.prefs.mail.colorQuotes)
|
||||
{
|
||||
return d.htmlizeText (msg);
|
||||
}
|
||||
|
||||
// Split the message up by newlines.
|
||||
msg = msg.split("\n");
|
||||
|
||||
var colors = new Array();
|
||||
|
||||
// Loop through and find quotes.
|
||||
for (i=0;i<msg.length;i++)
|
||||
{
|
||||
// Check if it starts with >
|
||||
if (msg[i].substring(0, 1) == ">")
|
||||
{
|
||||
// Loop and find out how deep we are.
|
||||
var depth = 0;
|
||||
for (x=0;x<msg[i].length;x++)
|
||||
{
|
||||
if (msg[i][x] == '>')
|
||||
{
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
var color = '';
|
||||
if (colors.length < depth)
|
||||
{
|
||||
color = d.getRandomColor();
|
||||
|
||||
// Make sure the color isn't the same as parent quote.
|
||||
if (colors.length > 0)
|
||||
{
|
||||
while (color == colors[depth - 1])
|
||||
{
|
||||
color = d.getRandomColor();
|
||||
}
|
||||
}
|
||||
|
||||
// Push it onto the array to get later if needed.
|
||||
colors.push(color);
|
||||
}
|
||||
else
|
||||
{
|
||||
color = colors[depth - 1];
|
||||
}
|
||||
|
||||
msg[i] = '<span style="color: ' + color + ';">' + d.htmlizeText (msg[i]) + '</span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
msg[i] = d.htmlizeText (msg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return msg.join("<br />");
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ Dragonfly.Mail.ConversationView.selectAlternative = function (part)
|
||||
{
|
||||
var favorite = null;
|
||||
|
||||
//logDebug('checking alternatives');
|
||||
logDebug('checking alternatives');
|
||||
for (var i = 0; i < part.children.length; i++) {
|
||||
var child = part.children[i];
|
||||
if (child.preview && (child.previewtype == 'text/plain'
|
||||
@@ -63,7 +63,16 @@ Dragonfly.Mail.ConversationView.formatPart = function (loc, msg, part)
|
||||
if (part.preview) {
|
||||
html.push ('<div class="msg-body">');
|
||||
if (part.previewtype == 'text/plain') {
|
||||
html.push (d.htmlizeText (part.preview));
|
||||
html.push ('<div style="font-family:\'DejaVu Sans Mono\', \'Bitstream Vera Sans Mono\', \'Monaco\', \'Courier\', monospace;">');
|
||||
if (d.Preferences.prefs.mail.colorQuotes)
|
||||
{
|
||||
html.push (m.yeahBaby (part.preview));
|
||||
}
|
||||
else
|
||||
{
|
||||
html.push (d.htmlizeText (part.preview));
|
||||
}
|
||||
html.push ('</div>');
|
||||
} else if (part.previewtype == 'text/html') {
|
||||
html.push (d.linkifyHtml (part.preview));
|
||||
} else {
|
||||
@@ -91,7 +100,7 @@ Dragonfly.Mail.ConversationView.formatPart = function (loc, msg, part)
|
||||
html.push (v.formatPart(loc, msg, child));
|
||||
} else {
|
||||
if (!inAttachments) {
|
||||
html.push ('<div class="msg-attachments"><b>Attachments:</b><ul>');
|
||||
html.push ('<div class="msg-attachments"><b>', _('Attachments:'), '</b><ul>');
|
||||
inAttachments = 1;
|
||||
}
|
||||
var partLoc = new d.Location (loc);
|
||||
|
||||
@@ -73,6 +73,7 @@ Dragonfly.Mail.ListView.load = function (loc, jsob)
|
||||
var force = false;
|
||||
|
||||
var html = new d.HtmlBuilder ('<div class="scrollv" id="mail-list-wrapper">');
|
||||
var pageSize = m.Preferences.getPageSize ();
|
||||
|
||||
document.title = _(loc.set) + ' - ' + _(loc.tab) + ': ' + Dragonfly.title;
|
||||
|
||||
@@ -104,7 +105,7 @@ Dragonfly.Mail.ListView.load = function (loc, jsob)
|
||||
list.buildEnd (html);
|
||||
|
||||
new d.Pager (html, pageFmt,
|
||||
loc.page, Math.ceil (jsob.total / jsob.pageSize));
|
||||
loc.page, Math.ceil (jsob.total / pageSize));
|
||||
|
||||
html.push ('</div>');
|
||||
html.set ('content-iframe');
|
||||
@@ -137,7 +138,7 @@ Dragonfly.Mail.MultiListView.getData = function (loc)
|
||||
var m = d.Mail;
|
||||
|
||||
var pageSize = m.Preferences.getPageSize ();
|
||||
|
||||
|
||||
var propsStart = ((loc.page || 1) - 1) * pageSize;
|
||||
|
||||
return d.requestJSONRPC ('getConversationList', loc,
|
||||
@@ -160,6 +161,7 @@ Dragonfly.Mail.MultiListView.load = function (loc, jsob)
|
||||
loc = new d.Location (loc);
|
||||
|
||||
var html = new d.HtmlBuilder ('<div class="scrollv" id="mail-list-wrapper">');
|
||||
var pageSize = m.Preferences.getPageSize ();
|
||||
|
||||
document.title = _(loc.set) + ' - ' + _(loc.tab) + ': ' + Dragonfly.title;
|
||||
|
||||
@@ -199,7 +201,7 @@ Dragonfly.Mail.MultiListView.load = function (loc, jsob)
|
||||
|
||||
pageFmt = loc.getClientUrl ('handler') + '/page{0}';
|
||||
|
||||
new d.Pager (html, pageFmt, loc.page, Math.ceil (jsob.total / jsob.pageSize));
|
||||
new d.Pager (html, pageFmt, loc.page, Math.ceil (jsob.total / pageSize));
|
||||
|
||||
html.push ('</div>');
|
||||
html.set ('content-iframe');
|
||||
|
||||
@@ -124,9 +124,16 @@ Dragonfly.Calendar.OccurrencePopup.prototype.edit = function (evt, occurrence, e
|
||||
this.setClosable (false);
|
||||
delete this.changes; // may be set if we're editing after a save but before dispose
|
||||
if (occurrence) {
|
||||
this.occurrence = (typeof occurrence == 'string')
|
||||
? d.JCal.buildNewEvent (occurrence).occurrences[0]
|
||||
: occurrence;
|
||||
if (!occurrence.pageX)
|
||||
{
|
||||
this.occurrence = (typeof occurrence == 'string')
|
||||
? d.JCal.buildNewEvent (occurrence).occurrences[0]
|
||||
: occurrence;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Rebuild the event?
|
||||
}
|
||||
} else if (!this.occurrence) {
|
||||
this.occurrence = d.JCal.buildNewEvent ().occurrences[0];
|
||||
}
|
||||
@@ -277,7 +284,7 @@ Dragonfly.Calendar.OccurrencePopup.prototype.getScope = function (forSave)
|
||||
'<label><input type="radio" name="scope">', _('all events in series'), '</label>',
|
||||
'</form>'];
|
||||
var actions = [
|
||||
{ value: _('genericCancel'), onclick: 'dispose'},
|
||||
{ value: _('Cancel'), onclick: 'dispose'},
|
||||
{ value: forSave ? _('Save') : _('Delete'), onclick: partial (this.dispatchWithScope, forSave) }];
|
||||
this.setForm (form, actions);
|
||||
this.show();
|
||||
@@ -377,7 +384,7 @@ Dragonfly.Calendar.OccurrenceEditor.prototype.buildSharingTab = function (page)
|
||||
var c = d.Calendar;
|
||||
|
||||
var html = new d.HtmlBuilder (
|
||||
_('includeEventLabel'),
|
||||
_('Include this event in:'),
|
||||
'<ul id="', this.calendarsId, '" class="scrollv" style="max-height: 8em">');
|
||||
|
||||
var calIds = this.occurrence.vcalendar.calendarIds;
|
||||
|
||||
+140
-75
@@ -32,6 +32,9 @@ Dragonfly.Preferences.defaultPrefs = {
|
||||
addressbook: {
|
||||
me: null
|
||||
},
|
||||
mail: {
|
||||
colorQuotes: true
|
||||
},
|
||||
calendar: {
|
||||
dayStart: 7,
|
||||
defaultView: 'month',
|
||||
@@ -238,79 +241,90 @@ Dragonfly.Preferences.Editor.parsePath = function (loc, path)
|
||||
Dragonfly.Preferences.Editor.build = function (loc)
|
||||
{
|
||||
var d = Dragonfly;
|
||||
var showmethemoney = true;
|
||||
|
||||
Element.setHTML ('toolbar', '');
|
||||
Element.hide ('toolbar');
|
||||
|
||||
var html = new d.HtmlBuilder ();
|
||||
// First, build the container.
|
||||
html.push ('<div id="preferences-container">', '</div>');
|
||||
html.set ('content-iframe');
|
||||
|
||||
if (!showmethemoney)
|
||||
{
|
||||
// Push the following HTML if we haven't completed our handler!
|
||||
html.push ('<div id="search-no-results" class="scrollv">', '<table style="margin: auto;"><tr>',
|
||||
'<td><img src="img/big-info.png" style="float: left;" /></td>',
|
||||
'<td style="vertical-align:middle;"><h3>The Preferences editor goes here! <code>:)</code></h3></td>',
|
||||
'</tr></table></div>');
|
||||
|
||||
html.set ('content-iframe');
|
||||
}
|
||||
else
|
||||
{
|
||||
// First, build the container.
|
||||
html.push ('<div id="preferences-container">', '</div>');
|
||||
html.set ('content-iframe');
|
||||
|
||||
// Come up with some magic tabs!
|
||||
var notebook = new d.Notebook();
|
||||
var userpage = notebook.appendPage('About Me');
|
||||
var composerpage = notebook.appendPage('Mail');
|
||||
var calendarpage = notebook.appendPage('Calendar');
|
||||
|
||||
var userhtml = new d.HtmlBuilder ();
|
||||
userhtml.push ('<table border="0" cellspacing="0">',
|
||||
'<tr><td><label>Name:</label></td>',
|
||||
'<td><input type="text"></td></tr>',
|
||||
'<tr><td><label>Timezone:</label></td>',
|
||||
'<td><span id="tzpicker"></span></td></tr>',
|
||||
'</table>');
|
||||
userhtml.set (userpage);
|
||||
|
||||
var composerhtml = new d.HtmlBuilder ();
|
||||
composerhtml.push ('<table border="0" cellspacing="0">',
|
||||
'<tr><td><label>', _('From address:'), '</label></td>',
|
||||
'<td><input type="text" id="from" /></td></tr>',
|
||||
'<tr><td colspan="2"><span style="font-size: 80%;">Please don\'t abuse the above feature for now.</span></td></tr>',
|
||||
'<tr><td><label>', _('Auto BCC:'), '</label></td>',
|
||||
'<td><input type="text" id="autobcc" /></td></tr>',
|
||||
'<tr><td><label>', _('Signature:'), '</label></td>',
|
||||
'<td><textarea rows="3" cols="30" id="signature"></textarea><br />',
|
||||
'<input type="checkbox" id="usesig" name="usesig" /><label for="usesig">', _('Apply signature to outgoing mail'), '</label>',
|
||||
'</td></tr>',
|
||||
'<tr><td><label>', _('Show HTML messages:'), '</label></td>',
|
||||
'<td><select id="htmlmsg"><option value="show">', _('Yes'), '</option><option value="ptext">', _('Prefer plain-text'), '</option><option value="hide">', _('No'), '</option></select></td></tr>',
|
||||
'<tr><td><label>', _('Page size:'), '</label></td>',
|
||||
'<td><input type="text" style="width: 20px;" id="mailpagesize"> ', _('items'), '</td></tr>',
|
||||
'</table>');
|
||||
composerhtml.set (composerpage);
|
||||
|
||||
var calendarhtml = new d.HtmlBuilder ();
|
||||
calendarhtml.push ('<p>Nothing to see here, move along.</p>');
|
||||
calendarhtml.set (calendarpage);
|
||||
|
||||
var form = [
|
||||
'<form id="someid">', notebook, '</form>'];
|
||||
|
||||
var actions = [{ value: _('Cancel'), onclick: 'dispose'}, { value: _('Save'), onclick: 'save'}];
|
||||
|
||||
// Now, fill in the content with tabs & buttons.
|
||||
this.contentId = 'preferences-container';
|
||||
this.buildInterface (form, actions);
|
||||
logDebug('Created UI OK - setting up TzSelector widget...');
|
||||
|
||||
// Setup timezone widget
|
||||
d.tzselector = new d.TzSelector (d.curTzid, 'tzpicker', true);
|
||||
}
|
||||
// Come up with some magic tabs!
|
||||
var notebook = new d.Notebook();
|
||||
var userpage = notebook.appendPage('General');
|
||||
var mailpage = notebook.appendPage('Mail');
|
||||
var calendarpage = notebook.appendPage('Calendar');
|
||||
var composerpage = notebook.appendPage('Composer');
|
||||
|
||||
var userhtml = new d.HtmlBuilder ();
|
||||
userhtml.push ('<table border="0" cellspacing="0">',
|
||||
'<tr><td><label>', _('Profile:'), '</td><td><form id="userprofile">', '</form></td></tr>',
|
||||
'<tr><td><label>', _('Timezone:'), '</label></td>',
|
||||
'<td><span id="tzpicker"></span></td></tr>',
|
||||
'</table>');
|
||||
userhtml.set (userpage);
|
||||
|
||||
var mailhtml = new d.HtmlBuilder ();
|
||||
mailhtml.push ('<table border="0" cellspacing="0">',
|
||||
'<tr><td><label for="from">', _('From address:'), '</label></td>',
|
||||
'<td><input type="text" id="from" name="from" /></td></tr>',
|
||||
'<tr><td colspan="2"><span style="font-size: 80%;">Please don\'t abuse the above feature for now.</span></td></tr>',
|
||||
'<tr><td><label for="autobcc">', _('Auto BCC:'), '</label></td>',
|
||||
'<td><input type="text" name="autobcc" id="autobcc" /></td></tr>',
|
||||
'<tr><td><label for="signature">', _('Signature:'), '</label></td>',
|
||||
'<td><textarea rows="3" cols="30" name="signature" id="signature"></textarea><br />',
|
||||
'<input type="checkbox" id="usesig" name="usesig" /><label for="usesig">', _('Apply signature to outgoing mail'), '</label>',
|
||||
'</td></tr>',
|
||||
'<tr><td><label for="htmlmsg">', _('Show HTML messages:'), '</label></td>',
|
||||
'<td><select id="htmlmsg" name="htmlmsg"><option value="show">', _('Yes'), '</option><option value="ptext">', _('Prefer plain-text'), '</option><option value="hide">', _('No'), '</option></select></td></tr>',
|
||||
'<tr><td><label for="mailpagesize">', _('Page size:'), '</label></td>',
|
||||
'<td><input type="text" style="width: 20px;" name="mailpagesize" id="mailpagesize"> ', _('items'), '</td></tr>',
|
||||
'<tr><td colspan="2"><input type="checkbox" id="colorquotes" name="colorquotes" checked /><label for="colorquotes">', _('Colorize quotes in plain-text messages.'), '</label></td>',
|
||||
'</table>');
|
||||
mailhtml.set (mailpage);
|
||||
|
||||
var calendarhtml = new d.HtmlBuilder ();
|
||||
calendarhtml.push ('<table border="0" cellspacing="0">',
|
||||
'<tr><td><label for="defaultcalview">', _('Default view:'), '</label></td>',
|
||||
'<td><select name="defaultcalview" id="defaultcalview">',
|
||||
'<option value="month">', _('Month'), '</option>',
|
||||
'<option value="week">', _('Week'), '</option>',
|
||||
'<option value="upcoming">', _('Upcoming'), '</option>',
|
||||
'<option value="day">', _('Day'), '</option>',
|
||||
'</select></td></tr>',
|
||||
'<tr><td><label>', _('Share with others by default?'), '</label></td>',
|
||||
'<input type="radio" name="calshare" value="public" id="calshareyes"><label for="calshareyes">Yes</label> ',
|
||||
'<input type="radio" name="calshare" value="private" id="calshareno"><label for="calshareno">No</label>',
|
||||
'</td></tr>',
|
||||
// '<tr><td><label>Day start:</label></td>',
|
||||
// '<td><input type="text" style="width: 20px;" id="daystart" value="7"></td></tr>',
|
||||
'</table>');
|
||||
calendarhtml.set (calendarpage);
|
||||
|
||||
var composerhtml = new d.HtmlBuilder();
|
||||
composerhtml.push('<table border="0" cellspacing="0">',
|
||||
'<tr><td><label for="defaultcompose">', _('Default message format:'), '</label></td>',
|
||||
'<td><select name="defaultcompose" id="defaultcompose">',
|
||||
'<option value="html">', _('HTML'), '</option>',
|
||||
'<option value="text">', _('Plain-text'), '</option>',
|
||||
'</select></td></tr>',
|
||||
'<tr><td><label for="linewidth">', _('Line width:'), '</label></td>',
|
||||
'<td><input type="text" id="linewidth" name="linewidth" style="width: 20px;"></td></tr>',
|
||||
'</table>');
|
||||
composerhtml.set(composerpage);
|
||||
|
||||
var form = [
|
||||
'<form id="someid">', notebook, '</form>'];
|
||||
|
||||
var actions = [{ value: _('Cancel'), onclick: 'dispose'}, { value: _('Save'), onclick: 'save'}];
|
||||
|
||||
// Now, fill in the content with tabs & buttons.
|
||||
this.buildInterface (form, actions, 'preferences-container');
|
||||
logDebug('Created UI OK - setting up TzSelector widget...');
|
||||
|
||||
// Setup timezone widget
|
||||
d.tzselector = new d.TzSelector (d.curTzid, 'tzpicker', true);
|
||||
|
||||
logDebug('We just got built.');
|
||||
};
|
||||
@@ -321,17 +335,36 @@ Dragonfly.Preferences.Editor.save = function ()
|
||||
var d = Dragonfly;
|
||||
var p = d.Preferences;
|
||||
|
||||
// User profile
|
||||
Dragonfly.notify (_('Saving changes...'), true);
|
||||
var result = this.profileEditor.save();
|
||||
p.prefs.addressbook.me = this.profileEditor.bongoId;
|
||||
p.prefs.mail.sender = this.profileEditor.name;
|
||||
|
||||
// Timezone
|
||||
d.setCurrentTzid (d.tzselector.getTzid());
|
||||
|
||||
// Mail prefs
|
||||
p.prefs.mail.from = $('from').value;
|
||||
p.prefs.mail.autoBcc = $('autobcc').value;
|
||||
p.prefs.mail.pageSize = $('mailpagesize').value;
|
||||
p.prefs.mail.signature = $('signature').value;
|
||||
p.prefs.mail.usesig = $('usesig').checked;
|
||||
p.prefs.mail.colorQuotes = $('colorquotes').checked;
|
||||
|
||||
// Calendar prefs
|
||||
p.prefs.calendar.defaultView = $('defaultcalview').value;
|
||||
p.prefs.calendar.dayStart = 7; // Yes, hardwire this one (for now)!
|
||||
p.prefs.calendar.sharePublicDefault = $('calshareyes').checked;
|
||||
|
||||
// Composer prefs
|
||||
p.prefs.composer = {};
|
||||
p.prefs.composer.messageType = $('defaultcompose');
|
||||
p.prefs.composer.lineWidth = $('linewidth');
|
||||
|
||||
// Finish up
|
||||
p.save();
|
||||
Dragonfly.notify (_('Changes saved.'));
|
||||
this.dispose();
|
||||
};
|
||||
|
||||
@@ -350,17 +383,49 @@ Dragonfly.Preferences.Editor.load = function (loc, jsob)
|
||||
document.title = 'Preferences: ' + Dragonfly.title;
|
||||
|
||||
// Mail prefs
|
||||
$('from').value = jsob.mail.from;
|
||||
if (jsob.mail && jsob.mail.from)
|
||||
{
|
||||
$('from').value = jsob.mail.from;
|
||||
}
|
||||
else
|
||||
{
|
||||
logWarning('You have no prefs. I should probably warn you, or.. something.');
|
||||
}
|
||||
|
||||
if (jsob.mail.autoBcc) { $('autobcc').value = jsob.mail.autoBcc; }
|
||||
if (jsob.mail.pageSize) { $('mailpagesize').value = jsob.mail.pageSize; }
|
||||
if (jsob.mail.signature) { $('signature').value = jsob.mail.signature; }
|
||||
if (jsob.mail.usesig) { $('usesig').checked = jsob.mail.usesig; }
|
||||
if (jsob.mail && jsob.mail.autoBcc) { $('autobcc').value = jsob.mail.autoBcc; }
|
||||
if (jsob.mail && jsob.mail.pageSize) { $('mailpagesize').value = jsob.mail.pageSize; }
|
||||
if (jsob.mail && jsob.mail.signature) { $('signature').value = jsob.mail.signature; }
|
||||
if (jsob.mail && jsob.mail.usesig) { $('usesig').checked = jsob.mail.usesig; }
|
||||
if (jsob.mail && jsob.mail.colorQuotes) { $('colorquotes').checked = jsob.mail.colorQuotes; }
|
||||
|
||||
// Calendar prefs
|
||||
if (jsob.calendar && jsob.calendar.defaultView) { $('defaultcalview').value = jsob.calendar.defaultView; }
|
||||
if (jsob.calendar && jsob.calendar.sharePublicDefault) { $('calshareyes').checked = jsob.calendar.sharePublicDefault; $('calshareno').checked = !jsob.calendar.sharePublicDefault } else { $('calshareno').checked = true; }
|
||||
//if (jsob.calendar.dayStart) { $('daystart').value = jsob.calendar.dayStart; }
|
||||
|
||||
// Composer prefs
|
||||
if (jsob.composer && jsob.composer.messageType) { $('defaultcompose').value = jsob.composer.messageType; }
|
||||
if (jsob.composer && jsob.composer.lineWidth) { $('linewidth').value = jsob.composer.lineWidth ; } else { $('linewidth').value = '80'; }
|
||||
|
||||
// Now, load up the profile editor!
|
||||
var pe = new d.AddressBook.UserProfile('userprofile');
|
||||
if (jsob.addressbook.me && jsob.addressbook.me != null)
|
||||
{
|
||||
// We've already setup our profile - load it!
|
||||
d.AddressBook.loadContact(jsob.addressbook.me).addCallback(bind ('build', pe));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Build empty profile editor UI.
|
||||
pe.build(Dragonfly.AddressBook.buildNewContact());
|
||||
}
|
||||
|
||||
this.profileEditor = pe;
|
||||
|
||||
logDebug('We just loaded.');
|
||||
};
|
||||
|
||||
Dragonfly.Preferences.Editor.buildInterface = function (children, actions, observer)
|
||||
Dragonfly.Preferences.Editor.buildInterface = function (children, actions, element)
|
||||
{
|
||||
var d = Dragonfly;
|
||||
|
||||
@@ -375,11 +440,11 @@ Dragonfly.Preferences.Editor.buildInterface = function (children, actions, obser
|
||||
}
|
||||
html.push ('</div>');
|
||||
|
||||
html.set (this.contentId);
|
||||
html.set (element);
|
||||
for (var i = 0; i < actions.length; i++){
|
||||
logDebug('Setting up actions for ' + actions[i].value);
|
||||
var clickHandler = actions[i].onclick;
|
||||
Event.observe (ids[i], 'click', bind (clickHandler, observer || this));
|
||||
Event.observe (ids[i], 'click', bind (clickHandler, this));
|
||||
logDebug('Done!');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -325,7 +325,7 @@ Dragonfly.Summary.addCalInvites = function (loc, jsob)
|
||||
var cal = s.calInvites[bongoId];
|
||||
html.push ('<li><a bongoid="', bongoId, '">',
|
||||
d.escapeHTML (cal.calendarName),
|
||||
' ', _('summaryInviteFrom'), ' ',
|
||||
' ', _('from'), ' ',
|
||||
d.escapeHTML (cal.from[0][0]),
|
||||
'</a></li>');
|
||||
}
|
||||
|
||||
+1
-1
@@ -905,7 +905,7 @@ Dragonfly.requestJSONRPC = function (rpcMethod, url /*, ... */)
|
||||
return d.requestJSON ('POST', url, jsob).addCallback (d.getJsonRpcResult);
|
||||
};
|
||||
|
||||
Dragonfly.Colors = [ 'yellow', 'orange', 'brown', 'red', 'gray', 'green', 'blue', 'indigo', 'violet' ];
|
||||
Dragonfly.Colors = [ 'brown', 'red', 'gray', 'green', 'blue', 'indigo', 'maroon', 'navy', 'olive', 'purple', 'MidnightBlue', 'DimGrey', 'DarkSlateGrey', 'teal', 'SlateBlue', 'SeaGreen', 'Sienna', 'DarkGoldenRod', 'BlueViolet' ];
|
||||
Dragonfly.getRandomColor = function ()
|
||||
{
|
||||
return Dragonfly.Colors[Math.floor ((Math.random() * 100) % Dragonfly.Colors.length)];
|
||||
|
||||
@@ -361,6 +361,7 @@ Dragonfly.PopupBuble.prototype.connectHtml = function (elem)
|
||||
this.dispose();
|
||||
}
|
||||
}.bindAsEventListener(this));
|
||||
|
||||
return elem;
|
||||
};
|
||||
|
||||
@@ -378,6 +379,7 @@ Dragonfly.PopupBuble.prototype.addPoppedOut = function ()
|
||||
{
|
||||
if (this.elem) {
|
||||
addElementClass (this.elem, 'popped-out');
|
||||
//Dragonfly.lastPopup = this;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -560,7 +562,7 @@ Dragonfly.PopupBuble.prototype.show = function (elem, position)
|
||||
}
|
||||
if (!this.elem) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.addPoppedOut ();
|
||||
|
||||
@@ -621,7 +623,7 @@ Dragonfly.PopupBuble.prototype.show = function (elem, position)
|
||||
}
|
||||
|
||||
$(this.id).style.visibility = 'visible';
|
||||
|
||||
|
||||
return;
|
||||
logDebug ('positioning summary:');
|
||||
logDebug (' elemMetrics:', repr (elemMetrics));
|
||||
|
||||
Reference in New Issue
Block a user