cyrus-sasl-digestmd5-parse.c [plain text]
#include <string.h>
#include "cyrus-sasl-digestmd5-parse.h"
#define HT (9)
#define CR (13)
#define LF (10)
#define SP (32)
#define DEL (127)
static char *skip_lws (char *s)
{
if (!s) return NULL;
while (s[0] == ' ' || s[0] == HT || s[0] == CR || s[0] == LF) {
if (s[0] == '\0') break;
s++;
}
return s;
}
static char *skip_token (char *s, int caseinsensitive)
{
if(!s) return NULL;
while (s[0]>SP) {
if (s[0]==DEL || s[0]=='(' || s[0]==')' || s[0]=='<' || s[0]=='>' ||
s[0]=='@' || s[0]==',' || s[0]==';' || s[0]==':' || s[0]=='\\' ||
s[0]=='\'' || s[0]=='/' || s[0]=='[' || s[0]==']' || s[0]== '?' ||
s[0]=='=' || s[0]== '{' || s[0]== '}') {
if (caseinsensitive == 1) {
if (!isupper((unsigned char) s[0]))
break;
} else {
break;
}
}
s++;
}
return s;
}
static char *unquote (char *qstr)
{
char *endvalue;
int escaped = 0;
char *outptr;
if(!qstr) return NULL;
if (qstr[0] == '"') {
qstr++;
outptr = qstr;
for (endvalue = qstr; endvalue[0] != '\0'; endvalue++, outptr++) {
if (escaped) {
outptr[0] = endvalue[0];
escaped = 0;
}
else if (endvalue[0] == '\\') {
escaped = 1;
outptr--;
}
else if (endvalue[0] == '"') {
break;
}
else {
outptr[0] = endvalue[0];
}
}
if (endvalue[0] != '"') {
return NULL;
}
while (outptr <= endvalue) {
outptr[0] = '\0';
outptr++;
}
endvalue++;
}
else {
endvalue = skip_token(qstr,0);
};
return endvalue;
}
static void get_pair(char **in, char **name, char **value)
{
char *endpair;
char *curp = *in;
*name = NULL;
*value = NULL;
if (curp == NULL) return;
if (curp[0] == '\0') return;
curp = skip_lws(curp);
*name = curp;
curp = skip_token(curp,1);
if (curp[0] != '=' && curp[0] != '\0') {
*curp++ = '\0';
};
curp = skip_lws(curp);
if (curp[0] != '=') {
*name = NULL;
return;
}
curp[0] = '\0';
curp++;
curp = skip_lws(curp);
*value = (curp[0] == '"') ? curp+1 : curp;
endpair = unquote (curp);
if (endpair == NULL) {
*name = NULL;
return;
}
if (endpair[0] != ',') {
if (endpair[0]!='\0') {
*endpair++ = '\0';
}
}
endpair = skip_lws(endpair);
if (endpair[0] == ',') {
endpair[0] = '\0';
endpair++;
} else if (endpair[0] != '\0') {
*name = NULL;
return;
}
*in = endpair;
}
void
ODKGetPair(char **in, char **name, char **value)
{
return get_pair(in, name, value);
}