/* * doaddvlist - add variable(s) to the variable list */ static void doaddvlist( struct varlist *vlist, const char *vars ) { register struct varlist *vl; int len; char *name; char *value; len = strlen(vars); while (nextvar(&len, &vars, &name, &value)) { vl = findlistvar(vlist, name); if (vl == 0) { (void) fprintf(stderr, "Variable list full\n"); return; } if (vl->name == 0) { vl->name = estrdup(name); } else if (vl->value != 0) { free(vl->value); vl->value = 0; } if (value != 0) vl->value = estrdup(value); } }
/* * dormvlist - remove variable(s) from the variable list */ static void dormvlist( struct varlist *vlist, const char *vars ) { register struct varlist *vl; int len; char *name; char *value; len = strlen(vars); while (nextvar(&len, &vars, &name, &value)) { vl = findlistvar(vlist, name); if (vl == 0 || vl->name == 0) { (void) fprintf(stderr, "Variable `%s' not found\n", name); } else { free((void *)vl->name); if (vl->value != 0) free(vl->value); for ( ; (vl+1) < (g_varlist + MAXLIST) && (vl+1)->name != 0; vl++) { vl->name = (vl+1)->name; vl->value = (vl+1)->value; } vl->name = vl->value = 0; } } }
size_t ntpq_getvar( const char * resultbuf, size_t datalen, const char * varname, char * varvalue, size_t maxlen) { char * name; char * value; int idatalen; value = NULL; idatalen = (int)datalen; while (nextvar(&idatalen, &resultbuf, &name, &value)) { if (strcmp(varname, name) == 0) { ntpq_stripquotes(varvalue, value, strlen(value), maxlen); return strlen(varvalue); } } return 0; }
bool Scope::visitASTExprReturn(AST::Node& node) { assert(node.rule == AST::rgReturn); // assert(not node.children.empty()); -- a return may be empty bool success = true; bool hasReturnValue = false; auto& irout = ircode(); for (auto& child : node.children) { switch (child.rule) { case AST::rgExpr: { ir::emit::ScopeLocker opscope{irout}; uint32_t localvar = 0; success &= visitASTExpr(child, localvar); // generate error on the begining of the expr and not the return itself emitDebugpos(child); ir::emit::ret(irout, localvar, ir::emit::alloc(irout, nextvar())); hasReturnValue = true; break; } default: return unexpectedNode(child, "[ir/return]"); } } if (not hasReturnValue) { emitDebugpos(node); ir::emit::ret(irout); } return success; }
bool Scope::visitASTExprStringLiteral(AST::Node& node, uint32_t& localvar) { // when called, this rule represents an internal cstring // thus, this function can not be called by an user-defined string emitDebugpos(node); localvar = ir::emit::alloctext(ircode(), nextvar(), node.text); return true; }
/* * Decode an incoming data buffer and print a line in the peer list */ static int doprintpeers( struct varlist *pvl, int associd, int rstatus, int datalen, const char *data, FILE *fp, int af ) { char *name; char *value = NULL; int i; int c; sockaddr_u srcadr; sockaddr_u dstadr; sockaddr_u refidadr; u_long srcport = 0; char *dstadr_refid = "0.0.0.0"; char *serverlocal; size_t drlen; u_long stratum = 0; long ppoll = 0; long hpoll = 0; u_long reach = 0; l_fp estoffset; l_fp estdelay; l_fp estjitter; l_fp estdisp; l_fp reftime; l_fp rec; l_fp ts; u_char havevar[MAXHAVE]; u_long poll_sec; char type = '?'; char refid_string[10]; char whenbuf[8], pollbuf[8]; char clock_name[LENHOSTNAME]; memset((char *)havevar, 0, sizeof(havevar)); get_systime(&ts); ZERO_SOCK(&srcadr); ZERO_SOCK(&dstadr); /* Initialize by zeroing out estimate variables */ memset((char *)&estoffset, 0, sizeof(l_fp)); memset((char *)&estdelay, 0, sizeof(l_fp)); memset((char *)&estjitter, 0, sizeof(l_fp)); memset((char *)&estdisp, 0, sizeof(l_fp)); while (nextvar(&datalen, &data, &name, &value)) { sockaddr_u dum_store; i = findvar(name, peer_var, 1); if (i == 0) continue; /* don't know this one */ switch (i) { case CP_SRCADR: if (decodenetnum(value, &srcadr)) { havevar[HAVE_SRCADR] = 1; } break; case CP_DSTADR: if (decodenetnum(value, &dum_store)) { type = decodeaddrtype(&dum_store); havevar[HAVE_DSTADR] = 1; dstadr = dum_store; if (pvl == opeervarlist) { dstadr_refid = trunc_left(stoa(&dstadr), 15); } } break; case CP_REFID: if (pvl == peervarlist) { havevar[HAVE_REFID] = 1; if (*value == '\0') { dstadr_refid = ""; } else if (strlen(value) <= 4) { refid_string[0] = '.'; (void) strcpy(&refid_string[1], value); i = strlen(refid_string); refid_string[i] = '.'; refid_string[i+1] = '\0'; dstadr_refid = refid_string; } else if (decodenetnum(value, &refidadr)) { if (SOCK_UNSPEC(&refidadr)) dstadr_refid = "0.0.0.0"; else if (ISREFCLOCKADR(&refidadr)) dstadr_refid = refnumtoa(&refidadr); else dstadr_refid = stoa(&refidadr); } else { havevar[HAVE_REFID] = 0; } } break; case CP_STRATUM: if (decodeuint(value, &stratum)) havevar[HAVE_STRATUM] = 1; break; case CP_HPOLL: if (decodeint(value, &hpoll)) { havevar[HAVE_HPOLL] = 1; if (hpoll < 0) hpoll = NTP_MINPOLL; } break; case CP_PPOLL: if (decodeint(value, &ppoll)) { havevar[HAVE_PPOLL] = 1; if (ppoll < 0) ppoll = NTP_MINPOLL; } break; case CP_REACH: if (decodeuint(value, &reach)) havevar[HAVE_REACH] = 1; break; case CP_DELAY: if (decodetime(value, &estdelay)) havevar[HAVE_DELAY] = 1; break; case CP_OFFSET: if (decodetime(value, &estoffset)) havevar[HAVE_OFFSET] = 1; break; case CP_JITTER: if (pvl == peervarlist) if (decodetime(value, &estjitter)) havevar[HAVE_JITTER] = 1; break; case CP_DISPERSION: if (decodetime(value, &estdisp)) havevar[HAVE_DISPERSION] = 1; break; case CP_REC: if (decodets(value, &rec)) havevar[HAVE_REC] = 1; break; case CP_SRCPORT: if (decodeuint(value, &srcport)) havevar[HAVE_SRCPORT] = 1; break; case CP_REFTIME: havevar[HAVE_REFTIME] = 1; if (!decodets(value, &reftime)) L_CLR(&reftime); break; default: break; } } /* * Check to see if the srcport is NTP's port. If not this probably * isn't a valid peer association. */ if (havevar[HAVE_SRCPORT] && srcport != NTP_PORT) return (1); /* * Got everything, format the line */ poll_sec = 1<<max(min3(ppoll, hpoll, NTP_MAXPOLL), NTP_MINPOLL); if (pktversion > NTP_OLDVERSION) c = flash3[CTL_PEER_STATVAL(rstatus) & 0x7]; else c = flash2[CTL_PEER_STATVAL(rstatus) & 0x3]; if (numhosts > 1) { if (peervarlist == pvl && havevar[HAVE_DSTADR]) { serverlocal = nntohost_col(&dstadr, (size_t)min(LIB_BUFLENGTH - 1, maxhostlen), TRUE); } else { if (currenthostisnum) serverlocal = trunc_left(currenthost, maxhostlen); else serverlocal = currenthost; } fprintf(fp, "%-*s ", maxhostlen, serverlocal); } if (AF_UNSPEC == af || AF(&srcadr) == af) { strncpy(clock_name, nntohost(&srcadr), sizeof(clock_name)); fprintf(fp, "%c%-15.15s ", c, clock_name); drlen = strlen(dstadr_refid); makeascii(drlen, dstadr_refid, fp); while (drlen++ < 15) fputc(' ', fp); fprintf(fp, " %2ld %c %4.4s %4.4s %3lo %7.7s %8.7s %7.7s\n", stratum, type, prettyinterval(whenbuf, sizeof(whenbuf), when(&ts, &rec, &reftime)), prettyinterval(pollbuf, sizeof(pollbuf), (int)poll_sec), reach, lfptoms(&estdelay, 3), lfptoms(&estoffset, 3), (havevar[HAVE_JITTER]) ? lfptoms(&estjitter, 3) : lfptoms(&estdisp, 3)); return (1); } else return(1); }
bool Scope::visitASTExprString(AST::Node& node, uint32_t& localvar) { assert(node.rule == AST::rgString); emitDebugpos(node); // transform string literals into implicit `new string()` // // several patterns can arise for declaring a string: // 1. an empty string: like `var s = ""` // 2. a string with a simple literal: `var s = "hello world"` // 3. or a more complex string, with string interpolation for example // `var w = "world"; var s = "hello \(w) another literal";` (where \(w) is an expr) // create a string object if (!context.reuse.string.createObject) context.prepareReuseForStrings(); bool success = visitASTExprNew(*(context.reuse.string.createObject), localvar); if (unlikely(not success)) return false; auto& irout = ircode(); uint32_t idlvid = ir::emit::alloc(irout, nextvar()); ir::emit::identify(irout, idlvid, "append", localvar); uint32_t calllvid = ir::emit::alloc(irout, nextvar()); ir::emit::identify(irout, calllvid, "^()", idlvid); // functor context.reuse.string.text.clear(); AST::Node* firstLiteralNode = nullptr; auto flush = [&]() { emitDebugpos(*firstLiteralNode); uint32_t sid = ir::emit::alloctext(irout, nextvar(), context.reuse.string.text); uint32_t lid = ir::emit::allocu64(irout, nextvar(), nyt_u32, context.reuse.string.text.size()); uint32_t ret = ir::emit::alloc(irout, nextvar(), nyt_void); ir::emit::push(irout, sid); // text: __text ir::emit::push(irout, lid); // size: __u64 ir::emit::call(irout, ret, calllvid); }; for (auto& child : node.children) { switch (child.rule) { case AST::rgStringLiteral: { if (not child.text.empty()) { context.reuse.string.text += child.text; if (nullptr == firstLiteralNode) firstLiteralNode = &child; } break; } case AST::rgStringInterpolation: { if (child.children.empty()) break; if (not context.reuse.string.text.empty()) { flush(); firstLiteralNode = nullptr; context.reuse.string.text.clear(); } for (auto& expr : child.children) { if (unlikely(expr.rule != AST::rgExpr)) return unexpectedNode(expr, "[string-interpolation]"); // creating a scope for temporary expression (string interpolation) ir::emit::ScopeLocker opscope{irout}; emitDebugpos(expr); uint32_t lvid; if (not visitASTExpr(expr, lvid)) return false; emitDebugpos(expr); uint32_t ret = ir::emit::alloc(irout, nextvar(), nyt_void); ir::emit::push(irout, lvid); ir::emit::call(irout, ret, calllvid); } break; } case AST::rgCharExtended: { if (nullptr == firstLiteralNode) firstLiteralNode = &child; if (child.text.size() == 1) { char c = '\0'; if (not convertCharExtended(c, child.text[0])) return (error(child) << "invalid escaped character '\\" << child.text << '\''); context.reuse.string.text += c; } else { error(child) << "invalid escaped character '\\" << child.text << '\''; return false; } break; } default: { return unexpectedNode(child, "[expr-string]"); } } } if (firstLiteralNode != nullptr) flush(); return true; }