Sync branch with HEAD of trunk

This commit is contained in:
alexhudson
2007-07-26 22:01:34 +00:00
parent 422036f5a7
commit 3a873c389c
33 changed files with 982 additions and 886 deletions
+1
View File
@@ -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
+6
View File
@@ -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
View File
@@ -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;
-410
View File
@@ -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());
+2 -1
View File
@@ -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
View File
@@ -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));
}
+6 -1
View File
@@ -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
View File
@@ -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());
+2
View File
@@ -22,6 +22,8 @@
#ifndef QUEUED_H
#define QUEUED_H
#define LOGGERNAME "queue"
#include <xpl.h>
#include <connio.h>
#include <mdb.h>
+14 -24
View File
@@ -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;
}
+9 -10
View File
@@ -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
+2 -1
View File
@@ -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:
+2 -2
View File
@@ -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;
}
+2 -1
View File
@@ -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';
+1 -2
View File
@@ -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
+26 -14
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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;
}
}
}
};
-8
View File
@@ -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 ()
+3 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 />");
}
+12 -3
View File
@@ -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);
+5 -3
View File
@@ -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');
+12 -5
View File
@@ -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
View File
@@ -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>&nbsp;',
'<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!');
}
};
+1 -1
View File
@@ -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
View File
@@ -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)];
+4 -2
View File
@@ -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));