+ const char *cmd;
+ const char *desc;
+};
+
+HashList *ProtoHookList = NULL;
+
+
+#define ERR_PORT (1 << 1)
+
+
+static StrBuf *portlist = NULL;
+
+static StrBuf *errormessages = NULL;
+
+
+long DetailErrorFlags;
+ConstStr Empty = {HKEY("")};
+char *ErrSubject = "Startup Problems";
+ConstStr ErrGeneral[] = {
+ {HKEY("Citadel had trouble on starting up. ")},
+ {HKEY(" This means, citadel won't be the service provider for a specific service you configured it to.\n\n"
+ "If you don't want citadel to provide these services, turn them off in WebCit via: ")},
+ {HKEY("To make both ways actualy take place restart the citserver with \"sendcommand down\"\n\n"
+ "The errors returned by the system were:\n")},
+ {HKEY("You can recheck the above if you follow this faq item:\n"
+ "http://www.citadel.org/doku.php?id=faq:mastering_your_os:net#netstat")}
+};
+
+ConstStr ErrPortShort = { HKEY("We couldn't bind all ports you configured to be provided by citadel server.\n")};
+ConstStr ErrPortWhere = { HKEY("\"Admin->System Preferences->Network\".\n\nThe failed ports and sockets are: ")};
+ConstStr ErrPortHint = { HKEY("If you want citadel to provide you with that functionality, "
+ "check the output of \"netstat -lnp\" on linux Servers or \"netstat -na\" on *BSD"
+ " and stop the program that binds these ports.\n You should eventually remove "
+ " their initscripts in /etc/init.d so that you won't get this trouble once more.\n"
+ " After that goto \"Administration -> Shutdown Citadel\" to make Citadel restart & retry to bind this port.\n")};
+
+
+void LogPrintMessages(long err)
+{
+ StrBuf *Message;
+ StrBuf *List, *DetailList;
+ ConstStr *Short, *Where, *Hint;
+
+
+ Message = NewStrBufPlain(NULL,
+ StrLength(portlist) + StrLength(errormessages));
+
+ DetailErrorFlags = DetailErrorFlags & ~err;
+
+ switch (err)
+ {
+ case ERR_PORT:
+ Short = &ErrPortShort;
+ Where = &ErrPortWhere;
+ Hint = &ErrPortHint;
+ List = portlist;
+ DetailList = errormessages;
+ break;
+ default:
+ Short = &Empty;
+ Where = &Empty;
+ Hint = &Empty;
+ List = NULL;
+ DetailList = NULL;
+ }
+
+ StrBufAppendBufPlain(Message, CKEY(ErrGeneral[0]), 0);
+ StrBufAppendBufPlain(Message, CKEY(*Short), 0);
+ StrBufAppendBufPlain(Message, CKEY(ErrGeneral[1]), 0);
+ StrBufAppendBufPlain(Message, CKEY(*Where), 0);
+ StrBufAppendBuf(Message, List, 0);
+ StrBufAppendBufPlain(Message, HKEY("\n\n"), 0);
+ StrBufAppendBufPlain(Message, CKEY(*Hint), 0);
+ StrBufAppendBufPlain(Message, HKEY("\n\n"), 0);
+ StrBufAppendBufPlain(Message, CKEY(ErrGeneral[2]), 0);
+ StrBufAppendBuf(Message, DetailList, 0);
+ StrBufAppendBufPlain(Message, HKEY("\n\n"), 0);
+ StrBufAppendBufPlain(Message, CKEY(ErrGeneral[3]), 0);
+
+ syslog(LOG_EMERG, "%s", ChrPtr(Message));
+ syslog(LOG_EMERG, "%s", ErrSubject);
+ quickie_message("Citadel", NULL, NULL, AIDEROOM, ChrPtr(Message), FMT_FIXED, ErrSubject);
+
+ FreeStrBuf(&Message);
+ FreeStrBuf(&List);
+ FreeStrBuf(&DetailList);
+}
+
+
+void AddPortError(char *Port, char *ErrorMessage)
+{
+ long len;
+
+ DetailErrorFlags |= ERR_PORT;
+
+ len = StrLength(errormessages);
+ if (len > 0) StrBufAppendBufPlain(errormessages, HKEY("; "), 0);
+ else errormessages = NewStrBuf();
+ StrBufAppendBufPlain(errormessages, ErrorMessage, -1, 0);
+
+
+ len = StrLength(portlist);
+ if (len > 0) StrBufAppendBufPlain(portlist, HKEY(";"), 0);
+ else portlist = NewStrBuf();
+ StrBufAppendBufPlain(portlist, Port, -1, 0);
+}
+
+
+int DLoader_Exec_Cmd(char *cmdbuf)
+{
+ void *vP;
+ ProtoFunctionHook *p;
+
+ if (GetHash(ProtoHookList, cmdbuf, 4, &vP) && (vP != NULL)) {
+ p = (ProtoFunctionHook*) vP;
+ p->handler(&cmdbuf[5]);
+ return 1;
+ }
+ return 0;
+}
+
+long FourHash(const char *key, long length)
+{
+ int i;
+ int ret = 0;
+ const unsigned char *ptr = (const unsigned char*)key;
+
+ for (i = 0; i < 4; i++, ptr ++)
+ ret = (ret << 8) |
+ ( ((*ptr >= 'a') &&
+ (*ptr <= 'z'))?
+ *ptr - 'a' + 'A':
+ *ptr);
+
+ return ret;
+}
+/*
+typedef struct __LogDebugEntry {
+ CtdlDbgFunction F;
+ const char *Name;
+ long Len;
+} LogDebugEntry;
+HashList *LogDebugEntryTable = NULL;
+*/
+void CtdlRegisterDebugFlagHook(const char *Name, long Len, CtdlDbgFunction F)
+{
+ LogDebugEntry *E;
+ if (LogDebugEntryTable == NULL)
+ LogDebugEntryTable = NewHash(1, NULL);
+ E = (LogDebugEntry*) malloc(sizeof(LogDebugEntry));
+ E->F = F;
+ E->Name = Name;
+ E->Len = Len;
+ Put(LogDebugEntryTable, Name, Len, E, NULL);
+
+}
+void CtdlSetDebugLogFacilities(const char **Str, long n)
+{
+ StrBuf *Token = NULL;
+ StrBuf *Buf = NULL;
+ const char *ch;
+ int i;
+ int DoAll = 0;
+ void *vptr;
+
+ for (i=0; i < n; i++){
+ if ((Str[i] != NULL) && !IsEmptyStr(Str[i])) {
+ if (strcmp(Str[i], "all") == 0) {
+ DoAll = 1;
+ continue;
+ }
+ Buf = NewStrBufPlain(Str[i], -1);
+ ch = NULL;
+ if (Token == NULL)
+ Token = NewStrBufPlain(NULL, StrLength(Buf));
+ while ((ch != StrBufNOTNULL) &&
+ StrBufExtract_NextToken(Token, Buf, &ch, ',')) {
+ if (GetHash(LogDebugEntryTable, SKEY(Token), &vptr) &&
+ (vptr != NULL))
+ {
+ LogDebugEntry *E = (LogDebugEntry*)vptr;
+ E->F();
+ }
+ }
+ }
+ FreeStrBuf(&Buf);
+ }
+ FreeStrBuf(&Token);
+ if (DoAll) {
+ long HKLen;
+ const char *ch;
+ HashPos *Pos;
+
+ Pos = GetNewHashPos(LogDebugEntryTable, 0);
+ while (GetNextHashPos(LogDebugEntryTable, Pos, &HKLen, &ch, &vptr)) {
+ LogDebugEntry *E = (LogDebugEntry*)vptr;
+ E->F();
+ }
+
+ DeleteHashPos(&Pos);
+ }
+}
+void CtdlDestroyDebugTable(void)
+{
+
+ DeleteHash(&LogDebugEntryTable);
+}