Beispiel #1
0
/* return: the strlen(string), that is, not include the '\0' */
PUBLIC int vsnprintf(char *buf, u32 size, const char *fmt, va_list args)
{
    u32 i, offset, len;
    u8  c;
    u32 d, x;
    char *s, *b;

    char num[11]; /* 2^32 = 4294967296 + '\0' */

    offset = 0;
    memset(buf, 0, size);
    memset(num, 0, sizeof(num));
    len = strlen(fmt);

    for(i=0;i<len;i++) {
        if (fmt[i] == '%') {
            if ((i+1) == len) { /* % is the last char of the string */
                buf_putc(buf, size, &offset, fmt[i]);
                break;
            } else {
                switch (fmt[i+1]) {
                    case ('c'):
                        c = va_arg(args, u32);
                        buf_putc(buf, size, &offset, c);
                        i++;
                        break;
                    case ('d'):
                        d = va_arg(args, u32);
                        b = itoa(num, d, 10);
                        buf_puts(buf, size, &offset, b);
                        i++;
                        break;
                    case ('x'):
                    case ('X'):
                        x = va_arg(args, u32);
                        b = itoa(num, x, 16);
                        if (fmt[i+1] == 'X') { b = &num[2]; };
                        buf_puts(buf, size, &offset, b);
                        i++;
                        break;
                    case ('s'):
                        s = va_arg(args, char *);
                        b = s;
                        if (b == NULL) {
                            buf_puts(buf, size, &offset, "(null)");
                        } else {
                            buf_puts(buf, size, &offset, b);
                        }
                        i++;
                        break;
                    default:
                        buf_putc(buf, size, &offset, fmt[i]);   /* the '%' */
                        break;
                }
            }
        } else {
            /*  ordinary character */
            buf_putc(buf, size, &offset, fmt[i]);
        }
    }
Beispiel #2
0
static void encode(const char *ps, int len, struct buf *buf)
{
    const unsigned char *p = (const unsigned char *)ps;

    buf_reset(buf);
    /* allocate enough space plus a little slop to cover
     * escaping a few characters */
    buf_ensure(buf, len+10);

    for ( ; len > 0 ; len--, p++) {
        switch (*p) {
        case '\0':
        case '\t':
        case '\r':
        case '\n':
            buf_putc(buf, ESCAPE);
            buf_putc(buf, 0x80|(*p));
            break;
        case ESCAPE:
            buf_putc(buf, ESCAPE);
            buf_putc(buf, ESCAPE);
            break;
        default:
            buf_putc(buf, *p);
            break;
        }
    }

    /* ensure the buf is NUL-terminated; we pass the buf's data to
     * bsearch_mem(), which expects a C string, several times */
    buf_cstring(buf);
}
Beispiel #3
0
char* tnfa_toString(TNFA* tnfa){
	StringBuffer* sb = buf_createDefault();
	char* result;
	int i;
	IntEnumeration* ie;
	
	buf_printf(sb,"\nStart state s%d\nFinish state s%d",tnfa->start,tnfa->finish);
	for(i=0;i<tnfa->laststate;i++){
		if(ihtab_contains(tnfa->states,i)){
			TFATrans* t;
			buf_printf(sb,"\ns%d in: %d out: ",i,itoi_get(tnfa->inputOrder,i));
			t= ihtab_get(tnfa->states, i);
			while(t!=NULL){
				if (t->c==0)
					buf_printf(sb,"<s%d,'\\0',%d,%c> ",t->to,t->tag,t->priority);
				else
					buf_printf(sb,"<s%d,'%c',%d,%c> ",t->to,t->c,t->tag,t->priority);
				t=t->next;
			}
		}
	}

	buf_printf(sb,"\n#Tags = %d #Minimized = %d Minimized Tags ={",tnfa->tagcount,iset_size(tnfa->minimized));
	ie = iset_elements(tnfa->minimized);
	while(ienum_hasNext(ie)){
	   buf_printf(sb,"%d",ienum_next(ie));
	   if(ienum_hasNext(ie)) buf_putc(sb,',');
	}
	buf_putc(sb,'}');
	result= buf_toString(sb);
	buf_free(sb);
	return(result);
}
Beispiel #4
0
static void decode(const char *ps, int len, struct buf *buf)
{
    const unsigned char *p = (const unsigned char *)ps;

    buf_reset(buf);
    /* allocate enough space; we don't need slop because
     * decoding can only shrink the result */
    buf_ensure(buf, len);

    for ( ; len > 0 ; len--, p++) {
        if (*p == ESCAPE) {
            if (len < 2) {
                /* invalid encoding, silently ignore */
                continue;
            }
            len--;
            p++;
            if (*p == ESCAPE)
                buf_putc(buf, ESCAPE);
            else
                buf_putc(buf, (*p) & ~0x80);
        }
        else
            buf_putc(buf, *p);
    }
    /* Note: buf is not NUL-terminated.  It happens that neither
     * skiplist nor berkeley backends guarantee any such thing,
     * and so code that depends on it is quite broken anyway */
}
Beispiel #5
0
void
cvs_trigger_loginfo_header(BUF *buf, char *repo)
{
	char *dir, pwd[PATH_MAX];
	char hostname[HOST_NAME_MAX+1];

	if (gethostname(hostname, sizeof(hostname)) == -1) {
		fatal("cvs_trigger_loginfo_header: gethostname failed %s",
		    strerror(errno));
	}

	if (getcwd(pwd, sizeof(pwd)) == NULL)
		fatal("cvs_trigger_loginfo_header: Cannot get working "
		    "directory");

	if ((dir = dirname(pwd)) == NULL) {
		fatal("cvs_trigger_loginfo_header: dirname failed %s",
		    strerror(errno));
	}

	buf_puts(buf, "Update of ");
	buf_puts(buf, current_cvsroot->cr_dir);
	buf_putc(buf, '/');
	buf_puts(buf, repo);
	buf_putc(buf, '\n');

	buf_puts(buf, "In directory ");
	buf_puts(buf, hostname);
	buf_puts(buf, ":");
	buf_puts(buf, dir);
	buf_putc(buf, '/');
	buf_puts(buf, repo);
	buf_putc(buf, '\n');
	buf_putc(buf, '\n');
}
Beispiel #6
0
static void _card_to_tgt(const struct vparse_card *card, struct vparse_target *tgt)
{
    const struct vparse_entry *entry;
    const struct vparse_card *sub;

    if (card->type) {
        _key_to_tgt("BEGIN", tgt);
        buf_putc(tgt->buf, ':');
        _key_to_tgt(card->type, tgt);
        _endline(tgt);
    }

    for (entry = card->properties; entry; entry = entry->next)
        _entry_to_tgt(entry, tgt);

    for (sub = card->objects; sub; sub = sub->next)
        _card_to_tgt(sub, tgt);

    if (card->type) {
        _key_to_tgt("END", tgt);
        buf_putc(tgt->buf, ':');
        _key_to_tgt(card->type, tgt);
        _endline(tgt);
    }
}
Beispiel #7
0
/*
 * Format the seqset `seq' as a string.  Returns a newly allocated
 * string which must be free()d by the caller.
 */
EXPORTED char *seqset_cstring(const struct seqset *seq)
{
    struct buf buf = BUF_INITIALIZER;
    unsigned i;

    if (!seq) return NULL;
    if (!seq->len) return NULL;

    for (i = 0; i < seq->len; i++) {
        /* join with comma if not the first item */
        if (i) buf_putc(&buf, ',');

        /* single value only */
        if (seq->set[i].low == seq->set[i].high)
            format_num(&buf, seq->set[i].low);

        /* value range */
        else {
            format_num(&buf, seq->set[i].low);
            buf_putc(&buf, ':');
            format_num(&buf, seq->set[i].high);
        }
    }

    return buf_release(&buf);
}
Beispiel #8
0
char *ihtab_toString(IntHashtable *p) {
	char *result = NULL;
	StringBuffer *buf = buf_createDefault();   
   IntEnumeration *e;  
   int i = 0;
 
   buf_putc(buf, '{');  
   for(e = ihtab_getKeys(p); ienum_hasNext(e); ) { 
      int curkey = ienum_next(e);
      void *curval = ihtab_get(p, curkey);
      
      if (i > 0) {
      	buf_puts(buf, ", ");
		}

      buf_printf(buf, "%d", curkey);
      buf_putc(buf, '=');
      buf_putp(buf, curval);
      
   	i++;
   }
   buf_putc(buf, '}');
   result = buf_toString(buf);
	free(e);
   
   return result;
}
Beispiel #9
0
static void _value_to_tgt(const char *value, struct vparse_target *tgt, int is_multival)
{
    if (!value) return; /* null fields or array items are empty string */
    for (; *value; value++) {
        _checkwrap(*value, tgt);
        switch (*value) {
        case '\r':
            break;
        case '\n':
            buf_putc(tgt->buf, '\\');
            buf_putc(tgt->buf, 'n');
            break;
        case ';':
            if (is_multival) break;
            /* or fall through */
        case ',':
        case '\\':
            buf_putc(tgt->buf, '\\');
            /* fall through */
        default:
            buf_putc(tgt->buf, *value);
            break;
        }
    }
}
Beispiel #10
0
static void
flacdec_read_vorbis_comment(BitstreamReader *comment,
                            unsigned channel_count,
                            int *channel_mask)
{
    struct bs_buffer *line = buf_new();
    unsigned line_len;
    unsigned total_lines;
    const char mask_prefix[] =
        "WAVEFORMATEXTENSIBLE_CHANNEL_MASK=";

    if (!setjmp(*br_try(comment))) {
        /*skip over vendor string*/
        line_len = comment->read(comment, 32);
        comment->skip_bytes(comment, line_len);

        /*walk through all entries in the comment*/
        for (total_lines = comment->read(comment, 32);
             total_lines > 0;
             total_lines--) {
            const char *s;

            /*populate entry one character at a time
              (this avoids allocating a big chunk of space
               if the length field is something way too large)*/
            buf_reset(line);

            for (line_len = comment->read(comment, 32);
                 line_len > 0;
                 line_len--) {
                buf_putc(
                    toupper((int)comment->read(comment, 8)),
                    line);
            }
            buf_putc(0, line);  /*NULL terminator*/

            s = (const char *)buf_window_start(line);

            /*if line starts with mask prefix*/
            if (strstr(s, mask_prefix) == s) {
                /*convert rest of line to base-16 integer*/
                unsigned mask = (unsigned)strtoul(
                    s + strlen(mask_prefix), NULL, 16);
                /*and populate mask field if its number of channel bits
                  matches the stream's channel count*/
                if (channel_bits(mask) == channel_count) {
                    *channel_mask = mask;
                }
            }
        }
        br_etry(comment);
    } else {
        /*read error in VORBIS_COMMENT
          (probably invalid length field somewhere)*/
        br_etry(comment);
    }

    buf_close(line);
}
Beispiel #11
0
static int make_key(struct buf *buf, const struct jmapauth_token *tok)
{
    /* Concatenate version, kind and the session id */
    buf_putc(buf, tok->version);
    buf_putc(buf, tok->kind);
    buf_appendmap(buf, tok->sessionid, JMAPAUTH_SESSIONID_LEN);
    return 0;
}
Beispiel #12
0
void
case_buf_putc()
{
    struct buf *buf = buf(NULL);
    assert(buf_putc(buf, 'a') == BUF_OK);
    assert(buf_putc(buf, 'b') == BUF_OK);
    assert(buf_putc(buf, 'c') == BUF_OK);
    assert(buf_putc(buf, 'd') == BUF_OK);
    assert(strcmp(str(buf), "abcd") == 0);
    buf_free(buf);
}
Beispiel #13
0
static int _parseqstring(struct dlistsax_state *s, struct buf *buf)
{
    buf->len = 0;

    /* get over the first quote */
    if (*s->p++ != '"') return IMAP_INVALID_IDENTIFIER;

    while (s->p < s->end) {
        /* found the end quote */
        if (*s->p == '"') {
            s->p++;
            return 0;
        }
        /* backslash just quotes the next char, no matter what it is */
        if (*s->p == '\\') {
            s->p++;
            if (s->p == s->end) break;
            /* fall through */
        }

        buf_putc(buf, *s->p++);
    }

    return IMAP_INVALID_IDENTIFIER;
}
Beispiel #14
0
static void format_num(struct buf *buf, unsigned i)
{
    if (i == UINT_MAX)
        buf_putc(buf, '*');
    else
        buf_printf(buf, "%u", i);
}
Beispiel #15
0
PRIVATE u32 buf_puts(char *buf, u32 size, u32 *offset, char *s)
{
    u32 i;
    for(i=0;s[i]!='\0';i++) {
        buf_putc(buf, size, offset, s[i]);
    }
    return 0;
}
Beispiel #16
0
static void _key_to_tgt(const char *key, struct vparse_target *tgt)
{
    /* uppercase keys */
    for (; *key; key++) {
        _checkwrap(*key, tgt);
        //buf_putc(tgt->buf, toupper(*key));
        buf_putc(tgt->buf, *key);
    }
}
Beispiel #17
0
char* 
unescapeStrConst(char* s){
   StringBuffer *tmp = buf_createDefault();
   char* r;
   int i, size = strlen(s);

   for (i = 1; i < size - 1; i++) {
      char c = s[i];
      if(s[i]=='\\') {
         c = s[++i];
         switch (c) {
            case 't':
               buf_puts(tmp, "\t");
               break;
            case 'n':
               buf_puts(tmp, "\n");
               break;
            case 'r':
               buf_puts(tmp, "\r");
               break;
            case 'f':
               buf_puts(tmp, "\f");
               break;
            case '"':
               buf_puts(tmp, "\"");
               break;
            case '\\':
               buf_puts(tmp, "\\");
               break;
            default:
               buf_putc(tmp, c);
               break;
         }
      } else {
         buf_putc(tmp, c);
      }
   }

   r = buf_toString(tmp);
   buf_free (tmp);

   return r;
}
Beispiel #18
0
char* plist_toString(PriorityList* p){
	StringBuffer* sb=buf_createDefault();
	char* result;
	int i;
	if (p==NULL) p=&defaultPList;
	for(i=0;i<p->length;i++){ 
		buf_putc(sb,p->priority[i]); if(i<p->length-1) buf_puts(sb,"<-");
	}
	result = buf_toString(sb);
	buf_free(sb);
	return result;
}
Beispiel #19
0
char *hset_toString(HashSet *p) {
	char *result = NULL;
	StringBuffer *buf = buf_createDefault();   
   Enumeration *e;  
   int i = 0;
   
   for(e = hset_elements(p); enum_hasNext(e); ) { 
      void *curkey = (void *)enum_next(e);
		if (i > 0) {
      	buf_puts(buf, ", ");
		}
      buf_putc(buf, '{');
      buf_puts(buf, curkey);
      buf_putc(buf, '}');
   	i++;
   }
   result = buf_toString(buf);
   free(e);
   
   return result;
}
Beispiel #20
0
static void _checkwrap(unsigned char c, struct vparse_target *tgt)
{
    if (buf_len(tgt->buf) - tgt->last < 75)
        return; /* still short line */

    if (c >= 0x80 && c < 0xC0)
        return; /* never wrap continuation chars */

    /* wrap */
    _endline(tgt);
    buf_putc(tgt->buf, ' ');
}
Beispiel #21
0
static void
import_loginfo(char *repo)
{
	int i;
	char pwd[MAXPATHLEN];

	if (getcwd(pwd, sizeof(pwd)) == NULL)
		fatal("Can't get working directory");

	logbuf = buf_alloc(1024);
	cvs_trigger_loginfo_header(logbuf, repo);

	buf_puts(logbuf, "Log Message:\n");
	buf_puts(logbuf, logmsg);
	if (logmsg[0] != '\0' && logmsg[strlen(logmsg) - 1] != '\n')
		buf_putc(logbuf, '\n');
	buf_putc(logbuf, '\n');

	buf_puts(logbuf, "Status:\n\n");

	buf_puts(logbuf, "Vendor Tag:\t");
	buf_puts(logbuf, vendor_tag);
	buf_putc(logbuf, '\n');
	buf_puts(logbuf, "Release Tags:\t");

	for (i = 0; i < tagcount ; i++) {
		buf_puts(logbuf, "\t\t");
		buf_puts(logbuf, release_tags[i]);
		buf_putc(logbuf, '\n');
	}
	buf_putc(logbuf, '\n');
	buf_putc(logbuf, '\n');
}
Beispiel #22
0
char* 
escapeStrConst(char* s){
   StringBuffer *tmp = buf_createDefault();
   char* r;
   int i, size = strlen(s);

   for (i = 0; i < size; i++) {
      char c = s[i];
      switch (c) {
         case '\t':
            buf_puts(tmp, "\\t");
            break;
         case '\n':
            buf_puts(tmp, "\\n");
            break;
         case '\r':
            buf_puts(tmp, "\\r");
            break;
         case '\f':
            buf_puts(tmp, "\\f");
            break;
         case '"':
            buf_putc(tmp, '\\');
            buf_putc(tmp, c);
            break;
         case '\\':
            buf_puts(tmp, "\\\\");
            break;
         default:
            buf_putc(tmp, c);
            break;
      }
   }
  
   r = buf_toString(tmp);
   buf_free(tmp);

   return r;
}
Beispiel #23
0
void
cvs_add_loginfo(char *repo)
{
	BUF *buf;
	char pwd[MAXPATHLEN];

	if (getcwd(pwd, sizeof(pwd)) == NULL)
		fatal("Can't get working directory");

	buf = buf_alloc(1024);

	cvs_trigger_loginfo_header(buf, repo);

	buf_puts(buf, "Log Message:\nDirectory ");
	buf_puts(buf, current_cvsroot->cr_dir);
	buf_putc(buf, '/');
	buf_puts(buf, repo);
	buf_puts(buf, " added to the repository\n");

	buf_putc(buf, '\0');

	loginfo = buf_release(buf);
}
Beispiel #24
0
/*
 * Add an entry to the deny DB.  Message 'msg' may be NULL, resulting
 * in a default message being used.  Service name 'service' may be NULL,
 * resulting in all services being blocked for the user.  The username
 * 'user' is a required argument.  Returns an IMAP error code or 0 on
 * success.
 */
EXPORTED int denydb_set(const char *user, const char *service, const char *msg)
{
    struct txn *txn = NULL;
    struct buf data = BUF_INITIALIZER;
    int r = 0;

    if (!denydb) {
	r = IMAP_INTERNAL;
	goto out;
    }

    if (!service)
	service = "*";

    if (!user || strchr(service, '\t')) {
	/* the service field may not contain a TAB, it's the field separator */
	r = IMAP_INVALID_IDENTIFIER;
	goto out;
    }

    /* compose the record */
    buf_printf(&data, "%u\t", USERDENY_VERSION);
    buf_appendcstr(&data, service);
    buf_putc(&data, '\t');
    buf_appendcstr(&data, (msg ? msg : default_message));

    /* write the record */
    do {
	r = cyrusdb_store(denydb,
			  user, strlen(user),
			  data.s, data.len,
			  &txn);
    } while (r == CYRUSDB_AGAIN);

    if (r) {
	syslog(LOG_ERR, "IOERROR: couldn't store denydb record for %s: %s",
			user, cyrusdb_strerror(r));
	r = IMAP_IOERROR;
    }

out:
    if (txn) {
	if (r) cyrusdb_abort(denydb, txn);
	else cyrusdb_commit(denydb, txn);
    }
    buf_free(&data);
    return r;
}
Beispiel #25
0
static void _entry_to_tgt(const struct vparse_entry *entry, struct vparse_target *tgt)
{
    struct vparse_param *param;

    // rfc6350 3.3 - it is RECOMMENDED that property and parameter names be upper-case on output.
    if (entry->group) {
        _key_to_tgt(entry->group, tgt);
        buf_putc(tgt->buf, '.');
    }
    _key_to_tgt(entry->name, tgt);

    for (param = entry->params; param; param = param->next) {
        buf_putc(tgt->buf, ';');
        _key_to_tgt(param->name, tgt);
        buf_putc(tgt->buf, '=');
        if (_needsquote(param->value)) {
            /* XXX - smart quoting? */
            buf_putc(tgt->buf, '"');
            _paramval_to_tgt(param->value, tgt);
            buf_putc(tgt->buf, '"');
        }
        else {
            _paramval_to_tgt(param->value, tgt);
        }
    }

    buf_putc(tgt->buf, ':');

    if (entry->multivalue) {
        int i;
        for (i = 0; i < entry->v.values->count; i++) {
            if (i) buf_putc(tgt->buf, ';');
            _value_to_tgt(strarray_nth(entry->v.values, i), tgt, 1);
        }
    }
    else {
        _value_to_tgt(entry->v.value, tgt, 0);
    }

    _endline(tgt);
}
Beispiel #26
0
static void _paramval_to_tgt(const char *value, struct vparse_target *tgt)
{
    for (; *value; value++) {
        _checkwrap(*value, tgt);
        switch (*value) {
        case '\r':
            break;
        case '\n':
            buf_putc(tgt->buf, '^');
            buf_putc(tgt->buf, 'n');
            break;
        case '^':
            buf_putc(tgt->buf, '^');
            buf_putc(tgt->buf, '^');
            break;
        case '"':
            buf_putc(tgt->buf, '^');
            buf_putc(tgt->buf, '\'');
            break;
        default:
            buf_putc(tgt->buf, *value);
        }
    }
}
Beispiel #27
0
/*
 * Construct an iCalendar property from a XML element.
 */
static icalproperty *xml_element_to_icalproperty(xmlNodePtr xprop)
{
    const char *propname, *typestr;
    icalproperty_kind kind;
    icalproperty *prop = NULL;
    icalvalue_kind valkind;
    icalvalue *value;
    xmlNodePtr node;

    /* Get the property type */
    propname = ucase(icalmemory_tmp_copy((const char *) xprop->name));
    kind = icalenum_string_to_property_kind(propname);
    if (kind == ICAL_NO_PROPERTY) {
        syslog(LOG_WARNING, "Unknown xCal property type: %s", propname);
        return NULL;
    }

    /* Create new property */
    prop = icalproperty_new(kind);
    if (!prop) {
        syslog(LOG_ERR, "Creation of new %s property failed", propname);
        return NULL;
    }
    if (kind == ICAL_X_PROPERTY) icalproperty_set_x_name(prop, propname);


    /* Add parameters */
    node = xmlFirstElementChild(xprop);
    if (node && !xmlStrcmp(node->name, BAD_CAST "parameters")) {
        xmlNodePtr xparam;

        for (xparam = xmlFirstElementChild(node); xparam;
                xparam = xmlNextElementSibling(xparam)) {
            char *paramname =
                ucase(icalmemory_tmp_copy((const char *) xparam->name));
            xmlChar *paramval = xmlNodeGetContent(xmlFirstElementChild(xparam));

            /* XXX  Need to handle multi-valued parameters */
            icalproperty_set_parameter_from_string(prop, paramname,
                                                   (const char *) paramval);

            xmlFree(paramval);
        }

        node = xmlNextElementSibling(node);
    }

    /* Get the value type */
    if (!node) {
        syslog(LOG_WARNING, "Missing xCal value for %s property",
               propname);
        return NULL;
    }
    typestr = ucase(icalmemory_tmp_copy((const char *) node->name));
    valkind = !strcmp(typestr, "UNKNOWN") ? ICAL_X_VALUE :
              icalenum_string_to_value_kind(typestr);
    if (valkind == ICAL_NO_VALUE) {
        syslog(LOG_WARNING, "Unknown xCal value type for %s property: %s",
               propname, typestr);
        return NULL;
    }
    else if (valkind == ICAL_TEXT_VALUE) {
        /* "text" also includes enumerated types - grab type from property */
        valkind = icalproperty_kind_to_value_kind(kind);
    }


    /* Add value */
    switch (kind) {
    case ICAL_CATEGORIES_PROPERTY:
    case ICAL_RESOURCES_PROPERTY:
    case ICAL_POLLPROPERTIES_PROPERTY:
        if (valkind == ICAL_TEXT_VALUE) {
            /* Handle multi-valued properties */
            struct buf buf = BUF_INITIALIZER;
            xmlChar *content = NULL;

            content = xmlNodeGetContent(node);
            buf_setcstr(&buf, (const char *) content);
            free(content);

            while ((node = xmlNextElementSibling(node))) {
                buf_putc(&buf, ',');
                content = xmlNodeGetContent(node);
                buf_appendcstr(&buf, (const char *) content);
                free(content);
            }

            value = icalvalue_new_from_string(valkind, buf_cstring(&buf));
            buf_free(&buf);
            break;
        }

    default:
        value = xml_element_to_icalvalue(node, valkind);
        if (!value) {
            syslog(LOG_ERR, "Parsing %s property value failed", propname);
            goto error;
        }
    }

    icalproperty_set_value(prop, value);


    /* Sanity check */
    if ((node = xmlNextElementSibling(node))) {
        syslog(LOG_WARNING,
               "Unexpected XML element in property: %s", node->name);
        goto error;
    }

    return prop;

error:
    icalproperty_free(prop);
    return NULL;
}
Beispiel #28
0
static int
expand_args(BUF *buf, struct file_info_list *file_info, const char *repo,
    const char *allowed_args, char *format)
{
	int oldstyle, quote;
	struct file_info *fi = NULL;
	char *p, valbuf[2] = { '\0', '\0' };
	const char *val;

	if (file_info != NULL && !TAILQ_EMPTY(file_info))
		fi = TAILQ_FIRST(file_info);

	quote = oldstyle = 0;

	/* Why does GNU cvs print something if it encounters %{}? */
	if (*format == '\0')
		oldstyle = 1;

	for (p = format; *p != '\0'; p++) {
		if (*p != '%' && strchr(allowed_args, *p) == NULL)
			return 1;

		switch (*p) {
		case 's':
		case 'V':
		case 'v':
			quote = 1;
			oldstyle = 1;
			break;
		default:
			break;
		}
	}
	if (quote)
		buf_putc(buf, '"');
	if (oldstyle) {
		buf_puts(buf, repo);
		buf_putc(buf, ' ');
	}

	if (*format == '\0')
		return 0;

	/*
	 * check like this, add only uses loginfo for directories anyway
	 */
	if (cvs_cmdop == CVS_OP_ADD) {
		buf_puts(buf, "- New directory");
		if (quote)
			buf_putc(buf, '"');
		return (0);
	}

	if (cvs_cmdop == CVS_OP_IMPORT) {
		buf_puts(buf, "- Imported sources");
		if (quote)
			buf_putc(buf, '"');
		return (0);
	}

	for (;;) {
		for (p = format; *p != '\0';) {
			val = NULL;

			switch (*p) {
			case '%':
				val = "%";
				break;
			case 'b':
				if (fi != NULL) {
					valbuf[0] = fi->tag_type;
					val = valbuf;
				}
				break;
			case 'o':
				if (fi != NULL)
					val = fi->tag_op;
				break;
			case 'p':
				val = current_cvsroot->cr_dir;
				break;
			case 'r':
				val = repo;
				break;
			case 'l':
			case 'S':
			case 's':
				if (fi != NULL)
					val = fi->file_path;
				break;
			case 't':
				if (fi != NULL)
					val = fi->tag_new;
				break;
			case 'V':
				if (fi != NULL) {
					if (fi->crevstr != NULL &&
					    !strcmp(fi->crevstr,
					    "Non-existent"))
						val = "NONE";
					else
						val = fi->crevstr;
				}
				break;
			case 'v':
				if (fi != NULL) {
					if (fi->nrevstr != NULL &&
					    !strcmp(fi->nrevstr, "Removed"))
						val = "NONE";
					else
						val = fi->nrevstr;
				}
				break;
			default:
				return 1;
			}

			if (val != NULL)
				buf_puts(buf, val);

			if (*(++p) != '\0')
				buf_putc(buf, ',');
		}

		if (fi != NULL)
			fi = TAILQ_NEXT(fi, flist);
		if (fi == NULL)
			break;

		if (strlen(format) == 1 && (*format == '%' || *format == 'o' ||
		    *format == 'p' || *format == 'r' || *format == 't'))
			break;

		buf_putc(buf, ' ');
	}

	if (quote)
		buf_putc(buf, '"');

	return 0;
}
Beispiel #29
0
static char *
parse_cmd(int type, char *cmd, const char *repo,
    struct file_info_list *file_info)
{
	int expanded = 0;
	char argbuf[2] = { '\0', '\0' };
	char *allowed_args, *default_args, *args, *file, *p, *q = NULL;
	size_t pos;
	BUF *buf;

	switch (type) {
	case CVS_TRIGGER_COMMITINFO:
		allowed_args = "prsS{}";
		default_args = " %p/%r %S";
		file = CVS_PATH_COMMITINFO;
		break;
	case CVS_TRIGGER_LOGINFO:
		allowed_args = "prsSvVt{}";
		default_args = NULL;
		file = CVS_PATH_LOGINFO;
		break;
	case CVS_TRIGGER_VERIFYMSG:
		allowed_args = "l";
		default_args = " %l";
		file = CVS_PATH_VERIFYMSG;
		break;
	case CVS_TRIGGER_TAGINFO:
		allowed_args = "btoprsSvV{}";
		default_args = " %t %o %p/%r %{sv}";
		file = CVS_PATH_TAGINFO;
		break;
	default:
		return (NULL);
	}

	/* before doing any stuff, check if the command starts with % */
	for (p = cmd;
	     *p != '%' && !isspace((unsigned char)*p) && *p != '\0'; p++)
		;
	if (*p == '%')
		return (NULL);

	buf = buf_alloc(1024);

	p = cmd;
again:
	for (; *p != '\0'; p++) {
		if ((pos = strcspn(p, "$%")) != 0) {
			buf_append(buf, p, pos);
			p += pos;
		}

		q = NULL;
		if (*p == '\0')
			break;
		if (*p++ == '$') {
			if (*p == '{') {
				pos = strcspn(++p, "}");
				if (p[pos] == '\0')
					goto bad;
			} else {
				for (pos = 0; isalpha(p[pos]); pos++)
					;
				if (pos == 0) {
					cvs_log(LP_ERR,
					    "unrecognized variable syntax");
					goto bad;
				}
			}
			q = xmalloc(pos + 1);
			memcpy(q, p, pos);
			q[pos] = '\0';
			if (expand_var(buf, q))
				goto bad;
			p += pos - (*(p - 1) == '{' ? 0 : 1);
		} else {
			switch (*p) {
			case '\0':
				goto bad;
			case '{':
				if (strchr(allowed_args, '{') == NULL)
					goto bad;
				pos = strcspn(++p, "}");
				if (p[pos] == '\0')
					goto bad;
				q = xmalloc(pos + 1);
				memcpy(q, p, pos);
				q[pos] = '\0';
				args = q;
				p += pos;
				break;
			default:
				argbuf[0] = *p;
				args = argbuf;
				break;
			}
	
			if (expand_args(buf, file_info, repo, allowed_args,
			    args))
				goto bad;
			expanded = 1;
		}

		free(q);
	}

	if (!expanded && default_args != NULL) {
		p = default_args;
		expanded = 1;
		goto again;
	}

	buf_putc(buf, '\0');
	return (buf_release(buf));

bad:
	free(q);
	cvs_log(LP_NOTICE, "%s contains malformed command '%s'", file, cmd);
	buf_free(buf);
	return (NULL);
}
Beispiel #30
0
/* This handles piping of the LSUB command, because we have to figure out
 * what mailboxes actually exist before passing them to the end user.
 *
 * It is also needed if we are doing a FIND MAILBOXES, for that we do an
 * LSUB on the backend anyway, because the semantics of FIND do not allow
 * it to return nonexistant mailboxes (RFC1176), but we need to really dumb
 * down the response when this is the case.
 */
int pipe_lsub(struct backend *s, const char *userid, const char *tag,
              int force_notfatal, const char *resp)
{
    int taglen = strlen(tag);
    int c;
    int r = PROXY_OK;
    int exist_r;
    static struct buf tagb, cmd, sep, name;
    struct buf flags = BUF_INITIALIZER;

    const char *end_strip_flags[] = { " \\NonExistent)", "\\NonExistent)",
                                      " \\Noselect)", "\\Noselect)",
                                      NULL };
    const char *mid_strip_flags[] = { "\\NonExistent ",
                                      "\\Noselect ",
                                      NULL
                                    };

    assert(s);
    assert(s->timeout);

    s->timeout->mark = time(NULL) + IDLE_TIMEOUT;

    while(1) {
        c = getword(s->in, &tagb);

        if(c == EOF) {
            if(s == backend_current && !force_notfatal)
                fatal("Lost connection to selected backend", EC_UNAVAILABLE);
            proxy_downserver(s);
            r = PROXY_NOCONNECTION;
            goto out;
        }

        if(!strncmp(tag, tagb.s, taglen)) {
            char buf[2048];
            if(!prot_fgets(buf, sizeof(buf), s->in)) {
                if(s == backend_current && !force_notfatal)
                    fatal("Lost connection to selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                goto out;
            }
            /* Got the end of the response */
            buf_appendcstr(&s->last_result, buf);
            buf_cstring(&s->last_result);

            switch (buf[0]) {
            case 'O': case 'o':
                r = PROXY_OK;
                break;
            case 'N': case 'n':
                r = PROXY_NO;
                break;
            case 'B': case 'b':
                r = PROXY_BAD;
                break;
            default: /* huh? no result? */
                if(s == backend_current && !force_notfatal)
                    fatal("Lost connection to selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                break;
            }
            break; /* we're done */
        }

        c = getword(s->in, &cmd);

        if(c == EOF) {
            if(s == backend_current && !force_notfatal)
                fatal("Lost connection to selected backend", EC_UNAVAILABLE);
            proxy_downserver(s);
            r = PROXY_NOCONNECTION;
            goto out;
        }

        if(strncasecmp("LSUB", cmd.s, 4) && strncasecmp("LIST", cmd.s, 4)) {
            prot_printf(imapd_out, "%s %s ", tagb.s, cmd.s);
            r = pipe_to_end_of_response(s, force_notfatal);
            if (r != PROXY_OK)
                goto out;
        } else {
            /* build up the response bit by bit */
            int i;

            buf_reset(&flags);
            c = prot_getc(s->in);
            while(c != ')' && c != EOF) {
                buf_putc(&flags, c);
                c = prot_getc(s->in);
            }

            if(c != EOF) {
                /* terminate string */
                buf_putc(&flags, ')');
                buf_cstring(&flags);

                /* get the next character */
                c = prot_getc(s->in);
            }

            if(c != ' ') {
                if(s == backend_current && !force_notfatal)
                    fatal("Bad LSUB response from selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                goto out;
            }

            /* Check for flags that we should remove
             * (e.g. Noselect, NonExistent) */
            for(i=0; end_strip_flags[i]; i++)
                buf_replace_all(&flags, end_strip_flags[i], ")");

            for (i=0; mid_strip_flags[i]; i++)
                buf_replace_all(&flags, mid_strip_flags[i], NULL);

            /* Get separator */
            c = getastring(s->in, s->out, &sep);

            if(c != ' ') {
                if(s == backend_current && !force_notfatal)
                    fatal("Bad LSUB response from selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                goto out;
            }

            /* Get name */
            c = getastring(s->in, s->out, &name);

            if(c == '\r') c = prot_getc(s->in);
            if(c != '\n') {
                if(s == backend_current && !force_notfatal)
                    fatal("Bad LSUB response from selected backend",
                          EC_UNAVAILABLE);
                proxy_downserver(s);
                r = PROXY_NOCONNECTION;
                goto out;
            }

            /* lookup name */
            exist_r = 1;
            char *intname = mboxname_from_external(name.s, &imapd_namespace, userid);
            mbentry_t *mbentry = NULL;
            exist_r = mboxlist_lookup(intname, &mbentry, NULL);
            free(intname);
            if(!exist_r && (mbentry->mbtype & MBTYPE_RESERVE))
                exist_r = IMAP_MAILBOX_RESERVED;
            mboxlist_entry_free(&mbentry);

            /* send our response */
            /* we need to set \Noselect if it's not in our mailboxes.db */
            if (resp[0] == 'L') {
                if(!exist_r) {
                    prot_printf(imapd_out, "* %s %s \"%s\" ",
                                resp, flags.s, sep.s);
                } else {
                    prot_printf(imapd_out, "* %s (\\Noselect) \"%s\" ",
                                resp, sep.s);
                }

                prot_printstring(imapd_out, name.s);
                prot_printf(imapd_out, "\r\n");

            } else if(resp[0] == 'M' && !exist_r) {
                /* Note that it has to exist for a find response */
                prot_printf(imapd_out, "* %s ", resp);
                prot_printastring(imapd_out, name.s);
                prot_printf(imapd_out, "\r\n");
            }
        }
    } /* while(1) */

out:
    buf_free(&flags);
    return r;
}