static void domainname_flip(char *out, const char *in, size_t len) { unsigned i; const char *e = in+len; const char *p = in, *n; char *o = out+len; for (i = 0; i < 4 && p < e; i ++) { p = strndigit(p, MIN(3,e-p)); if (p >= e || *p != '.') break; if (i < 3 && *p == '.') p ++; } if (p >= e) { /* looks like an IP: as is */ memcpy(out, in, len); return; } n = in; while (1) { p = n; STRSEARCH(n, e-p, *n == '.'); o -= n-p; memcpy(o, p, n-p); if (n >= e) break; *--o = *n++; } }
/* Parses a string into the provided IrcMessage struct. Returns 1 on success, 0 on failure. */ int irc_parse_string(char *msgstr, int len, IrcMessage *msg) { //Copy msgstr into the full field char *fullcpy = malloc(sizeof(char) * strlen(msgstr)); msg->full = strcpy(fullcpy, msgstr); //Set up all other fields msg->prefix = NULL; msg->command = IRC_NONE; msg->argc = 0; msg->argv = NULL; //Make parser pointer char *ptr = msgstr; //If first char is : we have a prefix if(msgstr[0] == ':') { ptr++; msg->prefix = first_word(&ptr); } if(ptr == NULL) return 1; //First word after optional prefix is command char *commandstr = first_word(&ptr); //Convert command string to command const int cmdlen = strlen(commandstr); if(cmdlen <= 3 && strndigit(commandstr,cmdlen)) { msg->command = IRC_NUMERIC; } else if(!strncmp(commandstr,"PING",4)) { msg->command = IRC_PING; } else if(!strncmp(commandstr,"NOTICE",6) || !strncmp(commandstr,"PRIVMSG",7)) { msg->command = IRC_MESSAGE; } else if(!strncmp(commandstr,"ERROR",5)) { msg->command = IRC_ERROR; } else if(!strncmp(commandstr,"JOIN",4)) { msg->command = IRC_JOIN; } else { msg->command = IRC_OTHER; } if(ptr == NULL) return 1; //Read additional arguments msg->argv = read_args(&ptr, &(msg->argc)); return 1; }
static bool uri_parse(const char *str, size_t len, struct uri_info *uri) { const char *b, *p = str, *e = str+len, *x; #define NEXT(I) ({ \ b = p += (I); \ STRSEARCH(p, e-p, isdelim(*p)); \ }) NEXT(0); if (p < e && p[0] == ':' && !( (x = strndigit(p+1, MIN(e-p-1,PORT_LEN))) > p+1 && (x == e || isdelim(*x)))) { uri->scheme = b; uri->scheme_len = p-b; NEXT(1); } else { uri->scheme = NULL; uri->scheme_len = 0; } if (p < e-1 && p == b && p[0] == '/' && p[1] == '/') NEXT(2); if (p < e-1 && *p == '@') NEXT(1); uri->host = b; uri->host_len = p-b; uri->port = -1; while (p < e-1 && p[0] == ':') { char portbuf[8]; unsigned portlen = sizeof(portbuf)-1; NEXT(1); if (p-b < portlen) portlen = p-b; memcpy(portbuf, b, portlen); portbuf[portlen] = 0; uri->port = strtoul(portbuf, (char **)&x, 10); if (!*x) break; uri->host_len = p-uri->host; uri->port = -1; } if (p < e) { uri->path = p; uri->path_len = e-p; } else { uri->path = NULL; uri->path_len = 0; } #undef NEXT return true; }