X-Git-Url: https://jfr.im/git/irc/evilnet/x3.git/blobdiff_plain/d76ed9a966ee3d955c8ef00ecc02e643c2005e2e..eb5d6b73587847fd4a98767248c56ae9b854c1d2:/src/tools.c diff --git a/src/tools.c b/src/tools.c index 161e9d2..2911508 100644 --- a/src/tools.c +++ b/src/tools.c @@ -307,10 +307,86 @@ match_ircglob(const char *text, const char *glob) extern const char *hidden_host_suffix; +int user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick) +{ + /* A new glob function, the old one had many false positives. + * look at IsSetHost(user) etc and include_nick, build a nick!user@host string + * from user and save it in a variable. Compare with match_ircglob() and + * return the results. Match any of the possible user@host combos (ugh) -Rubin + */ + char *matchstr_user; + char *matchstr_host; + char *matchstr_full = NULL; + + if(IsSetHost(user)) /* S: line sethosts */ + { + /* Grab host and user from sethost instead of real host */ + char *buff; + buff = alloca(strlen(user->sethost) + 1); + strcpy(buff, user->sethost); + matchstr_user = mysep(&buff, "@"); + matchstr_host = mysep(&buff, "@"); + + matchstr_full = alloca(strlen(user->nick) + strlen(matchstr_user) + strlen(matchstr_host) + 4); + if(include_nick) + sprintf(matchstr_full, "%s!%s@%s", user->nick, matchstr_user, matchstr_host); + else + sprintf(matchstr_full, "%s@%s", matchstr_user, matchstr_host); + if(match_ircglob(matchstr_full, orig_glob)) + return(1); + } + else if(IsFakeHost(user)) /* Fakehost */ + { + matchstr_full = alloca(strlen(user->nick) + strlen(user->ident) + strlen(user->fakehost) + 4); + if(include_nick) + sprintf(matchstr_full, "%s!%s@%s", user->nick, user->ident, user->fakehost); + else + sprintf(matchstr_full, "%s@%s", user->ident, user->fakehost); + if(match_ircglob(matchstr_full, orig_glob)) + return(1); + } + else if(hidden_host_suffix && user->handle_info) /* name.users.network.org host */ + { + matchstr_host = alloca(strlen(user->handle_info->handle) + strlen(hidden_host_suffix) + 2); + sprintf(matchstr_host, "%s.%s", user->handle_info->handle, hidden_host_suffix); + matchstr_user = user->ident; + + matchstr_full = alloca(strlen(user->nick) + strlen(user->ident) + strlen(matchstr_host) + 4); + if(include_nick) + sprintf(matchstr_full, "%s!%s@%s", user->nick, user->ident, matchstr_host); + else + sprintf(matchstr_full, "%s@%s", user->ident, matchstr_host); + if(match_ircglob(matchstr_full, orig_glob)) + return(1); + } + + /* Check normal hostname */ + matchstr_full = alloca(strlen(user->nick) + strlen(user->ident) + strlen(user->hostname) + 4); + if(include_nick) + sprintf(matchstr_full, "%s!%s@%s", user->nick, user->ident, user->hostname); + else + sprintf(matchstr_full, "%s@%s", user->ident, user->hostname); + if(match_ircglob(matchstr_full, orig_glob)) + return(1); + + /* Check IP hostname (could skip this if same as above?)*/ + matchstr_host = inet_ntoa(user->ip); + matchstr_full = alloca(strlen(user->nick) + strlen(user->ident) + strlen(matchstr_host) + 4); + if(include_nick) + sprintf(matchstr_full, "%s!%s@%s", user->nick, user->ident, matchstr_host); + else + sprintf(matchstr_full, "%s@%s", user->ident, matchstr_host); + if(match_ircglob(matchstr_full, orig_glob)) + return(1); + + return(0); /* Didnt match anything */ +} + int -user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick) +user_matches_glob_broken(struct userNode *user, const char *orig_glob, int include_nick) { char *glob, *marker; + char *setident = NULL, *sethostname = NULL; // sethost - reed/apples /* Make a writable copy of the glob */ glob = alloca(strlen(orig_glob)+1); @@ -331,8 +407,16 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick return 0; } *marker = 0; - if (!match_ircglob(user->ident, glob)) - return 0; + + // sethost - reed/apples + if (IsSetHost(user)) { + setident = alloca(strcspn(user->sethost, "@")+2); + safestrncpy(setident, user->sethost, strcspn(user->sethost, "@")+1); + sethostname = strchr(user->sethost, '@') + 1; + } + + if (!match_ircglob(user->ident, glob) && (IsSetHost(user) && !match_ircglob(setident, glob))) + return 0; glob = marker + 1; /* Now check the host part */ if (isdigit(*glob) && !glob[strspn(glob, "0123456789./*?")]) { @@ -340,8 +424,10 @@ user_matches_glob(struct userNode *user, const char *orig_glob, int include_nick return match_ircglob(inet_ntoa(user->ip), glob); } else { /* The host part of the mask isn't IP-based */ + if (IsSetHost(user) && match_ircglob(sethostname, glob)) + return 1; if (IsFakeHost(user) && match_ircglob(user->fakehost, glob)) - return 1; + return 1; if (hidden_host_suffix && user->handle_info) { char hidden_host[HOSTLEN+1]; snprintf(hidden_host, sizeof(hidden_host), "%s.%s", user->handle_info->handle, hidden_host_suffix); @@ -746,7 +832,7 @@ string_buffer_append_vprintf(struct string_buffer *buf, const char *fmt, va_list /* pre-C99 behavior; double buffer size until it is big enough */ va_end(working); VA_COPY(working, args); - while ((ret = vsnprintf(buf->list + buf->used, buf->size, fmt, working)) == -1) { + while ((ret = vsnprintf(buf->list + buf->used, buf->size - buf->used, fmt, working)) <= 0) { buf->size += len; buf->list = realloc(buf->list, buf->size); va_end(working); @@ -843,3 +929,36 @@ tools_cleanup(void) free(str_tab.list[ii]); free(str_tab.list); } + +/* mysep() is my answer to the strtok/strsep + * issue. strsep is nice but doesn't skip + * multiple dilimiters, which can really + * offset tokens and cause huge corruption + * so this function will use strsep but + * act like strtok in that sence. + */ +char *mysep(char **sepstr, char *delim) +{ + static char *retstr; + + if(!*sepstr || !**sepstr) + return(NULL); + + do + { + retstr = strsep(sepstr, delim); + }while (retstr && !(*retstr)); + + return(retstr); +} + +char *time2str(time_t thetime) +{ + char *buf, *tmp; + + buf = ctime(&thetime); + tmp = (char *)strchr(buf, '\n'); + *tmp = '\0'; + return(buf); +} +