/* Load processes using zone-aware ps * to obtain solaris list of global * process ids for root and non-root * users to lookup later */ int ZLoadProcesstable(Seq *pidlist, Seq *rootpidlist) { char *names[CF_PROCCOLS]; int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; int index = 0; const char *pscmd = "/usr/bin/ps -Aleo zone,user,pid"; FILE *psf = cf_popen(pscmd, "r", false); if (psf == NULL) { Log(LOG_LEVEL_ERR, "ZLoadProcesstable: Couldn't open the process list with command %s.", pscmd); return false; } size_t pbuff_size = CF_BUFSIZE; char *pbuff = xmalloc(pbuff_size); while (true) { ssize_t res = CfReadLine(&pbuff, &pbuff_size, psf); if (res == -1) { if (!feof(psf)) { Log(LOG_LEVEL_ERR, "IsGlobalProcess(char **, int): Unable to read process list with command '%s'. (fread: %s)", pscmd, GetErrorStr()); cf_pclose(psf); free(pbuff); return false; } else { break; } } Chop(pbuff, pbuff_size); if (strstr(pbuff, "PID")) /* This line is the header. */ { GetProcessColumnNames(pbuff, &names[0], start, end); } else { int pid = ExtractPid(pbuff, &names[0], end); size_t zone_offset = strspn(pbuff, " "); size_t zone_end_offset = strcspn(pbuff + zone_offset, " ") + zone_offset; size_t user_offset = strspn(pbuff + zone_end_offset, " ") + zone_end_offset; size_t user_end_offset = strcspn(pbuff + user_offset, " ") + user_offset; bool is_global = (zone_end_offset - zone_offset == 6 && strncmp(pbuff + zone_offset, "global", 6) == 0); bool is_root = (user_end_offset - user_offset == 4 && strncmp(pbuff + user_offset, "root", 4) == 0); if (is_global && is_root) { SeqAppend(rootpidlist, (void*)(intptr_t)pid); } else if (is_global && !is_root) { SeqAppend(pidlist, (void*)(intptr_t)pid); } } } cf_pclose(psf); free(pbuff); return true; }
static int HailServer(EvalContext *ctx, char *host) { AgentConnection *conn; char sendbuffer[CF_BUFSIZE], recvbuffer[CF_BUFSIZE], peer[CF_MAXVARSIZE], digest[CF_MAXVARSIZE], user[CF_SMALLBUF]; bool gotkey; char reply[8]; FileCopy fc = { .portnumber = (unsigned short) ParseHostname(host, peer), }; char ipaddr[CF_MAX_IP_LEN]; if (Hostname2IPString(ipaddr, peer, sizeof(ipaddr)) == -1) { Log(LOG_LEVEL_ERR, "HailServer: ERROR, could not resolve '%s'", peer); return false; } Address2Hostkey(ipaddr, digest); GetCurrentUserName(user, CF_SMALLBUF); if (INTERACTIVE) { Log(LOG_LEVEL_VERBOSE, "Using interactive key trust..."); gotkey = HavePublicKey(user, peer, digest) != NULL; if (!gotkey) { gotkey = HavePublicKey(user, ipaddr, digest) != NULL; } if (!gotkey) { printf("WARNING - You do not have a public key from host %s = %s\n", host, ipaddr); printf(" Do you want to accept one on trust? (yes/no)\n\n--> "); while (true) { if (fgets(reply, sizeof(reply), stdin) == NULL) { FatalError(ctx, "EOF trying to read answer from terminal"); } if (Chop(reply, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } if (strcmp(reply, "yes") == 0) { printf("Will trust the key...\n"); fc.trustkey = true; break; } else if (strcmp(reply, "no") == 0) { printf("Will not trust the key...\n"); fc.trustkey = false; break; } else { printf("Please reply yes or no...(%s)\n", reply); } } } } /* Continue */ #ifdef __MINGW32__ if (LEGACY_OUTPUT) { Log(LOG_LEVEL_INFO, "..........................................................................."); Log(LOG_LEVEL_INFO, " * Hailing %s : %u, with options \"%s\" (serial)", peer, fc.portnumber, REMOTE_AGENT_OPTIONS); Log(LOG_LEVEL_INFO, "..........................................................................."); } else { Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (serial)", peer, fc.portnumber, REMOTE_AGENT_OPTIONS); } #else /* !__MINGW32__ */ if (BACKGROUND) { Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (parallel)", peer, fc.portnumber, REMOTE_AGENT_OPTIONS); } else { if (LEGACY_OUTPUT) { Log(LOG_LEVEL_INFO, "..........................................................................."); Log(LOG_LEVEL_INFO, " * Hailing %s : %u, with options \"%s\" (serial)", peer, fc.portnumber, REMOTE_AGENT_OPTIONS); Log(LOG_LEVEL_INFO, "..........................................................................."); } else { Log(LOG_LEVEL_INFO, "Hailing '%s' : %u, with options '%s' (serial)", peer, fc.portnumber, REMOTE_AGENT_OPTIONS); } } #endif /* !__MINGW32__ */ fc.servers = RlistFromSplitString(peer, '*'); if (fc.servers == NULL || strcmp(RlistScalarValue(fc.servers), "localhost") == 0) { Log(LOG_LEVEL_INFO, "No hosts are registered to connect to"); return false; } else { int err = 0; conn = NewServerConnection(fc, false, &err); if (conn == NULL) { RlistDestroy(fc.servers); Log(LOG_LEVEL_VERBOSE, "No suitable server responded to hail"); return false; } } /* Check trust interaction*/ HailExec(ctx, conn, peer, recvbuffer, sendbuffer); RlistDestroy(fc.servers); return true; } /********************************************************************/ /* Level 2 */ /********************************************************************/ static void KeepControlPromises(EvalContext *ctx, Policy *policy) { Rval retval; RUNATTR.copy.trustkey = false; RUNATTR.copy.encrypt = true; RUNATTR.copy.force_ipv4 = false; RUNATTR.copy.portnumber = SHORT_CFENGINEPORT; /* Keep promised agent behaviour - control bodies */ Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_RUNAGENT); if (constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes, NULL)) { continue; } VarRef *ref = VarRefParseFromScope(cp->lval, "control_runagent"); if (!EvalContextVariableGet(ctx, ref, &retval, NULL)) { Log(LOG_LEVEL_ERR, "Unknown lval '%s' in runagent control body", cp->lval); VarRefDestroy(ref); continue; } VarRefDestroy(ref); if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_FORCE_IPV4].lval) == 0) { RUNATTR.copy.force_ipv4 = BooleanFromString(retval.item); Log(LOG_LEVEL_VERBOSE, "SET force_ipv4 = %d", RUNATTR.copy.force_ipv4); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TRUSTKEY].lval) == 0) { RUNATTR.copy.trustkey = BooleanFromString(retval.item); Log(LOG_LEVEL_VERBOSE, "SET trustkey = %d", RUNATTR.copy.trustkey); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_ENCRYPT].lval) == 0) { RUNATTR.copy.encrypt = BooleanFromString(retval.item); Log(LOG_LEVEL_VERBOSE, "SET encrypt = %d", RUNATTR.copy.encrypt); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_PORT_NUMBER].lval) == 0) { RUNATTR.copy.portnumber = (unsigned short) IntFromString(retval.item); Log(LOG_LEVEL_VERBOSE, "SET default portnumber = %u", RUNATTR.copy.portnumber); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_BACKGROUND].lval) == 0) { /* * Only process this option if are is no -b or -i options specified on * command line. */ if (BACKGROUND || INTERACTIVE) { Log(LOG_LEVEL_WARNING, "'background_children' setting from 'body runagent control' is overridden by command-line option."); } else { BACKGROUND = BooleanFromString(retval.item); } continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_MAX_CHILD].lval) == 0) { MAXCHILD = (short) IntFromString(retval.item); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_TO_FILE].lval) == 0) { OUTPUT_TO_FILE = BooleanFromString(retval.item); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_DIRECTORY].lval) == 0) { if (IsAbsPath(retval.item)) { strncpy(OUTPUT_DIRECTORY, retval.item, CF_BUFSIZE - 1); Log(LOG_LEVEL_VERBOSE, "Setting output direcory to '%s'", OUTPUT_DIRECTORY); } continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TIMEOUT].lval) == 0) { RUNATTR.copy.timeout = (short) IntFromString(retval.item); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_HOSTS].lval) == 0) { if (HOSTLIST == NULL) // Don't override if command line setting { HOSTLIST = retval.item; } continue; } } } if (EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER, &retval)) { LASTSEENEXPIREAFTER = IntFromString(retval.item) * 60; } }
bool GetExecOutput(const char *command, char *buffer, bool useshell) /* Buffer initially contains whole exec string */ { int offset = 0; char line[CF_EXPANDSIZE]; FILE *pp; if (useshell) { pp = cf_popen_sh(command, "r"); } else { pp = cf_popen(command, "r", true); } if (pp == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open pipe to command '%s'. (cf_popen: %s)", command, GetErrorStr()); return false; } memset(buffer, 0, CF_EXPANDSIZE); for (;;) { ssize_t res = CfReadLine(line, CF_EXPANDSIZE, pp); if (res == 0) { break; } if (res == -1) { Log(LOG_LEVEL_ERR, "Unable to read output of command '%s'. (fread: %s)", command, GetErrorStr()); cf_pclose(pp); return false; } if (strlen(line) + offset > CF_EXPANDSIZE - 10) { Log(LOG_LEVEL_ERR, "Buffer exceeded %d bytes in exec '%s'", CF_EXPANDSIZE, command); break; } snprintf(buffer + offset, CF_EXPANDSIZE, "%s\n", line); offset += strlen(line) + 1; } if (offset > 0) { if (Chop(buffer, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } } Log(LOG_LEVEL_DEBUG, "GetExecOutput got '%s'", buffer); cf_pclose(pp); return true; }
static int SplitProcLine(char *proc, char **names, int *start, int *end, char **line) { int i, s, e; char *sp = NULL; char cols1[CF_PROCCOLS][CF_SMALLBUF] = { "" }; char cols2[CF_PROCCOLS][CF_SMALLBUF] = { "" }; if ((proc == NULL) || (strlen(proc) == 0)) { return false; } memset(line, 0, sizeof(char *) * CF_PROCCOLS); // First try looking at all the separable items sp = proc; for (i = 0; (i < CF_PROCCOLS) && (names[i] != NULL); i++) { while (*sp == ' ') { sp++; } if ((strcmp(names[i], "CMD") == 0) || (strcmp(names[i], "COMMAND") == 0)) { sscanf(sp, "%127[^\n]", cols1[i]); sp += strlen(cols1[i]); } else { sscanf(sp, "%127s", cols1[i]); sp += strlen(cols1[i]); } // Some ps stimes may contain spaces, e.g. "Jan 25" if ((strcmp(names[i], "STIME") == 0) && (strlen(cols1[i]) == 3)) { char s[CF_SMALLBUF] = { 0 }; sscanf(sp, "%127s", s); strcat(cols1[i], " "); strcat(cols1[i], s); sp += strlen(s) + 1; } } // Now try looking at columne alignment for (i = 0; (i < CF_PROCCOLS) && (names[i] != NULL); i++) { // Start from the header/column tab marker and count backwards until we find 0 or space for (s = start[i]; (s >= 0) && (!isspace((int) *(proc + s))); s--) { } if (s < 0) { s = 0; } // Make sure to strip off leading spaces while (isspace((int) proc[s])) { s++; } if ((strcmp(names[i], "CMD") == 0) || (strcmp(names[i], "COMMAND") == 0)) { e = strlen(proc); } else { for (e = end[i]; (e <= end[i] + 10) && (!isspace((int) *(proc + e))); e++) { } while (isspace((int) proc[e])) { if (e > 0) { e--; } if(e == 0) { break; } } } if (s <= e) { strncpy(cols2[i], (char *) (proc + s), MIN(CF_SMALLBUF - 1, (e - s + 1))); } else { cols2[i][0] = '\0'; } if (Chop(cols2[i], CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } if (strcmp(cols2[i], cols1[i]) != 0) { Log(LOG_LEVEL_INFO, "Unacceptable model uncertainty examining processes"); } line[i] = xstrdup(cols1[i]); } return true; }
int LoadProcessTable(Item **procdata) { FILE *prp; char pscomm[CF_MAXLINKSIZE]; Item *rootprocs = NULL; Item *otherprocs = NULL; if (PROCESSTABLE) { Log(LOG_LEVEL_VERBOSE, "Reusing cached process table"); return true; } CheckPsLineLimitations(); const char *psopts = GetProcessOptions(); snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VPSHARDCLASS], psopts); Log(LOG_LEVEL_VERBOSE, "Observe process table with %s", pscomm); if ((prp = cf_popen(pscomm, "r", false)) == NULL) { Log(LOG_LEVEL_ERR, "Couldn't open the process list with command '%s'. (popen: %s)", pscomm, GetErrorStr()); return false; } size_t vbuff_size = CF_BUFSIZE; char *vbuff = xmalloc(vbuff_size); # ifdef HAVE_GETZONEID char *names[CF_PROCCOLS]; int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; Seq *pidlist = SeqNew(1, NULL); Seq *rootpidlist = SeqNew(1, NULL); bool global_zone = IsGlobalZone(); if (global_zone) { int res = ZLoadProcesstable(pidlist, rootpidlist); if (res == false) { Log(LOG_LEVEL_ERR, "Unable to load solaris zone process table."); return false; } } # endif for (;;) { ssize_t res = CfReadLine(&vbuff, &vbuff_size, prp); if (res == -1) { if (!feof(prp)) { Log(LOG_LEVEL_ERR, "Unable to read process list with command '%s'. (fread: %s)", pscomm, GetErrorStr()); cf_pclose(prp); free(vbuff); return false; } else { break; } } Chop(vbuff, vbuff_size); # ifdef HAVE_GETZONEID if (global_zone) { if (strstr(vbuff, "PID") != NULL) { /* this is the banner so get the column header names for later use*/ GetProcessColumnNames(vbuff, &names[0], start, end); } else { int gpid = ExtractPid(vbuff, names, end); if (!IsGlobalProcess(gpid, pidlist, rootpidlist)) { continue; } } } # endif AppendItem(procdata, vbuff, ""); } cf_pclose(prp); /* Now save the data */ const char* const statedir = GetStateDir(); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_procs", statedir, FILE_SEPARATOR); RawSaveItemList(*procdata, vbuff, NewLineMode_Unix); # ifdef HAVE_GETZONEID if (global_zone) /* pidlist and rootpidlist are empty if we're not in the global zone */ { Item *ip = *procdata; while (ip != NULL) { ZCopyProcessList(&rootprocs, ip, rootpidlist, names, end); ip = ip->next; } ReverseItemList(rootprocs); ip = *procdata; while (ip != NULL) { ZCopyProcessList(&otherprocs, ip, pidlist, names, end); ip = ip->next; } ReverseItemList(otherprocs); } else # endif { CopyList(&rootprocs, *procdata); CopyList(&otherprocs, *procdata); while (DeleteItemNotContaining(&rootprocs, "root")) { } while (DeleteItemContaining(&otherprocs, "root")) { } } if (otherprocs) { PrependItem(&rootprocs, otherprocs->name, NULL); } snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_rootprocs", statedir, FILE_SEPARATOR); RawSaveItemList(rootprocs, vbuff, NewLineMode_Unix); DeleteItemList(rootprocs); snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_otherprocs", statedir, FILE_SEPARATOR); RawSaveItemList(otherprocs, vbuff, NewLineMode_Unix); DeleteItemList(otherprocs); free(vbuff); return true; }
int GetExecOutput(char *command, char *buffer, int useshell) /* Buffer initially contains whole exec string */ { int offset = 0; char line[CF_EXPANDSIZE], *sp; FILE *pp; int flatten_newlines = false; CfDebug("GetExecOutput(%s,%s) - use shell = %d\n", command, buffer, useshell); if (useshell) { pp = cf_popen_sh(command, "r"); } else { pp = cf_popen(command, "r"); } if (pp == NULL) { CfOut(cf_error, "cf_popen", "Couldn't open pipe to command %s\n", command); return false; } memset(buffer, 0, CF_EXPANDSIZE); while (!feof(pp)) { if (ferror(pp)) /* abortable */ { fflush(pp); break; } CfReadLine(line, CF_EXPANDSIZE, pp); if (ferror(pp)) /* abortable */ { fflush(pp); break; } if (flatten_newlines) { for (sp = line; *sp != '\0'; sp++) { if (*sp == '\n') { *sp = ' '; } } } if (strlen(line) + offset > CF_EXPANDSIZE - 10) { CfOut(cf_error, "", "Buffer exceeded %d bytes in exec %s\n", CF_EXPANDSIZE, command); break; } if (flatten_newlines) { snprintf(buffer + offset, CF_EXPANDSIZE, "%s ", line); } else { snprintf(buffer + offset, CF_EXPANDSIZE, "%s\n", line); } offset += strlen(line) + 1; } if (offset > 0) { Chop(buffer); } CfDebug("GetExecOutput got: [%s]\n", buffer); cf_pclose(pp); return true; }
void cfPS(enum cfreport level, char status, char *errstr, const Promise *pp, Attributes attr, char *fmt, ...) { va_list ap; char buffer[CF_BUFSIZE], output[CF_BUFSIZE], *v, handle[CF_MAXVARSIZE]; const char *sp; Item *ip, *mess = NULL; int verbose; Rval retval; if ((fmt == NULL) || (strlen(fmt) == 0)) { return; } va_start(ap, fmt); vsnprintf(buffer, CF_BUFSIZE - 1, fmt, ap); va_end(ap); Chop(buffer); AppendItem(&mess, buffer, NULL); if ((errstr == NULL) || (strlen(errstr) > 0)) { snprintf(output, CF_BUFSIZE - 1, " !!! System reports error for %s: \"%s\"", errstr, GetErrorStr()); AppendItem(&mess, output, NULL); } if (level == cf_error) { if (GetVariable("control_common", "version", &retval) != cf_notype) { v = (char *) retval.item; } else { v = "not specified"; } if ((sp = GetConstraintValue("handle", pp, CF_SCALAR)) || (sp = PromiseID(pp))) { strncpy(handle, sp, CF_MAXVARSIZE - 1); } else { strcpy(handle, "(unknown)"); } if (INFORM || VERBOSE || DEBUG) { snprintf(output, CF_BUFSIZE - 1, "I: Report relates to a promise with handle \"%s\"", handle); AppendItem(&mess, output, NULL); } if (pp && pp->audit) { snprintf(output, CF_BUFSIZE - 1, "I: Made in version \'%s\' of \'%s\' near line %zu", v, pp->audit->filename, pp->offset.line); } else { snprintf(output, CF_BUFSIZE - 1, "I: Promise is made internally by cfengine"); } AppendItem(&mess, output, NULL); if (pp != NULL) { switch (pp->promisee.rtype) { case CF_SCALAR: snprintf(output, CF_BUFSIZE - 1, "I: The promise was made to: \'%s\'", (char *) pp->promisee.item); AppendItem(&mess, output, NULL); break; case CF_LIST: snprintf(output, CF_BUFSIZE - 1, "I: The promise was made to (stakeholders): "); PrintRlist(output+strlen(output), CF_BUFSIZE, (Rlist *)pp->promisee.item); AppendItem(&mess, output, NULL); break; } if (pp->ref) { snprintf(output, CF_BUFSIZE - 1, "I: Comment: %s\n", pp->ref); AppendItem(&mess, output, NULL); } } } verbose = (attr.transaction.report_level == cf_verbose) || VERBOSE; switch (level) { case cf_inform: if (INFORM || verbose || DEBUG || attr.transaction.report_level == cf_inform) { LogList(stdout, mess, verbose); } if (attr.transaction.log_level == cf_inform) { MakeLog(mess, level); } break; case cf_reporting: case cf_cmdout: if (attr.report.to_file) { FileReport(mess, verbose, attr.report.to_file); } else { LogList(stdout, mess, verbose); } if (attr.transaction.log_level == cf_inform) { MakeLog(mess, level); } break; case cf_verbose: if (verbose || DEBUG) { LogList(stdout, mess, verbose); } if (attr.transaction.log_level == cf_verbose) { MakeLog(mess, level); } break; case cf_error: if (attr.report.to_file) { FileReport(mess, verbose, attr.report.to_file); } else { LogList(stdout, mess, verbose); } if (attr.transaction.log_level == cf_error) { MakeLog(mess, level); } break; case cf_log: MakeLog(mess, level); break; default: break; } if (pp != NULL) { LogPromiseResult(pp->promiser, pp->promisee.rtype, pp->promisee.item, status, attr.transaction.log_level, mess); } /* Now complete the exits status classes and auditing */ if (pp != NULL) { for (ip = mess; ip != NULL; ip = ip->next) { ClassAuditLog(pp, attr, ip->name, status, buffer); } } DeleteItemList(mess); }
/* * Common functionality of CfFOut and CfOut. */ static void VLog(FILE *fh, enum cfreport level, const char *errstr, const char *fmt, va_list args) { char buffer[CF_BUFSIZE], output[CF_BUFSIZE]; Item *mess = NULL; if ((fmt == NULL) || (strlen(fmt) == 0)) { return; } memset(output, 0, CF_BUFSIZE); vsnprintf(buffer, CF_BUFSIZE - 1, fmt, args); Chop(buffer); AppendItem(&mess, buffer, NULL); if ((errstr == NULL) || (strlen(errstr) > 0)) { snprintf(output, CF_BUFSIZE - 1, " !!! System reports error for %s: \"%s\"", errstr, GetErrorStr()); AppendItem(&mess, output, NULL); } switch (level) { case cf_inform: if (INFORM || VERBOSE || DEBUG) { LogList(fh, mess, VERBOSE); } break; case cf_verbose: if (VERBOSE || DEBUG) { LogList(fh, mess, VERBOSE); } break; case cf_error: case cf_reporting: case cf_cmdout: LogList(fh, mess, VERBOSE); MakeLog(mess, level); break; case cf_log: if (VERBOSE || DEBUG) { LogList(fh, mess, VERBOSE); } MakeLog(mess, cf_verbose); break; default: FatalError("Report level unknown"); break; } DeleteItemList(mess); }
static void MonLogSymbolicValue(EvalContext *ctx, const char *handle, Item *stream, Attributes a, const Promise *pp, PromiseResult *result) { char value[CF_BUFSIZE], sdate[CF_MAXVARSIZE], filename[CF_BUFSIZE], *v; int count = 1, found = false, match_count = 0; Item *ip, *match = NULL, *matches = NULL; time_t now = time(NULL); FILE *fout; if (stream == NULL) { Log(LOG_LEVEL_VERBOSE, "No stream to measure"); return; } Log(LOG_LEVEL_VERBOSE, "Locate and log sample ..."); for (ip = stream; ip != NULL; ip = ip->next) { if (ip->name == NULL) { continue; } if (count == a.measure.select_line_number) { Log(LOG_LEVEL_VERBOSE, "Found line %d by number...", count); found = true; match_count = 1; match = ip; if (a.measure.extraction_regex) { Log(LOG_LEVEL_VERBOSE, "Now looking for a matching extractor \"%s\"", a.measure.extraction_regex); strncpy(value, ExtractFirstReference(a.measure.extraction_regex, match->name), CF_MAXVARSIZE - 1); Log(LOG_LEVEL_INFO, "Extracted value \"%s\" for promise \"%s\"", value, handle); AppendItem(&matches, value, NULL); } break; } if (a.measure.select_line_matching && StringMatchFull(a.measure.select_line_matching, ip->name)) { Log(LOG_LEVEL_VERBOSE, "Found line %d by pattern...", count); found = true; match = ip; match_count++; if (a.measure.extraction_regex) { Log(LOG_LEVEL_VERBOSE, "Now looking for a matching extractor \"%s\"", a.measure.extraction_regex); strncpy(value, ExtractFirstReference(a.measure.extraction_regex, match->name), CF_MAXVARSIZE - 1); Log(LOG_LEVEL_INFO, "Extracted value \"%s\" for promise \"%s\"", value, handle); AppendItem(&matches, value, NULL); } } count++; } if (!found) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Promiser '%s' found no matching line.", pp->promiser); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return; } if (match_count > 1) { Log(LOG_LEVEL_INFO, "Warning: %d lines matched the line_selection \"%s\"- matching to last", match_count, a.measure.select_line_matching); } switch (a.measure.data_type) { case CF_DATA_TYPE_COUNTER: Log(LOG_LEVEL_VERBOSE, "Counted %d for %s", match_count, handle); snprintf(value, CF_MAXVARSIZE, "%d", match_count); break; case CF_DATA_TYPE_STRING_LIST: v = ItemList2CSV(matches); snprintf(value, CF_BUFSIZE, "%s", v); free(v); break; default: snprintf(value, CF_BUFSIZE, "%s", matches->name); } DeleteItemList(matches); if (a.measure.history_type && strcmp(a.measure.history_type, "log") == 0) { snprintf(filename, CF_BUFSIZE, "%s%cstate%c%s_measure.log", CFWORKDIR, FILE_SEPARATOR, FILE_SEPARATOR, handle); if ((fout = fopen(filename, "a")) == NULL) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Unable to open the output log \"%s\"", filename); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); PromiseRef(LOG_LEVEL_ERR, pp); return; } strncpy(sdate, ctime(&now), CF_MAXVARSIZE - 1); if (Chop(sdate, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } fprintf(fout, "%s,%ld,%s\n", sdate, (long) now, value); Log(LOG_LEVEL_VERBOSE, "Logging: %s,%s to %s", sdate, value, filename); fclose(fout); } else // scalar or static { CF_DB *dbp; char id[CF_MAXVARSIZE]; if (!OpenDB(&dbp, dbid_static)) { return; } snprintf(id, CF_MAXVARSIZE - 1, "%s:%d", handle, a.measure.data_type); WriteDB(dbp, id, value, strlen(value) + 1); CloseDB(dbp); } }
void Drift_correction() { //Compensation the Roll, Pitch and Yaw drift. static float Scaled_Omega_P[3]; static float Scaled_Omega_I[3]; float Accel_magnitude; float Accel_weight; float Integrator_magnitude; // Local Working Variables float errorRollPitch[3]; float errorYaw[3]; float errorCourse; //*****Roll and Pitch*************** // Calculate the magnitude of the accelerometer vector Accel_magnitude = sqrtf(accel_float.x * accel_float.x + accel_float.y * accel_float.y + accel_float.z * accel_float.z); Accel_magnitude = Accel_magnitude / GRAVITY; // Scale to gravity. // Dynamic weighting of accelerometer info (reliability filter) // Weight for accelerometer info (<0.5G = 0.0, 1G = 1.0 , >1.5G = 0.0) Accel_weight = Chop(1 - 2 * fabs(1 - Accel_magnitude), 0, 1); // #if PERFORMANCE_REPORTING == 1 { //amount added was determined to give imu_health a time constant about twice the time constant of the roll/pitch drift correction float tempfloat = ((Accel_weight - 0.5) * 256.0f); imu_health += tempfloat; Bound(imu_health, 129, 65405); } #endif Vector_Cross_Product(&errorRollPitch[0], &accel_float.x, &DCM_Matrix[2][0]); //adjust the ground of reference Vector_Scale(&Omega_P[0], &errorRollPitch[0], Kp_ROLLPITCH * Accel_weight); Vector_Scale(&Scaled_Omega_I[0], &errorRollPitch[0], Ki_ROLLPITCH * Accel_weight); Vector_Add(Omega_I, Omega_I, Scaled_Omega_I); //*****YAW*************** #if USE_MAGNETOMETER // We make the gyro YAW drift correction based on compass magnetic heading // float mag_heading_x = cos(MAG_Heading); // float mag_heading_y = sin(MAG_Heading); // 2D dot product //Calculating YAW error errorCourse = (DCM_Matrix[0][0] * MAG_Heading_Y) + (DCM_Matrix[1][0] * MAG_Heading_X); //Applys the yaw correction to the XYZ rotation of the aircraft, depeding the position. Vector_Scale(errorYaw, &DCM_Matrix[2][0], errorCourse); Vector_Scale(&Scaled_Omega_P[0], &errorYaw[0], Kp_YAW); Vector_Add(Omega_P, Omega_P, Scaled_Omega_P); //Adding Proportional. Vector_Scale(&Scaled_Omega_I[0], &errorYaw[0], Ki_YAW); Vector_Add(Omega_I, Omega_I, Scaled_Omega_I); //adding integrator to the Omega_I #else // Use GPS Ground course to correct yaw gyro drift if (ahrs_dcm.gps_course_valid) { float course = ahrs_dcm.gps_course - M_PI; //This is the runaway direction of you "plane" in rad float COGX = cosf(course); //Course overground X axis float COGY = sinf(course); //Course overground Y axis errorCourse = (DCM_Matrix[0][0] * COGY) - (DCM_Matrix[1][0] * COGX); //Calculating YAW error //Applys the yaw correction to the XYZ rotation of the aircraft, depeding the position. Vector_Scale(errorYaw, &DCM_Matrix[2][0], errorCourse); Vector_Scale(&Scaled_Omega_P[0], &errorYaw[0], Kp_YAW); Vector_Add(Omega_P, Omega_P, Scaled_Omega_P); //Adding Proportional. Vector_Scale(&Scaled_Omega_I[0], &errorYaw[0], Ki_YAW); Vector_Add(Omega_I, Omega_I, Scaled_Omega_I); //adding integrator to the Omega_I } #if USE_MAGNETOMETER_ONGROUND == 1 PRINT_CONFIG_MSG("AHRS_FLOAT_DCM uses magnetometer prior to takeoff and GPS during flight") else if (launch == FALSE) { float COGX = mag->x; // Non-Tilt-Compensated (for filter stability reasons) float COGY = mag->y; // Non-Tilt-Compensated (for filter stability reasons) errorCourse = (DCM_Matrix[0][0] * COGY) - (DCM_Matrix[1][0] * COGX); //Calculating YAW error //Applys the yaw correction to the XYZ rotation of the aircraft, depeding the position. Vector_Scale(errorYaw, &DCM_Matrix[2][0], errorCourse); // P only Vector_Scale(&Scaled_Omega_P[0], &errorYaw[0], Kp_YAW / 10.0); Vector_Add(Omega_P, Omega_P, Scaled_Omega_P); //Adding Proportional.fi } #endif // USE_MAGNETOMETER_ONGROUND #endif // Here we will place a limit on the integrator so that the integrator cannot ever exceed half the saturation limit of the gyros Integrator_magnitude = sqrt(Vector_Dot_Product(Omega_I, Omega_I)); if (Integrator_magnitude > RadOfDeg(300)) { Vector_Scale(Omega_I, Omega_I, 0.5f * RadOfDeg(300) / Integrator_magnitude); } }
static int HailServer(const EvalContext *ctx, const GenericAgentConfig *config, char *host) { assert(host != NULL); AgentConnection *conn; char hostkey[CF_HOSTKEY_STRING_SIZE], user[CF_SMALLBUF]; bool gotkey; char reply[8]; bool trustkey = false; char *hostname, *port; ParseHostPort(host, &hostname, &port); if (hostname == NULL) { Log(LOG_LEVEL_INFO, "No remote hosts were specified to connect to"); return false; } if (port == NULL) { port = "5308"; } char ipaddr[CF_MAX_IP_LEN]; if (Hostname2IPString(ipaddr, hostname, sizeof(ipaddr)) == -1) { Log(LOG_LEVEL_ERR, "HailServer: ERROR, could not resolve '%s'", hostname); return false; } Address2Hostkey(hostkey, sizeof(hostkey), ipaddr); GetCurrentUserName(user, sizeof(user)); if (INTERACTIVE) { Log(LOG_LEVEL_VERBOSE, "Using interactive key trust..."); gotkey = HavePublicKey(user, ipaddr, hostkey) != NULL; if (!gotkey) { /* TODO print the hash of the connecting host. But to do that we * should open the connection first, and somehow pass that hash * here! redmine#7212 */ printf("WARNING - You do not have a public key from host %s = %s\n", hostname, ipaddr); printf(" Do you want to accept one on trust? (yes/no)\n\n--> "); while (true) { if (fgets(reply, sizeof(reply), stdin) == NULL) { FatalError(ctx, "EOF trying to read answer from terminal"); } if (Chop(reply, CF_EXPANDSIZE) == -1) { Log(LOG_LEVEL_ERR, "Chop was called on a string that seemed to have no terminator"); } if (strcmp(reply, "yes") == 0) { printf("Will trust the key...\n"); trustkey = true; break; } else if (strcmp(reply, "no") == 0) { printf("Will not trust the key...\n"); trustkey = false; break; } else { printf("Please reply yes or no...(%s)\n", reply); } } } } #ifndef __MINGW32__ if (BACKGROUND) { Log(LOG_LEVEL_INFO, "Hailing %s : %s (in the background)", hostname, port); } else #endif { Log(LOG_LEVEL_INFO, "........................................................................"); Log(LOG_LEVEL_INFO, "Hailing %s : %s", hostname, port); Log(LOG_LEVEL_INFO, "........................................................................"); } ConnectionFlags connflags = { .protocol_version = config->protocol_version, .trust_server = trustkey }; int err = 0; conn = ServerConnection(hostname, port, CONNTIMEOUT, connflags, &err); if (conn == NULL) { Log(LOG_LEVEL_ERR, "Failed to connect to host: %s", hostname); return false; } /* Send EXEC command. */ HailExec(conn, hostname); return true; } /********************************************************************/ /* Level 2 */ /********************************************************************/ static void KeepControlPromises(EvalContext *ctx, const Policy *policy) { Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_RUNAGENT); if (constraints) { for (size_t i = 0; i < SeqLength(constraints); i++) { Constraint *cp = SeqAt(constraints, i); if (!IsDefinedClass(ctx, cp->classes)) { continue; } VarRef *ref = VarRefParseFromScope(cp->lval, "control_runagent"); DataType value_type; const void *value = EvalContextVariableGet(ctx, ref, &value_type); VarRefDestroy(ref); /* If var not found, or if it's an empty list. */ if (value_type == CF_DATA_TYPE_NONE || value == NULL) { Log(LOG_LEVEL_ERR, "Unknown lval '%s' in runagent control body", cp->lval); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_FORCE_IPV4].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TRUSTKEY].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_ENCRYPT].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_PORT_NUMBER].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_BACKGROUND].lval) == 0) { /* * Only process this option if are is no -b or -i options specified on * command line. */ if (BACKGROUND || INTERACTIVE) { Log(LOG_LEVEL_WARNING, "'background_children' setting from 'body runagent control' is overridden by command-line option."); } else { BACKGROUND = BooleanFromString(value); } continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_MAX_CHILD].lval) == 0) { MAXCHILD = (short) IntFromString(value); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_TO_FILE].lval) == 0) { OUTPUT_TO_FILE = BooleanFromString(value); continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_OUTPUT_DIRECTORY].lval) == 0) { if (IsAbsPath(value)) { strlcpy(OUTPUT_DIRECTORY, value, CF_BUFSIZE); Log(LOG_LEVEL_VERBOSE, "Setting output direcory to '%s'", OUTPUT_DIRECTORY); } continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_TIMEOUT].lval) == 0) { continue; } if (strcmp(cp->lval, CFR_CONTROLBODY[RUNAGENT_CONTROL_HOSTS].lval) == 0) { if (HOSTLIST == NULL) // Don't override if command line setting { HOSTLIST = value; } continue; } } } const char *expire_after = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER); if (expire_after) { LASTSEENEXPIREAFTER = IntFromString(expire_after) * 60; } }
String *SwigType_str(SwigType *s, const String_or_char *id) { String *result; String *element = 0, *nextelement; List *elements; int nelements, i; if (id) { result = NewString(id); } else { result = NewStringEmpty(); } elements = SwigType_split(s); nelements = Len(elements); if (nelements > 0) { element = Getitem(elements, 0); } /* Now, walk the type list and start emitting */ for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements, i + 1); } else { nextelement = 0; } if (SwigType_isqualifier(element)) { DOH *q = 0; q = SwigType_parm(element); Insert(result, 0, " "); Insert(result, 0, q); Delete(q); } else if (SwigType_ispointer(element)) { Insert(result, 0, "*"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result, 0, "("); Append(result, ")"); } } else if (SwigType_ismemberpointer(element)) { String *q; q = SwigType_parm(element); Insert(result, 0, "::*"); Insert(result, 0, q); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result, 0, "("); Append(result, ")"); } Delete(q); } else if (SwigType_isreference(element)) { Insert(result, 0, "&"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result, 0, "("); Append(result, ")"); } } else if (SwigType_isarray(element)) { DOH *size; Append(result, "["); size = SwigType_parm(element); Append(result, size); Append(result, "]"); Delete(size); } else if (SwigType_isfunction(element)) { DOH *parms, *p; int j, plen; Append(result, "("); parms = SwigType_parmlist(element); plen = Len(parms); for (j = 0; j < plen; j++) { p = SwigType_str(Getitem(parms, j), 0); Append(result, p); if (j < (plen - 1)) Append(result, ","); } Append(result, ")"); Delete(parms); } else { if (strcmp(Char(element), "v(...)") == 0) { Insert(result, 0, "..."); } else { String *bs = SwigType_namestr(element); Insert(result, 0, " "); Insert(result, 0, bs); Delete(bs); } } element = nextelement; } Delete(elements); Chop(result); return result; }
void Drift_correction(void) { //Compensation the Roll, Pitch and Yaw drift. static float Scaled_Omega_P[3]; static float Scaled_Omega_I[3]; float Accel_magnitude; float Accel_weight; float Integrator_magnitude; // Local Working Variables float errorRollPitch[3]; float errorYaw[3]; float errorCourse; // ***** Roll and Pitch *************** // Calculate the magnitude of the accelerometer vector Accel_magnitude = sqrt(accel_float.x*accel_float.x + accel_float.y*accel_float.y + accel_float.z*accel_float.z); Accel_magnitude = Accel_magnitude / GRAVITY; // Scale to gravity. // Dynamic weighting of accelerometer info (reliability filter) // Weight for accelerometer info (<0.5G = 0.0, 1G = 1.0 , >1.5G = 0.0) Accel_weight = Chop(1 - 2*fabs(1 - Accel_magnitude),0,1); // #if PERFORMANCE_REPORTING == 1 { // amount added was determined to give imu_health a time constant about // twice the time constant of the roll/pitch drift correction float tempfloat = ((Accel_weight - 0.5f) * 256.0f); imu_health += tempfloat; Bound(imu_health,129,65405); } #endif //adjust the ground of reference Vector_Cross_Product(&errorRollPitch[0],&accel_float.x,&DCM_Matrix[2][0]); Vector_Scale(&Omega_P[0],&errorRollPitch[0],Kp_ROLLPITCH*Accel_weight); Vector_Scale(&Scaled_Omega_I[0],&errorRollPitch[0],Ki_ROLLPITCH*Accel_weight); Vector_Add(Omega_I,Omega_I,Scaled_Omega_I); // ***** Yaw *************** #ifdef USE_MAGNETOMETER // We make the gyro YAW drift correction based on compass magnetic heading float mag_heading_x = cosf(MAG_Heading); float mag_heading_y = sinf(MAG_Heading); //Calculating YAW error errorCourse=(DCM_Matrix[0][0]*mag_heading_y) - (DCM_Matrix[1][0]*mag_heading_x); // Applys the yaw correction to the XYZ rotation of the aircraft, // depeding the position. Vector_Scale(errorYaw,&DCM_Matrix[2][0],errorCourse); Vector_Scale(&Scaled_Omega_P[0],&errorYaw[0],Kp_YAW); Vector_Add(Omega_P,Omega_P,Scaled_Omega_P);//Adding Proportional. Vector_Scale(&Scaled_Omega_I[0],&errorYaw[0],Ki_YAW); Vector_Add(Omega_I,Omega_I,Scaled_Omega_I);//adding integrator to the Omega_I #elif defined USE_GPS // Use GPS Ground course to correct yaw gyro drift //got a 3d fix and ground speed is more than 0.5 m/s if(gps_mode==3 && gps_gspeed>= 500) { //This is the runaway direction of you "plane" in degrees float ground_course = gps_course/10. - 180.; float COGX = cosf(RadOfDeg(ground_course)); //Course overground X axis float COGY = sinf(RadOfDeg(ground_course)); //Course overground Y axis //Calculating YAW error errorCourse=(DCM_Matrix[0][0]*COGY) - (DCM_Matrix[1][0]*COGX); // Applys the yaw correction to the XYZ rotation of the aircraft, // depeding the position. Vector_Scale(errorYaw,&DCM_Matrix[2][0],errorCourse); Vector_Scale(&Scaled_Omega_P[0],&errorYaw[0],Kp_YAW); //Adding Proportional. Vector_Add(Omega_P,Omega_P,Scaled_Omega_P); Vector_Scale(&Scaled_Omega_I[0],&errorYaw[0],Ki_YAW); //adding integrator to the Omega_I Vector_Add(Omega_I,Omega_I,Scaled_Omega_I); } #endif // Here we will place a limit on the integrator so that the integrator cannot // ever exceed half the saturation limit of the gyros Integrator_magnitude = sqrt(Vector_Dot_Product(Omega_I,Omega_I)); if (Integrator_magnitude > DegOfRad(300)) { Vector_Scale(Omega_I,Omega_I,0.5f*DegOfRad(300)/Integrator_magnitude); } }