/*------------------------------------------------------------------------*\ | METHOD : OQcncShutdownMeth | | DESCRIPTION : ODBC Connection object's destructor. | | Novell, Inc., November 1, 1993. mw | \*------------------------------------------------------------------------*/ void ALMAPI OQcncShutdownMeth ( pAEvtInfo, // event pointer pAObjMessage // system pointer ) { MemBlock mb; // memblock class long objIdx; // object index OBJECTID qcncObj; // qcnc object QcncCore *qcncCore; // qcnc core info QCNC_FNC fnc; // qcnc_fnc class qeSTATUS errorCode; // error code objIdx = AOBJ_GETFIRSTKEY; while((qcncObj = AObjGetNextObject(OTYPE_QCNC, &objIdx)) != 0) { /* ---- releases resources ---- */ qcncCore = (QcncCore *) mb.GetPointer(qcncObj, QCNCCORE); if (qcncCore->isConnected) { fnc.CloseCursor(qcncObj); // closes the qsql cursors errorCode = (*qe_Disconnect)(qcncCore->hdbc); if (fnc.RecordError(qcncCore, errorCode)) AEvtPostSignalAtMark(qcncObj, QCNCIFERROR); else qcncCore->isConnected = FALSE; } // if if (qcncCore->errorCode != qeSUCCESS) { qcncCore->errorCode = qeSUCCESS; MBFree(qcncCore->errorMsg); } // if } // while if (sqlLib.IsLoadLib()) (*qe_LibTerm)(); } // OQcncShutdownMeth
BOOL QCNC_FNC::RecordError /* ---- Record Error -------------------- */ ( QcncCore *qcncCore, // qcnc core info qeSTATUS errorCode // error code ) /* Returns true or false as the result of recording error. */ { if (errorCode == qeSUCCESS) { /* ---- no error ---- */ if (qcncCore->errorCode != qeSUCCESS) { /* ---- erases the previous error message ---- */ qcncCore->errorCode = qeSUCCESS; MBFree(qcncCore->errorMsg); } // if return FALSE; } // if if (qcncCore->errorCode == qeSUCCESS) /* ---- creates buffer for the current error message ---- */ qcncCore->errorMsg = (char *) MBAlloc(qeMAX_ERR_MSG_LEN); (*qe_ErrMsgBuf)(qcncCore->errorMsg); qcncCore->errorCode = errorCode; return TRUE; } // RecordError
void NNSpoolResponse1(Connection *conn) { ServReq *sreq = conn->co_SReq; char *buf; int len; conn->co_Func = NNSpoolResponse1; conn->co_State = "spres1"; if ((len = MBReadLine(&conn->co_RMBuf, &buf)) > 0) { conn->co_ServerByteCount += len; if (strtol(buf, NULL, 10) == 220) { /* We have a positive answer, we may cache article */ if (conn->co_Desc->d_Cache) { CreateCache(conn); } /* * sr_CConn may be NULL if client was terminated while * server operation was still in progress. */ if (conn->co_SReq->sr_CConn) { MBFree(&conn->co_SReq->sr_CConn->co_ArtBuf); switch(sreq->sr_CConn->co_ArtMode) { case COM_BODYNOSTAT: break; case COM_STAT: case COM_HEAD: case COM_BODY: case COM_ARTICLE: MBLogPrintf(sreq->sr_CConn, &sreq->sr_CConn->co_ArtBuf, "%03d 0 %s %s\r\n", GoodRC(sreq->sr_CConn), sreq->sr_MsgId, GoodResId(sreq->sr_CConn) ); break; case COM_BODYWVF: MBLogPrintf(sreq->sr_CConn, &sreq->sr_CConn->co_ArtBuf, "%03d %lld %s %s\r\n", GoodRC(sreq->sr_CConn), artno_art(sreq->sr_CConn->co_ArtBeg, sreq->sr_CConn->co_ArtEnd, sreq->sr_CConn->co_ArtNo, sreq->sr_CConn->co_Numbering), sreq->sr_MsgId, GoodResId(sreq->sr_CConn) ); break; case COM_ARTICLEWVF: { const char *ovdata; const char *msgid; int ovlen; if ((ovdata = NNRetrieveHead(sreq->sr_CConn, &ovlen, &msgid, NULL, NULL, NULL)) != NULL) { MBLogPrintf(sreq->sr_CConn, &sreq->sr_CConn->co_TMBuf, "%03d %lld %s %s\r\n", GoodRC(sreq->sr_CConn), artno_art(sreq->sr_CConn->co_ArtBeg, sreq->sr_CConn->co_ArtEnd, sreq->sr_CConn->co_ArtNo, sreq->sr_CConn->co_Numbering), sreq->sr_MsgId, GoodResId(sreq->sr_CConn) ); DumpOVHeaders(sreq->sr_CConn, ovdata, ovlen); MBPrintf(&sreq->sr_CConn->co_TMBuf, "\r\n"); sreq->sr_CConn->co_ArtMode = COM_BODYNOSTAT; } else { NNSpoolResponseScrap(conn); return; /* bleh */ } } break; } } NNSpoolResponse2(conn); return; } else if (strtol(buf, NULL, 10) == 430) { conn->co_ServerArticleNotFoundErrorCount++; } else { conn->co_ServerArticleMiscErrorCount++; } if (sreq->sr_CConn == NULL) NNFinishSReq(conn, NULL, 0); else if (sreq->sr_CConn->co_ArtMode == COM_BODYNOSTAT) NNFinishSReq(conn, "(article not available)\r\n.\r\n", 1); else if (sreq->sr_CConn->co_RequestFlags == ARTFETCH_ARTNO) NNFinishSReq(conn, "423 No such article number in this group\r\n", 1); else NNFinishSReq(conn, "430 No such article\r\n", 1); } else if (len < 0) { NNServerTerminate(conn); } else { /* else we haven't got the response yet */ /* note that we get here at least every 30s or so via forceallcheck */ if (conn->co_Desc->d_Timeout && (time(NULL) > sreq->sr_Time + conn->co_Desc->d_Timeout)) { logit(LOG_ERR, "Timeout elapsed waiting for %s to answer request %s (2), closing spool server", conn->co_Desc->d_Id, sreq->sr_MsgId); NNServerTerminate(conn); } } }
/* * Retrieve location */ void NNGetLocal1(Connection *conn) { ServReq *sreq = conn->co_SReq; char *buf; char *ptr; char *filename; int len; long offset; long size; char smaxage[32]; conn->co_Func = NNGetLocal1; conn->co_State = "getlcl1"; *smaxage = '\0'; if ((len = MBReadLine(&conn->co_RMBuf, &buf)) > 0) { conn->co_ServerByteCount += len; if (sreq->sr_MaxAge) { snprintf(smaxage, sizeof(smaxage), " a%d", sreq->sr_MaxAge); } if (strtol(buf, NULL, 10) == 223) { /* * sr_CConn may be NULL if client was terminated while * server operation was still in progress. */ if (conn->co_SReq->sr_CConn) { MBFree(&conn->co_SReq->sr_CConn->co_ArtBuf); switch(sreq->sr_CConn->co_ArtMode) { case COM_BODYNOSTAT: break; case COM_STAT: case COM_HEAD: case COM_BODY: case COM_ARTICLE: MBLogPrintf(sreq->sr_CConn, &sreq->sr_CConn->co_ArtBuf, "%03d 0 %s %s\r\n", GoodRC(sreq->sr_CConn), sreq->sr_MsgId, GoodResId(sreq->sr_CConn) ); break; case COM_BODYWVF: MBLogPrintf(sreq->sr_CConn, &sreq->sr_CConn->co_ArtBuf, "%03d %lld %s %s\r\n", GoodRC(sreq->sr_CConn), artno_art(sreq->sr_CConn->co_ArtBeg, sreq->sr_CConn->co_ArtEnd, sreq->sr_CConn->co_ArtNo, sreq->sr_CConn->co_Numbering), sreq->sr_MsgId, GoodResId(sreq->sr_CConn) ); break; case COM_ARTICLEWVF: { const char *ovdata; const char *msgid; int ovlen; if ((ovdata = NNRetrieveHead(sreq->sr_CConn, &ovlen, &msgid, NULL, NULL, NULL)) != NULL) { MBLogPrintf(sreq->sr_CConn, &sreq->sr_CConn->co_TMBuf, "%03d %lld %s %s\r\n", GoodRC(sreq->sr_CConn), artno_art(sreq->sr_CConn->co_ArtBeg, sreq->sr_CConn->co_ArtEnd, sreq->sr_CConn->co_ArtNo, sreq->sr_CConn->co_Numbering), sreq->sr_MsgId, GoodResId(sreq->sr_CConn) ); DumpOVHeaders(sreq->sr_CConn, ovdata, ovlen); MBPrintf(&sreq->sr_CConn->co_TMBuf, "\r\n"); sreq->sr_CConn->co_ArtMode = COM_BODYNOSTAT; } else { NNSpoolResponseScrap(conn); return; /* bleh */ } } break; } } /* * We have to get additionnal information from the buffer */ strtok(buf, " ") ; offset = -1; size = -1; filename = NULL; while ((ptr = strtok(NULL, " ")) != NULL) { if (strcasecmp(ptr, "in") == 0) { filename = strtok(NULL," "); } else if (strcasecmp("offset", ptr) == 0) { ptr = strtok(NULL," "); if (ptr) { offset = strtol(ptr, NULL, 10); if (offset == LONG_MIN || offset == LONG_MAX) offset = -1; } else { offset = -1; } } else if (strcasecmp("length", ptr) == 0) { ptr = strtok(NULL," "); if (ptr) { size = strtol(ptr, NULL, 10); if (size == LONG_MIN || size == LONG_MAX) size = -1; } else { size = -1; } } } if (filename != NULL && offset >= 0 && size >= 0) { int lf; static char filepath[PATH_MAX]; if (DebugOpt) printf("NNGetLocal1 : whereis returned file %s offset %ld size %ld\n", filename, offset, size); if (strcmp(conn->co_Desc->d_LocalSpool, "/") == 0) snprintf(filepath, sizeof(filepath), "%s", filename); else snprintf(filepath, sizeof(filepath), "%s/%s", conn->co_Desc->d_LocalSpool, filename); lf = open(filepath, O_RDONLY); if (lf >= 0 && NewDFA(conn, lf, offset, size)) { NNSendLocalArticle(conn); } else { if (lf == -1) { logit(LOG_ERR, "NNGetLocal1 : problem while openning file %s", filepath); } else { logit(LOG_ERR, "NNGetLocal1 : problem while seeking file %s offset %i", filepath, offset); } close(lf); MBPrintf(&conn->co_TMBuf, "article %s%s\r\n", sreq->sr_MsgId, smaxage); NNSpoolResponse1(conn); } } else { logit(LOG_ERR, "NNGetLocal1 : error while getting whereis informations"); MBPrintf(&conn->co_TMBuf, "article %s%s\r\n", sreq->sr_MsgId, smaxage); NNSpoolResponse1(conn); } } else { /* * whereis request failed, try the normal way */ MBPrintf(&conn->co_TMBuf, "article %s%s\r\n", sreq->sr_MsgId, smaxage); conn->co_ServerArticleRequestedCount++; NNSpoolResponse1(conn); } } else if (len < 0) { NNServerTerminate(conn); } else { /* else we haven't got the response yet */ /* note that we get here at least every 30s or so via forceallcheck */ if (conn->co_Desc->d_Timeout && (time(NULL) > sreq->sr_Time + conn->co_Desc->d_Timeout)) { logit(LOG_ERR, "Timeout elapsed waiting for %s to answer request %s (1), closing spool server", conn->co_Desc->d_Id, sreq->sr_MsgId); NNServerTerminate(conn); } } }
void NNFeedOverview(Connection *conn) { int artLen; int l = 0; char *art = MBNormalize(&conn->co_ArtBuf, &artLen); char *line; int appr = 0; char ch; int err = 0; char *newsgroups = NULL; char *msgid = NULL; char *subject = NULL; char *date = NULL; char *xref = NULL; char *control = NULL; char *supers = NULL; /* Supersedes */ /* * Scan headers, look for Newsgroups: line, Subject:, Date:, From:, and * Message-Id:. If any are missing, the article is bad. If there is an * Xref: line, save that too and use it to calculate line numbers if * Xref operation is enabled. * * We allow an LF-only line to terminate the headers as well as CR+LF, * because some news systems are totally broken. */ for (line = art; line < art + artLen; line += l + 1) { for (l = line - art; l < artLen; ++l) { if (art[l] == '\n') { if (l + 1 >= artLen || /* past end of article */ l == line - art || /* blank line */ (art[l+1] != ' ' && art[l+1] != '\t') /* !header ext */ ) { break; } } } l -= line - art; ch = tolower(*line); if (l == 0 || (l == 1 && line[0] == '\r')) { /* out of headers */ break; } else if (ch == 'n' && strncasecmp(line, "Newsgroups:", 11) == 0) { newsgroups = zallocStrTrim2(&conn->co_MemPool, ',', line + 11, l - 11); } else if (ch == 'm' && strncasecmp(line, "Message-ID:", 11) == 0) { msgid = zallocStrTrim2(&conn->co_MemPool, 0, line + 11, l - 11); } else if (ch == 's' && strncasecmp(line, "Subject:", 8) == 0) { subject = zallocStrTrim2(&conn->co_MemPool, 0, line + 8, l - 8); } else if (ch == 'd' && strncasecmp(line, "Date:", 5) == 0) { date = zallocStrTrim2(&conn->co_MemPool, 0, line + 5, l - 5); } else if (ch == 'x' && strncasecmp(line, "Xref:", 5) == 0) { xref = zallocStrTrim2(&conn->co_MemPool, ',', line + 5, l - 5); } else if (ch == 'c' && strncasecmp(line, "Control:", 8) == 0) { control = zallocStrTrim2(&conn->co_MemPool, 0, line + 8, l - 8); } else if (ch == 's' && strncasecmp(line, "Supersedes:", 11) == 0) { supers = zallocStrTrim2(&conn->co_MemPool, 0, line + 11, l - 11); } else if (ch == 'a' && strncasecmp(line, "Approved:", 9) == 0) { appr = 1; } } if (conn->co_Flags & COF_POSTTOOBIG) { conn->co_Auth.dr_PostFailCount++; if (conn->co_Flags & COF_IHAVE) { MBLogPrintf(conn, &conn->co_TMBuf, "437 Rejected, too big\r\n"); } else { MBLogPrintf(conn, &conn->co_TMBuf, "439 %s too big\r\n", conn->co_IHaveMsgId); } conn->co_Flags &= ~COF_POSTTOOBIG; } else if (newsgroups == NULL || msgid == NULL || subject == NULL || date == NULL || strcmp(msgid, "<>") == 0 ) { /* * failure */ conn->co_Auth.dr_PostFailCount++; if (conn->co_Flags & COF_IHAVE) { MBLogPrintf(conn, &conn->co_TMBuf, "437 Rejected, headers missing\r\n"); } else { MBLogPrintf(conn, &conn->co_TMBuf, "439 %s\r\n", conn->co_IHaveMsgId); } } else if (conn->co_ByteCounter == 0.0 && conn->co_BytesHeader == 0) { conn->co_Auth.dr_PostFailCount++; if (conn->co_Flags & COF_IHAVE) { MBLogPrintf(conn, &conn->co_TMBuf, "437 Rejected, Bytes header missing for header-only feed\r\n"); } else { MBLogPrintf(conn, &conn->co_TMBuf, "439 %s headerOnlyFeed requires Bytes header\r\n", conn->co_IHaveMsgId); } } else if (FindCancelCache(msgid) == 0) { char logbuf[1024]; conn->co_Auth.dr_PostFailCount++; snprintf(logbuf, sizeof(logbuf), "%s cancel cache", msgid); LogCmd(conn, '-', logbuf); if (DRIncomingLogPat != NULL) LogIncoming("%s - %s%s", conn->co_Auth.dr_Host, "", logbuf); if (conn->co_Flags & COF_IHAVE) { MBLogPrintf(conn, &conn->co_TMBuf, "437 Article Already Cancelled\r\n"); } else { MBLogPrintf(conn, &conn->co_TMBuf, "439 %s Article Already Cancelled\r\n", conn->co_IHaveMsgId); } } else { /* * write out overview information */ char *group; char *ngroup = NULL; ArtNumAss *ANABase = NULL; /* * if it is a control message, we don't really care what the newsgroups * line says. instead, we cobble up "control.<type>" or just "control" */ if (conn->co_Flags & COF_WASCONTROL) { char cmsgtype[64]; char *cptr; cptr = control; while (*cptr == ' ' || *cptr == '\t') { cptr++; } snprintf(cmsgtype, sizeof(cmsgtype), "control%s%s", *cptr ? "." : "", cptr); if (((cptr = strchr(cmsgtype, ' '))) || ((cptr = strchr(cmsgtype, '\t')))) { *cptr = '\0'; } zfreeStr(&conn->co_MemPool, &newsgroups); newsgroups = zallocStr(&conn->co_MemPool, cmsgtype); } if (DebugOpt) printf("Feed overview %s %s\n", msgid, newsgroups); /* * pass 1 - assign article numbers */ for (group = newsgroups; *group; group = ngroup) { char c; char whspc = 0; char *whspptr; /* Strip leading spaces */ while (*group == ' ' || *group == '\t') { group++; } if (! *group) { break; } for (ngroup = group; *ngroup && *ngroup != ','; ++ngroup) ; c = *ngroup; *ngroup = 0; /* * Skip groups with names that are too long */ if (ngroup - group > MAXGNAME) continue; /* Strip trailing space or tab from group name */ whspptr = strpbrk(group, " \t"); if (whspptr) { whspc = *whspptr; *whspptr = 0; } AssignArticleNo(conn, &ANABase, group, xref, appr, art, artLen, msgid); /* Repair string back to its former state */ if (whspptr) { *whspptr = whspc; } *ngroup = c; if (*ngroup == ',') ++ngroup; } /* * Supersedes is allowed on non-control messages. We execute the * cancel AND post the article. Note: we do not allow supersedes * on Control: messages. (XXX is this still true with the new logic? JG) */ if (supers) { if (DebugOpt) printf("has Supersedes: %s %s\n", msgid, newsgroups); ExecuteSupersedes(conn, supers, art, artLen); } err = 0; for (group = newsgroups; *group; group = ngroup) { char c; char whspc = 0; char *whspptr; for (ngroup = group; *ngroup && *ngroup != ','; ++ngroup) ; c = *ngroup; *ngroup = 0; /* * Skip groups with names that are too long */ if (ngroup - group > MAXGNAME) continue; /* Strip trailing space or tab from group name */ whspptr = strpbrk(group, " \t"); if (whspptr) { whspc = *whspptr; *whspptr = 0; } err += WriteOverview(conn, ANABase, group, xref, art, artLen, msgid); /* Repair string back to its former state */ if (whspptr) { *whspptr = whspc; } *ngroup = c; if (*ngroup == ',') ++ngroup; } while (ANABase) { ArtNumAss *an = ANABase; ANABase = an->an_Next; zfree(&conn->co_MemPool, an, sizeof(ArtNumAss)); } if (conn->co_Flags & COF_WASCONTROL) { if (DebugOpt) printf("Control message: %s %s\n", msgid, newsgroups); LogCmd(conn, 'c', control); if (DRIncomingLogPat != NULL) LogIncoming("%s c %s %s", conn->co_Auth.dr_Host, msgid, control); ExecuteControl(conn, control, art, artLen); } if (!err) { conn->co_Auth.dr_PostCount++; if (conn->co_Flags & COF_IHAVE) { MBLogPrintf(conn, &conn->co_TMBuf, "235\r\n"); } else { MBLogPrintf(conn, &conn->co_TMBuf, "239 %s\r\n", conn->co_IHaveMsgId); } } } zfreeStr(&conn->co_MemPool, &newsgroups); zfreeStr(&conn->co_MemPool, &msgid); zfreeStr(&conn->co_MemPool, &subject); zfreeStr(&conn->co_MemPool, &date); zfreeStr(&conn->co_MemPool, &xref); zfreeStr(&conn->co_MemPool, &control); zfreeStr(&conn->co_MemPool, &conn->co_IHaveMsgId); MBFree(&conn->co_ArtBuf); NNCommand(conn); }