Пример #1
0
/*------------------------------------------------------------------------*\
 | 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
Пример #2
0
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
Пример #3
0
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);
	}
    }
}
Пример #4
0
/*
 * 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);
	}
    }
}
Пример #5
0
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);
}