void NNTPListDistribPats(Connection *conn, char **pptr) { FILE *fi; MBLogPrintf(conn, &conn->co_TMBuf, "215 Default distributions in form \"weight:pattern:value\".\r\n"); if ((fi = fopen(PatLibExpand(DistribDotPatsPat), "r")) != NULL) { char buf[256]; while (fgets(buf, sizeof(buf), fi) != NULL) { int l = strlen(buf); if (l > 0 && buf[l-1] == '\n') { buf[--l] = 0; if (l > 0 && buf[l-1] == '\r') buf[--l] = 0; } if (buf[0] == '.') MBWrite(&conn->co_TMBuf, ".", 1); MBWrite(&conn->co_TMBuf, buf, l); MBWrite(&conn->co_TMBuf, "\r\n", 2); } fclose(fi); } MBPrintf(&conn->co_TMBuf, ".\r\n"); NNCommand(conn); }
void NNTPListModerators(Connection *conn, char **pptr) { FILE *fi; MBLogPrintf(conn, &conn->co_TMBuf, "215 Newsgroup moderators in form \"group-pattern:mail-address-pattern\".\r\n"); if ((fi = fopen(PatLibExpand(ModeratorsPat), "r")) != NULL) { char buf[256]; while (fgets(buf, sizeof(buf), fi) != NULL) { int l = strlen(buf); if (l == 0 || buf[0] == '#' || buf[0] == '\n') continue; if (buf[l-1] == '\n') buf[--l] = 0; if (buf[0] == '.') MBWrite(&conn->co_TMBuf, ".", 1); MBWrite(&conn->co_TMBuf, buf, l); MBWrite(&conn->co_TMBuf, "\r\n", 2); } fclose(fi); } MBPrintf(&conn->co_TMBuf, ".\r\n"); NNCommand(conn); }
void NNListActiveScan(Connection *conn) { struct GroupList *groups = conn->co_Auth.dr_ListGroupDef->gr_Groups; conn->co_Func = NNListActiveScan; conn->co_State = "listac"; while ((conn->co_TMBuf.mh_Bytes < MBUF_HIWAT) && (((conn->co_ListCacheMode != ACMODE_READ) && conn->co_ListRec) || ((conn->co_ListCacheMode == ACMODE_READ) && conn->co_ListCacheGroups))) { int glen; const char *group; char grpbuf[MAXGNAME]; const char *rec; if (conn->co_ListCacheMode == ACMODE_READ) { char *grpname = conn->co_ListCacheGroups->group; rec = KPDBReadRecord(KDBActive, grpname, 0, &conn->co_ListRecLen); } else { rec = KPDBReadRecordAt(KDBActive, conn->co_ListRec, 0, NULL); } group = rec ? KPDBGetField(rec, conn->co_ListRecLen, NULL, &glen, NULL) : ""; if (*group && (glen < MAXGNAME)) { bcopy(group, grpbuf, glen); grpbuf[glen] = 0; if ((conn->co_ListPat == NULL || WildCmp(conn->co_ListPat, grpbuf) == 0) && (groups == NULL || GroupFindWild(grpbuf, groups)) ) { /* * note: because we are locking a previously retrieved but unlocked * record, the record may be marked as deleted. We cannot do * KPDBWrite()'s with KP_LOCK_CONTINUE in this case because it * may not properly locate the record to continue the lock at. */ KPDBLock(KDBActive, rec); if (conn->co_ArtMode == COM_GROUPDESC) { int glen; const char *desc = KPDBGetField(rec, conn->co_ListRecLen, "GD", &glen, "?"); MBPrintf(&conn->co_TMBuf, "%s\t", grpbuf); MBWriteDecode(&conn->co_TMBuf, desc, glen); MBWrite(&conn->co_TMBuf, "\r\n", 2); } else if (conn->co_ArtMode == COM_ACTIVE) { int flen; const char *flags = KPDBGetField(rec, conn->co_ListRecLen, "S", &flen, "n"); artno_t ne = strtoll(KPDBGetField(rec, conn->co_ListRecLen, "NE", NULL, "0"), NULL, 10); artno_t nb = strtoll(KPDBGetField(rec, conn->co_ListRecLen, "NB", NULL, "0"), NULL, 10); /* * NOTE: we cannot use *.*s because it's broken on most * platforms... it will strlen() the string, and the string * in this case is the entire size of the active file! */ MBPrintf(&conn->co_TMBuf, "%s %010lld %010lld ", grpbuf, artno_ne(nb, ne, conn->co_Numbering), artno_nb(nb, ne, conn->co_Numbering) ); MBWrite(&conn->co_TMBuf, flags, flen); MBWrite(&conn->co_TMBuf, "\r\n", 2); } else if (conn->co_ArtMode == COM_NEWGROUPS) { const char *cts = KPDBGetField(rec, conn->co_ListRecLen, "CTS", NULL, NULL); if (cts) { int dt, cts_int = (int)strtoul(cts, NULL, 16); if (conn->co_ListCacheMode == ACMODE_WRITE) ActiveCacheInsert(&activeCache, grpbuf, cts_int); dt = cts_int - (int)conn->co_TimeRestrict.tr_Time; if (dt > 0) { int flen; const char *flags = KPDBGetField(rec, conn->co_ListRecLen, "S", &flen, "n"); artno_t ne = strtoll(KPDBGetField(rec, conn->co_ListRecLen, "NE", NULL, "0"), NULL, 10); artno_t nb = strtoll(KPDBGetField(rec, conn->co_ListRecLen, "NB", NULL, "0"), NULL, 10); MBPrintf(&conn->co_TMBuf, "%s %lld %lld ", grpbuf, artno_ne(nb, ne, conn->co_Numbering), artno_nb(nb, ne, conn->co_Numbering) ); MBWrite(&conn->co_TMBuf, flags, flen); MBWrite(&conn->co_TMBuf, "\r\n", 2); } } } KPDBUnlock(KDBActive, rec); } } /* * If we are looking for a wildcard, continue the scan. Otherwise * we are done. */ if (conn->co_Flags & COF_PATISWILD) { if (conn->co_ListCacheMode == ACMODE_READ) { conn->co_ListCacheGroups = conn->co_ListCacheGroups->next; if (conn->co_ListCacheGroups == NULL) { conn->co_ListCachePtr = ActiveCacheGetNext(conn->co_ListCachePtr); conn->co_ListCacheGroups = conn->co_ListCachePtr ? conn->co_ListCachePtr->nglist : NULL; } } else { conn->co_ListRec = KPDBScanNext( KDBActive, conn->co_ListRec, 0, &conn->co_ListRecLen ); } } else { conn->co_ListRec = 0; conn->co_ListCachePtr = NULL; } } if ((conn->co_ListCacheMode == ACMODE_NONE) && (conn->co_ListRec == 0)) { MBPrintf(&conn->co_TMBuf, ".\r\n"); NNCommand(conn); zfreeStr(&conn->co_MemPool, &conn->co_ListPat); if (DebugOpt) printf("done\n"); } if ((conn->co_ListCacheMode == ACMODE_READ) && (conn->co_ListCacheGroups == NULL)) { ActiveCacheReadUnlock(); conn->co_ListCacheMode = ACMODE_NONE; MBPrintf(&conn->co_TMBuf, ".\r\n"); NNCommand(conn); zfreeStr(&conn->co_MemPool, &conn->co_ListPat); if (DebugOpt) printf("done\n"); } if ((conn->co_ListCacheMode == ACMODE_WRITE) && (conn->co_ListRec == 0)) { ActiveCacheMarkValid(KDBActive); ActiveCacheWriteUnlock(); conn->co_ListCacheMode = ACMODE_NONE; MBPrintf(&conn->co_TMBuf, ".\r\n"); NNCommand(conn); zfreeStr(&conn->co_MemPool, &conn->co_ListPat); if (DebugOpt) printf("done\n"); } }
void NNSpoolResponse3(Connection *conn) { char *buf; ServReq *sreq = conn->co_SReq; int len = 0; conn->co_Func = NNSpoolResponse3; conn->co_State = "spres3"; for (;;) { int error = 0; len = MBReadLine(&conn->co_RMBuf, &buf); /* * If an error occurs and we are not in FastCopyOpt mode, * we can simply terminate the server and the request will be * retried. If we are an FastCopyOpt mode we have already * started writing the article back to the client and cannot * simply cut things off. We simulate an ending, make sure * we do not commit the article to the cache, and *then* * terminate the server. */ if (len < 0) { if (FastCopyOpt == 0) { NNServerTerminate(conn); return; } len = 3; buf = ".\r"; error = 1; } /* * If len is 0, we have nothing to do */ if (len == 0) break; conn->co_ServerByteCount += len + 1; if (len == 3 && strcmp(buf, ".\r") == 0) { conn->co_ServerArticleCount++; if (sreq->sr_CConn) { MBCopy( &sreq->sr_CConn->co_ArtBuf, &sreq->sr_CConn->co_TMBuf ); } if (sreq->sr_Cache) { fflush(sreq->sr_Cache); if (ferror(sreq->sr_Cache) || error) AbortCache(fileno(sreq->sr_Cache), sreq->sr_MsgId, 0); else CommitCache(conn, 0); fclose(sreq->sr_Cache); sreq->sr_Cache = NULL; } if (sreq->sr_CConn == NULL) { NNFinishSReq(conn, NULL, 0); } else { switch(sreq->sr_CConn->co_ArtMode) { case COM_ARTICLE: case COM_BODY: case COM_BODYWVF: case COM_BODYNOSTAT: case COM_HEAD: if (error) MBPrintf(&sreq->sr_CConn->co_TMBuf, "(spool server died prior to completion of the article dump)\r\n"); NNFinishSReq(conn, ".\r\n", 0); break; case COM_STAT: NNFinishSReq(conn, "", 0); break; default: NNFinishSReq(conn, "(something blew up in the spool code)\r\n.\r\n", 0); break; } } /* * If an error occured ( can only happen if we were in FastCopyOpt * mode ), we have to terminate the server now, after we've * finished processing the client request. */ if (error) { NNServerTerminate(conn); } return; } if (len > 0) buf[len-1] = '\n'; if (sreq->sr_CConn) { switch(sreq->sr_CConn->co_ArtMode) { case COM_ARTICLE: case COM_BODY: case COM_BODYWVF: case COM_BODYNOSTAT: MBWrite(&sreq->sr_CConn->co_ArtBuf, buf, len); break; } } if (sreq->sr_Cache) fwrite(buf, 1, len, sreq->sr_Cache); } if (FastCopyOpt && sreq->sr_CConn) { MBCopy( &sreq->sr_CConn->co_ArtBuf, &sreq->sr_CConn->co_TMBuf ); } /* still waiting for input */ if (len == 0) { /* 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 (4), closing spool server", conn->co_Desc->d_Id, sreq->sr_MsgId); NNServerTerminate(conn); } } }
void NNSpoolResponse2(Connection *conn) { char *buf; int len; ServReq *sreq = conn->co_SReq; char *vserver; int doneconn; char ch; conn->co_Func = NNSpoolResponse2; conn->co_State = "spres2"; /* * We need to check that co_Auth.dr_VServerDef is defined * because it probably won't be for a connection to a backend * spool */ if (sreq->sr_CConn && sreq->sr_CConn->co_Auth.dr_VServerDef) vserver = sreq->sr_CConn->co_Auth.dr_VServerDef->vs_ClusterName; else vserver = ""; while ((len = MBReadLine(&conn->co_RMBuf, &buf)) > 0) { #ifdef STATS_ART_AGE_DR if (! strncasecmp(buf, "Date:", 5)) { logit(LOG_INFO, "articleage %s %d", sreq->sr_MsgId, (int)(time(NULL)) - parsedate(buf)); } #endif conn->co_ServerByteCount += len; if (len == 2 && strcmp(buf, "\r") == 0) { if (sreq->sr_Cache) fwrite("\r\n", 1, 2, sreq->sr_Cache); if (sreq->sr_CConn) { switch(sreq->sr_CConn->co_ArtMode) { case COM_ARTICLE: MBPrintf(&sreq->sr_CConn->co_ArtBuf, "\r\n"); break; } } NNSpoolResponse3(conn); return; } if (len == 3 && strcmp(buf, ".\r") == 0) { 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); return; } /* * Only munge Xref: header if we asked for it, the wrong Xref: * header can blow up news readers, so we need to be able to * change it when viewing to match the Path: * * sr_CConn may be NULL if the client terminated or if an * autonomous lookahead request was issued. * */ doneconn = 0; ch = tolower(*buf); if (*vserver && sreq->sr_CConn && !sreq->sr_CConn->co_Auth.dr_VServerDef->vs_NoXrefHostUpdate && ch == 'x' && strncasecmp(buf, "Xref:", 5) == 0) { char *ptr; int l; /* * The len includes the trailing \n converted to a \0 */ l = len - 2; while (l > 5 && (buf[l] == '\r' || buf[l] == '\n')) l--; ptr = buf + 5; while (isspace((int)*ptr)) ptr++; while (!isspace((int)*ptr)) ptr++; while (isspace((int)*ptr)) ptr++; if (*ptr) { char line[8192]; int e; l = (buf + l) - ptr + 1; sprintf(line, "Xref: %s ", vserver); e = strlen(line); memcpy(&line[e], ptr, l); line[e + l] = '\0'; strcat(line, "\r\n"); switch(sreq->sr_CConn->co_ArtMode) { case COM_HEAD: case COM_ARTICLE: MBWrite(&sreq->sr_CConn->co_ArtBuf, line, strlen(line)); break; } doneconn = 1; } } if (*vserver && sreq->sr_CConn && !sreq->sr_CConn->co_Auth.dr_VServerDef->vs_NoReadPath && ch == 'p' && strncasecmp(buf, "Path:", 5) == 0) { char *ptr; int l; int vsl = strlen(vserver); /* * The len includes the trailing \n converted to a \0 */ l = len - 2; while (l > 5 && (buf[l] == '\r' || buf[l] == '\n')) l--; ptr = buf + 5; while (isspace((int)*ptr)) ptr++; if (*ptr && (strncmp(vserver, ptr, vsl) || ((ptr[vsl] != '\0') && (ptr[vsl] != '!')))) { char line[8192]; int e; l = (buf + l) - ptr + 1; sprintf(line, "Path: %s!", vserver); e = strlen(line); memcpy(&line[e], ptr, l); line[e + l] = '\0'; strcat(line, "\r\n"); switch(sreq->sr_CConn->co_ArtMode) { case COM_HEAD: case COM_ARTICLE: MBWrite(&sreq->sr_CConn->co_ArtBuf, line, strlen(line)); break; } doneconn = 1; } } if (len) { buf[len-1] = '\n'; if (sreq->sr_Cache) fwrite(buf, 1, len, sreq->sr_Cache); /* * sr_CConn may be NULL if the client terminated or if an * autonomous lookahead request was issued. */ if (!doneconn && sreq->sr_CConn) { switch(sreq->sr_CConn->co_ArtMode) { case COM_HEAD: case COM_ARTICLE: MBWrite(&sreq->sr_CConn->co_ArtBuf, buf, len); break; } } } } 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 (3), closing spool server", conn->co_Desc->d_Id, sreq->sr_MsgId); NNServerTerminate(conn); } } }
int main (int argc,char *argv[]) { int num=1; int c,i,w=0,rep=0; float value; char TagName[MAXALIASSIZE]="\0"; char *ip; int repeat=1,wait=1000; int port=MODBUS_PORT; while ((c=getopt(argc,argv,"r:s:p:t:d:n:w:?h"))!=EOF) switch(c) { case 'r': //Repeat { repeat=atoi(optarg); }; break; case 's': //Sleep { wait=atoi(optarg); }; break; case 'p': //Port { port=atoi(optarg); }; break; case 't': //Timeout { MB_TIMEOUT=1000*atoi(optarg); }; break; case 'd': //Device Id { MB_UNIT_IDENTIFIER=atoi(optarg); }; break; case 'n': //Number of value to read { num=atoi(optarg); }; break; case 'w': //Write value { w=1; value=atof(optarg); }; break; case '?': case 'h': { printf("%s (Build on %s %s)\n",LOG_TITLE,__DATE__,__TIME__); printf("usage: %s:[-?,h] [-p1~65535] [-t1...] [-d0~255] [-n1..] [-w Value] node_adress var\n",argv[0]); printf("-r\tRepeat (Default : %d)\n",repeat); printf("-s\tRepeat interval (Default : %d ms)\n",wait); printf("-p\tPort (Default : %d)\n",port); printf("-t\tTimeout (Default : %d s)\n",MB_TIMEOUT/1000); printf("-n\tNumber of value to read(Default : 1)\n"); printf("-d\tDevice Id(Default : 1)\n"); printf("-w\tValue to write\n"); return(0); } break; default: break; } if (optind < argc) { ip=argv[optind]; strcpy(TagName,argv[optind+1]); } int sock=MBOpenSock(ip,port); if (sock==MBError) { MBLog("opensock : %s\n",mb_err_msg); return(1); } for(rep=0; rep<repeat; rep++) { if (w) { mb_write_rsp *rsp=MBWrite(sock,TagName,1,&value); //mb_write_rsp *rsp=_MBWrite_Ext(sock,timeout,MBGet_Transaction_Id(),UNIT_IDENTIFIER,TagName,1,&value); if(rsp==NULL) { MBLog("Write error : %s\n",mb_err_msg); } MBLog("%s Write %s \n",TagName,mb_err_msg); free(rsp); } mb_read_rsp *rsp=MBRead(sock,TagName,num); //mb_read_rsp *rsp=_MBRead_Ext(sock,timeout,MBGet_Transaction_Id(),UNIT_IDENTIFIER,TagName,num); if(rsp==NULL) { MBLog("Read error ! : %s\n",mb_err_msg); return(1); } MBLog("Read %s \n",mb_err_msg); for(i=0; i<rsp->Number; i++) { MBLog("Value (%s + %d) : %.8X (%d = %g) (%s)\n",TagName,i,MBGetValueAsInteger(rsp,i),MBGetValueAsInteger(rsp,i),MBGetValueAsReal(rsp,i),mb_err_msg); } free(rsp); if (rep+1<repeat) sleep(wait/1000); } close(sock); return(0); exit(0); }