static size_t skip_delim (struct wordsplit *wsp) { size_t start = wsp->ws_endp; if (wsp->ws_flags & WRDSF_SQUEEZE_DELIMS) { if ((wsp->ws_flags & WRDSF_RETURN_DELIMS) && ISDELIM (wsp, wsp->ws_input[start])) { int delim = wsp->ws_input[start]; do start++; while (start < wsp->ws_len && delim == wsp->ws_input[start]); } else { do start++; while (start < wsp->ws_len && ISDELIM (wsp, wsp->ws_input[start])); } start--; } if (!(wsp->ws_flags & WRDSF_RETURN_DELIMS)) start++; return start; }
static size_t gettok (struct imap4d_tokbuf *tok, size_t off) { char *buf = tok->buffer; while (off < tok->level && mu_isblank (buf[off])) off++; if (tok->argc == tok->argmax) { if (tok->argmax == 0) tok->argmax = 16; else tok->argmax *= 2; tok->argp = realloc (tok->argp, tok->argmax * sizeof (tok->argp[0])); if (!tok->argp) imap4d_bye (ERR_NO_MEM); } if (buf[off] == '"') { char *start = buf + off + 1; char *p = NULL; while (*start && (p = strchr (start, '"'))) { if (p == start || p[-1] != '\\') break; start = p + 1; } if (p) { size_t len; off++; len = unquote (buf + off, p - (buf + off)); buf[off + len] = 0; tok->argp[tok->argc++] = off; return p - buf + 1; } } tok->argp[tok->argc++] = off; if (ISDELIM (buf[off])) return insert_nul (tok, off + 1); while (off < tok->level && !mu_isblank (buf[off])) { if (ISDELIM (buf[off])) return insert_nul (tok, off); off++; } insert_nul (tok, off); return off + 1; }
/* return pointer to first line delim in our receive buffer, or NULL if none */ static char * find_delim(struct readctx *rctx) { *rctx->eptr = '\0'; // for tracing for (char *ptr = rctx->wptr; ptr < rctx->eptr; ptr++) if (ISDELIM(*ptr)) return ptr; return NULL; }
/* Documented in io.h */ int lsi_io_read(sckhld sh, struct readctx *rctx, tokarr *tok, uint64_t to_us) { uint64_t tend = to_us ? lsi_b_tstamp_us() + to_us : 0; uint64_t tnow, trem = 0; V("Wanna read with%s timeout (%"PRIu64"). %zu bytes in buffer: '%.*s'", tend?"":" no", to_us, rctx->eptr - rctx->wptr, (int)(rctx->eptr - rctx->wptr), rctx->wptr); while (rctx->wptr < rctx->eptr && ISDELIM(*rctx->wptr)) rctx->wptr++; /* skip leading line delimiters */ if (rctx->wptr == rctx->eptr) { /* empty buffer, use the opportunity.. */ rctx->wptr = rctx->eptr = rctx->workbuf; V("Opportunistical buffer reset"); } size_t linelen; char *delim; char *linestart; do { while (!(delim = find_delim(rctx))) { if (tend) { tnow = lsi_b_tstamp_us(); trem = tnow >= tend ? 1 : tend - tnow; } int r = read_more(sh, rctx, trem); if (r <= 0) return r; } linestart = rctx->wptr; linelen = delim - linestart; rctx->wptr++; V("Delim found, linelen %zu", linelen); } while (linelen == 0); rctx->wptr += linelen; *delim = '\0'; I("Read: '%s'", linestart); return lsi_ut_tokenize(linestart, tok) ? 1 : -1; }
static int scan_word (struct wordsplit *wsp, size_t start) { size_t len = wsp->ws_len; const char *command = wsp->ws_input; const char *comment = wsp->ws_comment; int join = 0; int flags = 0; size_t i = start; if (i >= len) { wsp->ws_errno = WRDSE_EOF; return _WRDS_EOF; } start = i; if (wsp->ws_flags & WRDSF_SED_EXPR && command[i] == 's' && i + 3 < len && ISPUNCT (command[i + 1])) { flags = _WSNF_SEXP; i = skip_sed_expr (command, i, len); } else if (!ISDELIM (wsp, command[i])) { while (i < len) { if (comment && strchr (comment, command[i]) != NULL) { size_t j; for (j = i + 1; j < len && command[j] != '\n'; j++) ; if (wordsplit_add_segm (wsp, start, i, 0)) return _WRDS_ERR; wsp->ws_endp = j; return _WRDS_OK; } if (wsp->ws_flags & WRDSF_QUOTE) { if (command[i] == '\\') { if (++i == len) break; i++; continue; } if (((wsp->ws_flags & WRDSF_SQUOTE) && command[i] == '\'') || ((wsp->ws_flags & WRDSF_DQUOTE) && command[i] == '"')) { if (join && wsp->ws_tail) wsp->ws_tail->flags |= _WSNF_JOIN; if (wordsplit_add_segm (wsp, start, i, _WSNF_JOIN)) return _WRDS_ERR; if (scan_qstring (wsp, i, &i)) return _WRDS_ERR; start = i + 1; join = 1; } } if (ISDELIM (wsp, command[i])) break; else i++; } } else if (wsp->ws_flags & WRDSF_RETURN_DELIMS) { i++; } else if (!(wsp->ws_flags & WRDSF_SQUEEZE_DELIMS)) flags |= _WSNF_EMPTYOK; if (join && i > start && wsp->ws_tail) wsp->ws_tail->flags |= _WSNF_JOIN; if (wordsplit_add_segm (wsp, start, i, flags)) return _WRDS_ERR; wsp->ws_endp = i; if (wsp->ws_flags & WRDSF_INCREMENTAL) return _WRDS_EOF; return _WRDS_OK; }
static void parseconfigline (char *buf, unsigned int line, zconf_t *z) { char *end, *val, *p; char *tag; unsigned int len, found; zconf_para_t *c; assert (buf[0] != '\0'); p = &buf[strlen(buf)-1]; /* Chop off white space at eol */ while ( p >= buf && isspace (*p) ) *p-- = '\0'; for (p = buf; isspace (*p); p++ ) /* Ignore leading white space */ ; /* Ignore comments and emtpy lines */ if ( *p == '\0' || ISCOMMENT (p) ) return; tag = p; /* Get the end of the first argument */ end = &buf[strlen(buf)-1]; while ( p < end && !ISDELIM (*p) ) /* Skip until delim */ p++; *p++ = '\0'; /* Terminate this argument */ dbg_val1 ("Parsing \"%s\"\n", tag); while ( p < end && ISDELIM (*p) ) /* Skip delim chars */ p++; val = p; /* Start of the value */ dbg_val1 ("\tgot value \"%s\"\n", val); /* If starting with quote, skip until next quote */ if ( *p == '"' || *p == '\'' ) { p++; /* Find next quote */ while ( p <= end && *p && *p != *val ) p++; *p = '\0'; val++; /* Skip the first quote */ } else /* Otherwise check if there is any comment char at the end */ { while ( p < end && *p && !ISCOMMENT(p) ) p++; if ( ISCOMMENT (p) ) { do /* Chop off white space before comment */ *p-- = '\0'; while ( p >= val && isspace (*p) ); } } /* Otherwise it is already terminated above */ found = 0; c = confpara; while ( !found && c->type != CONF_END ) { len = strlen (c->label); if ( strcasecmp (tag, c->label) == 0 ) { char **str; char quantity; long lval; found = 1; switch ( c->type ) { case CONF_LEVEL: case CONF_FACILITY: case CONF_STRING: str = (char **)c->var; *str = strdup (val); str_untaint (*str); /* remove "bad" characters */ break; case CONF_INT: sscanf (val, "%d", (int *)c->var); break; case CONF_TIMEINT: quantity = 'd'; sscanf (val, "%ld%c", &lval, &quantity); if ( quantity == 'm' ) lval *= MINSEC; else if ( quantity == 'h' ) lval *= HOURSEC; else if ( quantity == 'd' ) lval *= DAYSEC; else if ( quantity == 'w' ) lval *= WEEKSEC; else if ( quantity == 'y' ) lval *= YEARSEC; (*(long *)c->var) = lval; break; case CONF_ALGO: if ( strcasecmp (val, "rsa") == 0 || strcasecmp (val, "rsamd5") == 0 ) *((int *)c->var) = DK_ALGO_RSA; else if ( strcasecmp (val, "dsa") == 0 ) *((int *)c->var) = DK_ALGO_DSA; else if ( strcasecmp (val, "rsasha1") == 0 ) *((int *)c->var) = DK_ALGO_RSASHA1; else if ( strcasecmp (val, "nsec3dsa") == 0 || strcasecmp (val, "n3dsa") == 0 ) *((int *)c->var) = DK_ALGO_NSEC3DSA; else if ( strcasecmp (val, "nsec3rsasha1") == 0 || strcasecmp (val, "n3rsasha1") == 0 ) *((int *)c->var) = DK_ALGO_NSEC3RSASHA1; else error ("Illegal algorithm \"%s\" " "in line %d.\n" , val, line); break; case CONF_SERIAL: if ( strcasecmp (val, "unixtime") == 0 ) *((serial_form_t *)c->var) = Unixtime; else if ( strcasecmp (val, "incremental") == 0 ) *((serial_form_t *)c->var) = Incremental; else error ("Illegal serial no format \"%s\" " "in line %d.\n" , val, line); break; case CONF_BOOL: *((int *)c->var) = ISTRUE (val); break; default: fatal ("Illegal configuration type in line %d.\n", line); } } c++; } if ( !found ) error ("Unknown configuration statement: %s \"%s\"\n", tag, val); return; }