/** * Handle NOTICE commands * * @param source is the nick of the person whom sent the notice * @param receiver is the nick whom it was sent to * @param msg is the message that was sent * * @return always returns MOD_CONT */ int m_notice(char *source, char *receiver, char *msg) { char *temp = NULL; char *version; char *clean; if (BadPtr(source) || BadPtr(receiver) || BadPtr(msg)) { return MOD_CONT; } if (!stricmp(receiver, s_StatServ) || (s_StatServ_alias && !stricmp(receiver, s_StatServ_alias))) { clean = normalizeBuffer(msg); doCleanBuffer((char *) clean); temp = myStrGetToken(clean, ' ', 0); if (!temp) { free(clean); return MOD_CONT; } if (!stricmp(temp, "VERSION")) { version = myStrGetTokenRemainder(clean, ' ', 1); handle_ctcp_version(source, version); free(version); } free(clean); free(temp); } return MOD_CONT; }
static void hsreq_load_db(void) { FILE *fp; char *filename; char readbuf[1024]; char *nick, *vident, *vhost, *creator, *tmp; int32 tmp_time; char *buf; if (HSRequestDBName) filename = HSRequestDBName; else filename = HSREQ_DEFAULT_DBNAME; fp = fopen(filename, "r"); if (!fp) { alog("[hs_request] Unable to open database ('%s') for reading", filename); return; } while (fgets(readbuf, 1024, fp)) { buf = normalizeBuffer(readbuf); if (buf || *buf) { nick = myStrGetToken(buf, ':', 0); vident = myStrGetToken(buf, ':', 1); vhost = myStrGetToken(buf, ':', 2); tmp = myStrGetToken(buf, ':', 3); if (tmp) { tmp_time = strtol(tmp, (char **) NULL, 16); free(tmp); } else { tmp_time = 0; } creator = myStrGetToken(buf, ':', 4); if (!nick || !vident || !vhost || !creator) { alog("[hs_request] Error while reading database, skipping record"); continue; } if (stricmp(vident, "(null)") == 0) { free(vident); vident = NULL; } my_add_host_request(nick, vident, vhost, creator, tmp_time); free(nick); free(vhost); free(creator); if (vident) free(vident); } free(buf); } fclose(fp); if (debug) alog("[hs_request] Succesfully loaded database"); }
void viagra_cmd_ctcp(char *source, char *dest, char *buf) { char *s; if (!buf) { return; } else { s = normalizeBuffer(buf); } send_cmd(source, "NOTICE %s :\1%s \1", dest, s); free(s); }
// This function performs time-domain multiplication (slow convolution) // dry_wet is a measure of the ratio between the dry and wet signals. 0 is completely dry // and 1 is completely wet void slowConvolve(audioData *signal, audioData *impulse, float dry_wet, char *outFileName) { // Check for realistic dry_wet values if (dry_wet < 0 || dry_wet > 1) { printf("Error: dry_wet must be between 0 and 1\n"); return; } int i, j, k; if (signal->numChannels == 1 && impulse->numChannels == 1) { } if (signal->numChannels == 2 && impulse->numChannels == 1) { } if (signal->numChannels == 1 && impulse->numChannels == 2) { } if (signal->numChannels == 2 && impulse->numChannels == 2) { // Find new length int newLength = signal->numFrames + impulse->numFrames - 1; // Create buffer for output float *outputBuffer = (float *) malloc(sizeof(float) * newLength * 2); // Zero out buffer memset(outputBuffer, 0, sizeof(float) * newLength * 2); // Perform convolution for (j = 0; j < signal->numFrames; j++) { for (k = 0; k < impulse->numFrames; k++) { outputBuffer[2 * (j + k)] += signal->buffer1[2 * j] * impulse->buffer1[2 * k]; outputBuffer[2 * (j + k) + 1] += signal->buffer1[2 * j + 1] * impulse->buffer1[2 * k + 1]; } } // Multiply by dry/wet coefficient for (i = 0; i < newLength * 2; i++) { outputBuffer[i] *= dry_wet; } // Add dry signal to output buffer, multiply by dry/wet coefficient for (i = 0; i < signal->numFrames * 2; i++) { outputBuffer[i] += signal->buffer1[i] * (1 - dry_wet); } // Normalize outputBuffer = normalizeBuffer(outputBuffer, newLength * 2); // Write to wav file writeWavFile(outputBuffer, 44100, 2, newLength, 2, outFileName); } }
bool OpenDDLParser::parse() { if( m_buffer.empty() ) { return false; } normalizeBuffer( m_buffer ); m_context = new Context; m_context->m_root = DDLNode::create( "root", "", ddl_nullptr ); pushNode( m_context->m_root ); // do the main parsing char *current( &m_buffer[ 0 ] ); char *end( &m_buffer[m_buffer.size() - 1 ] + 1 ); size_t pos( current - &m_buffer[ 0 ] ); while( pos < m_buffer.size() ) { current = parseNextNode( current, end ); if ( current == ddl_nullptr ) { return false; } pos = current - &m_buffer[ 0 ]; } return true; }
void IRCDProto::SendCTCPInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf) { Anope::string s = normalizeBuffer(buf); this->SendNoticeInternal(bi, dest, "\1" + s + "\1"); }
/** * Adds a new user to anopes internal userlist. * * If the SVID passed is 2, the user will not be marked registered or requested to ID. * This is an addition to accomodate IRCds where we cannot determine this based on the NICK * or UID command. Some IRCd's keep +r on when changing nicks and do not use SVID (ex. InspIRCd 1.2). * Instead we get a METADATA command containing the accountname the user was last identified to. * Since this is received after the user is introduced to us we should not yet mark the user * as identified or ask him to identify. We will mark him as recognized for the time being and let * him keep his +r if he has it. * It is the responsibility of the protocol module to make sure that this is either invalidated, * or changed to identified. ~ Viper **/ User *do_nick(const char *source, char *nick, char *username, char *host, char *server, char *realname, time_t ts, uint32 svid, uint32 ip, char *vhost, char *uid) { User *user = NULL; char *tmp = NULL; NickAlias *old_na; /* Old nick rec */ int nc_changed = 1; /* Did nick core change? */ int status = 0; /* Status to apply */ char mask[USERMAX + HOSTMAX + 2]; char *logrealname; char *oldnick; if (!*source) { char ipbuf[16]; struct in_addr addr; if (ircd->nickvhost) { if (vhost) { if (!strcmp(vhost, "*")) { vhost = NULL; if (debug) alog("debug: new user�with no vhost in NICK command: %s", nick); } } } /* This is a new user; create a User structure for it. */ if (debug) alog("debug: new user: %s", nick); if (ircd->nickip) { addr.s_addr = htonl(ip); ntoa(addr, ipbuf, sizeof(ipbuf)); } if (LogUsers) { /** * Ugly swap routine for Flop's bug :) **/ if (realname) { tmp = strchr(realname, '%'); while (tmp) { *tmp = '-'; tmp = strchr(realname, '%'); } } logrealname = normalizeBuffer(realname); /** * End of ugly swap **/ if (ircd->nickvhost) { if (ircd->nickip) { alog("LOGUSERS: %s (%s@%s => %s) (%s) [%s] connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, ipbuf, server); } else { alog("LOGUSERS: %s (%s@%s => %s) (%s) connected to the network (%s).", nick, username, host, (vhost ? vhost : "none"), logrealname, server); } } else { if (ircd->nickip) { alog("LOGUSERS: %s (%s@%s) (%s) [%s] connected to the network (%s).", nick, username, host, logrealname, ipbuf, server); } else { alog("LOGUSERS: %s (%s@%s) (%s) connected to the network (%s).", nick, username, host, logrealname, server); } } Anope_Free(logrealname); } /* We used to ignore the ~ which a lot of ircd's use to indicate no * identd response. That caused channel bans to break, so now we * just take what the server gives us. People are still encouraged * to read the RFCs and stop doing anything to usernames depending * on the result of an identd lookup. */ /* First check for AKILLs. */ /* DONT just return null if its an akill match anymore - yes its more efficent to, however, now that ircd's are * starting to use things like E/F lines, we cant be 100% sure the client will be removed from the network :/ * as such, create a user_struct, and if the client is removed, we'll delete it again when the QUIT notice * comes in from the ircd. **/ if (check_akill(nick, username, host, vhost, ipbuf)) { /* return NULL; */ } /** * DefCon AKILL system, if we want to akill all connecting user's here's where to do it * then force check_akill again on them... **/ /* don't akill on netmerges -Certus */ /* don't akill clients introduced by ulines. -Viper */ if (is_sync(findserver(servlist, server)) && checkDefCon(DEFCON_AKILL_NEW_CLIENTS) && !is_ulined(server)) { strncpy(mask, "*@", 3); strncat(mask, host, HOSTMAX); alog("DEFCON: adding akill for %s", mask); add_akill(NULL, mask, s_OperServ, time(NULL) + dotime(DefConAKILL), DefConAkillReason ? DefConAkillReason : "DEFCON AKILL"); if (check_akill(nick, username, host, vhost, ipbuf)) { /* return NULL; */ } } /* SGLINE */ if (ircd->sgline) { if (check_sgline(nick, realname)) return NULL; } /* SQLINE */ if (ircd->sqline) { if (check_sqline(nick, 0)) return NULL; } /* SZLINE */ if (ircd->szline && ircd->nickip) { if (check_szline(nick, ipbuf)) return NULL; } /* Now check for session limits */ if (LimitSessions && !is_ulined(server) && !add_session(nick, host, ipbuf)) return NULL; /* Allocate User structure and fill it in. */ user = new_user(nick); user->username = sstrdup(username); user->host = sstrdup(host); user->server = findserver(servlist, server); user->realname = sstrdup(realname); user->timestamp = ts; user->my_signon = time(NULL); user->chost = vhost ? sstrdup(vhost) : sstrdup(host); user->vhost = vhost ? sstrdup(vhost) : sstrdup(host); if (uid) { user->uid = sstrdup(uid); /* p10/ts6 stuff */ } else { user->uid = NULL; } user->vident = sstrdup(username); /* We now store the user's ip in the user_ struct, * because we will use it in serveral places -- DrStein */ if (ircd->nickip) { user->hostip = sstrdup(ipbuf); } else { user->hostip = NULL; } if (svid == 0) { display_news(user, NEWS_LOGON); display_news(user, NEWS_RANDOM); } if (svid == 2 && user->na) { /* We do not yet know if the user should be identified or not. * mark him as recognized for now. * It s up to the protocol module to make sure this either becomes ID'd or * is invalidated. ~ Viper */ if (debug) alog("debug: Marking %s as recognized..", user->nick); user->svid = 1; user->na->status |= NS_RECOGNIZED; nc_changed = 0; } else if (svid == ts && user->na) { /* Timestamp and svid match, and nick is registered; automagically identify the nick */ user->svid = svid; user->na->status |= NS_IDENTIFIED; check_memos(user); nc_changed = 0; /* Start nick tracking if available */ if (NSNickTracking) nsStartNickTracking(user); } else if (svid != 1) { /* Resets the svid because it doesn't match */ user->svid = 1; anope_cmd_svid_umode(user->nick, user->timestamp); } else { user->svid = 1; } send_event(EVENT_NEWNICK, 1, nick); } else { /* An old user changing nicks. */ if (UseTS6 && ircd->ts6) user = find_byuid(source); if (!user) user = finduser(source); if (!user) { alog("user: NICK from nonexistent nick %s", source); return NULL; } user->isSuperAdmin = 0; /* Dont let people nick change and stay SuperAdmins */ if (debug) alog("debug: %s changes nick to %s", source, nick); if (LogUsers) { logrealname = normalizeBuffer(user->realname); if (ircd->vhost) { alog("LOGUSERS: %s (%s@%s => %s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, (user->vhost ? user->vhost : "(none)"), logrealname, nick, user->server->name); } else { alog("LOGUSERS: %s (%s@%s) (%s) changed nick to %s (%s).", user->nick, user->username, user->host, logrealname, nick, user->server->name); } if (logrealname) { free(logrealname); } } user->timestamp = ts; if (stricmp(nick, user->nick) == 0) { /* No need to redo things */ change_user_nick(user, nick); nc_changed = 0; } else { /* Update this only if nicks aren't the same */ user->my_signon = time(NULL); old_na = user->na; if (old_na) { if (nick_recognized(user)) user->na->last_seen = time(NULL); status = old_na->status & NS_TRANSGROUP; cancel_user(user); } oldnick = sstrdup(user->nick); change_user_nick(user, nick); if ((old_na ? old_na->nc : NULL) == (user->na ? user->na->nc : NULL)) nc_changed = 0; if (!nc_changed && (user->na)) user->na->status |= status; else { anope_cmd_nc_change(user); } send_event(EVENT_CHANGE_NICK, 2, nick, oldnick); free(oldnick); } if (ircd->sqline) { if (!is_oper(user) && check_sqline(user->nick, 1)) return NULL; } } /* if (!*source) */ /* Check for nick tracking to bypass identification */ if (NSNickTracking && nsCheckNickTracking(user)) { user->na->status |= NS_IDENTIFIED; nc_changed = 0; } if (nc_changed || !nick_recognized(user)) { if (validate_user(user)) check_memos(user); } else { if (nick_identified(user)) { char tsbuf[16]; user->na->last_seen = time(NULL); if (user->na->last_usermask) free(user->na->last_usermask); user->na->last_usermask = smalloc(strlen(common_get_vident(user)) + strlen(common_get_vhost(user)) + 2); sprintf(user->na->last_usermask, "%s@%s", common_get_vident(user), common_get_vhost(user)); snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) user->timestamp); anope_cmd_svid_umode2(user, tsbuf); alog("%s: %s!%s@%s automatically identified for nick %s", s_NickServ, user->nick, user->username, user->host, user->nick); } } /* Bahamut sets -r on every nick changes, so we must test it even if nc_changed == 0 */ if (ircd->check_nick_id) { if (nick_identified(user)) { char tsbuf[16]; snprintf(tsbuf, sizeof(tsbuf), "%lu", (unsigned long int) user->timestamp); anope_cmd_svid_umode3(user, tsbuf); } } return user; }
void delete_user(User * user) { struct u_chanlist *c, *c2; struct u_chaninfolist *ci, *ci2; char *realname; if (LogUsers) { realname = normalizeBuffer(user->realname); if (ircd->vhost) { alog("LOGUSERS: %s (%s@%s => %s) (%s) left the network (%s).", user->nick, user->username, user->host, (user->vhost ? user->vhost : "(none)"), realname, user->server->name); } else { alog("LOGUSERS: %s (%s@%s) (%s) left the network (%s).", user->nick, user->username, user->host, realname, user->server->name); } free(realname); } send_event(EVENT_USER_LOGOFF, 1, user->nick); if (debug >= 2) alog("debug: delete_user() called"); usercnt--; if (is_oper(user)) opcnt--; if (debug >= 2) alog("debug: delete_user(): free user data"); free(user->username); free(user->host); if (user->chost) free(user->chost); if (user->vhost) free(user->vhost); if (user->vident) free(user->vident); if (user->uid) { free(user->uid); } Anope_Free(user->realname); Anope_Free(user->hostip); if (debug >= 2) { alog("debug: delete_user(): remove from channels"); } c = user->chans; while (c) { c2 = c->next; chan_deluser(user, c->chan); free(c); c = c2; } /* This called only here now */ cancel_user(user); if (user->na) user->na->u = NULL; if (debug >= 2) alog("debug: delete_user(): free founder data"); ci = user->founder_chans; while (ci) { ci2 = ci->next; free(ci); ci = ci2; } if (user->nickTrack) free(user->nickTrack); moduleCleanStruct(&user->moduleData); if (debug >= 2) alog("debug: delete_user(): delete from list"); if (user->prev) user->prev->next = user->next; else userlist[HASH(user->nick)] = user->next; if (user->next) user->next->prev = user->prev; if (debug >= 2) alog("debug: delete_user(): free user structure"); free(user); if (debug >= 2) alog("debug: delete_user() done"); }
/* * m_notice - generic message handler */ int m_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { char* name; char* server; int ret = 0; int i; int j; int fd = 0; int count; char *clean; char* vector[MAXTARGETS]; char* temp; /* added by Vadtec 02/25/2008 */ char* parv_temp; /* added by Vadtec 02/26/2008 */ int found_g = 0; /* added by Vadtec 02/26/2008 */ int sent = 0; /* added by Vadtec 03/13/2008 */ struct Client* acptr; /* added by Vadtec 02/26/2008 */ struct Channel* chptr; /* added by Vadtec 02/27/2008 */ int isdcc = 0; assert(0 != cptr); assert(cptr == sptr); ClrFlag(sptr, FLAG_TS8); if (parc < 2 || EmptyString(parv[1])) return send_reply(sptr, ERR_NORECIPIENT, MSG_NOTICE); if (parc < 3 || EmptyString(parv[parc - 1])) return send_reply(sptr, ERR_NOTEXTTOSEND); if (parv[1][0] == '@' && IsChannelPrefix(parv[1][1])) { parv[1]++; /* Get rid of '@' */ return m_wallchops(cptr, sptr, parc, parv); } count = unique_name_vector(parv[1], ',', vector, MAXTARGETS); /* Check here to make sure that the client is ours so we dont respond to NOTICES from other server's users. - Vadtec 02/25/2008 */ /* Also, check to make sure that the notice is actually destined for the *server* and not another user. That way we don't process some user saying "what version do you use" to another user via notice. - Vadtec 03/13/2008 */ if (feature_bool(FEAT_CTCP_VERSIONING) && MyConnect(sptr) && !strcmp(parv[1], cli_name(&me))) { /* Added by Vadtec 02/25/2008. This is so that we can do version checking (and banning) of connecting clients. Rules: Only one really. CTCP VERSION is not part of the RFC and therefore clients are not required to respond to a request for their version. NOTE: If we are lucky enough to have _GNU_SOURCE, we will use it over the standard strstr because its case insensetive. This should help against clients that like to send lower case CTCPs from slipping through as easily with only one function call. */ for (fd = HighestFd; fd >= 0 && !sent; --fd) { /* Added the "sent" check here so that if we have already sent the notice we don't needlessly loop through *all* the users - Vadtec 03/13/2008 */ if ((acptr = LocalClientArray[fd])) { if (!cli_user(acptr)) continue; #ifdef _GNU_SOURCE if ((temp = strcasestr(parv[2], "\x01VERSION"))) { /* added \x01 to the string so that it will *only* respond to CTCP version replies. Seems redundant, but we dont want the users doing /notice <server> version (and getting away with it) - Vadtec 03/13/2008 */ temp = strchrnul(parv[2], ' '); /* Moved this here to take advantage of strchrnul - added by Vadtec 03/13/2008 */ #else if ((temp = strstr(parv[2], "\x01VERSION")) || (temp = strstr(parv[2], "\x01version"))) { /* See above comment about \x01 - Vadtec */ temp = strchr(parv[2], ' '); /* Moved this here to take advantage of strchrnul - added by Vadtec 03/13/2008 */ if (temp == 0) temp = parv[2] + strlen(parv[2]); /* This does the same thing as strchrnul - Vadtec */ #endif parv_temp = parv[2]; j = 0; while (j <= (temp - parv[2])) { parv_temp++; j++; } clean = normalizeBuffer(parv_temp); doCleanBuffer((char *) clean); ircd_strncpy(cli_version(sptr), normalizeBuffer(clean), VERSIONLEN); sendcmdto_serv_butone(&me, CMD_MARK, cptr, "%s %s :%s", cli_name(sptr), MARK_CVERSION, cli_version(sptr)); /* Moved here to solve duplicate MARK's if any of the CTCP_* conditions were false 05/13/2009 */ sent = 1; if (feature_bool(FEAT_CTCP_VERSIONING_CHAN)) { sprintf(temp, "%s has version \002%s\002", cli_name(sptr), cli_version(sptr)); /* Announce to channel. */ if ((chptr = FindChannel(feature_str(FEAT_CTCP_VERSIONING_CHANNAME)))) { if (feature_bool(FEAT_CTCP_VERSIONING_USEMSG)) sendcmdto_channel_butone(&me, CMD_PRIVATE, chptr, cptr, SKIP_DEAF | SKIP_BURST, '\0', "%H :%s", chptr, temp); else sendcmdto_channel_butone(&me, CMD_NOTICE, chptr, cptr, SKIP_DEAF | SKIP_BURST, '\0', "%H :%s", chptr, temp); /* Removed sent=1 from here because it caused the MARK above to be sent more then once if any of the conditions leading here are false 05/13/2009 */ } } if (feature_bool(FEAT_CTCP_VERSIONING_KILL)) { if ((found_g = find_kill(acptr))) { sendto_opmask_butone(0, found_g == -2 ? SNO_GLINE : SNO_OPERKILL, found_g == -2 ? "G-line active for %s%s" : "K-line active for %s%s", IsUnknown(sptr) ? "Unregistered Client ":"", get_client_name(sptr, SHOW_IP)); return exit_client_msg(cptr, acptr, &me, "Banned Client: %s", cli_version(acptr)); } } else return 0; } } } } for (i = 0; i < count; ++i) { name = vector[i]; if (IsChannelPrefix(*name)) { ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_CHANNOTICE, name); if (ret != 0) { if (ret == 2) return CPTR_KILLED; else return 0; } } else { #ifdef _GNU_SOURCE if ((temp = strcasestr(parv[2], "\001DCC"))) { temp = strchrnul(parv[2], ' '); #else if ((temp = strstr(parv[2], "\001DCC")) || (temp = strstr(parv[2], "\001dcc"))) { temp = strchr(parv[2], ' '); #endif isdcc = 1; ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_DCC, name); if (ret != 0) { if (ret == 2) return CPTR_KILLED; else return 0; } } if (!isdcc) { ret = find_fline(cptr, sptr, parv[parc-1], WFFLAG_NOTICE, name); if (ret != 0) { if (ret == 2) return CPTR_KILLED; else return 0; } } } } i = 0; for (i = 0; i < count; ++i) { name = vector[i]; /* * channel msg? */ if (IsChannelPrefix(*name)) { relay_channel_notice(sptr, name, parv[parc - 1], count); } /* * we have to check for the '@' at least once no matter what we do * handle it first so we don't have to do it twice */ else if ((server = strchr(name, '@'))) relay_directed_notice(sptr, name, server, parv[parc - 1]); else relay_private_notice(sptr, name, parv[parc - 1]); } return 0; } /* * ms_notice - server message handler */ int ms_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { char* name; char* server; ClrFlag(sptr, FLAG_TS8); if (parc < 3) { /* * we can't deliver it, sending an error back is pointless */ return protocol_violation(sptr,"Not enough params for NOTICE"); } name = parv[1]; /* * channel msg? */ if (IsChannelPrefix(*name)) { server_relay_channel_notice(sptr, name, parv[parc - 1]); } /* * coming from another server, we have to check this here */ else if ('$' == *name && IsOper(sptr)) { server_relay_masked_notice(sptr, name, parv[parc - 1]); } else if ((server = strchr(name, '@'))) { /* * XXX - can't get away with not doing everything * relay_directed_notice has to do */ relay_directed_notice(sptr, name, server, parv[parc - 1]); } else { server_relay_private_notice(sptr, name, parv[parc - 1]); } return 0; } /* * mo_notice - oper message handler */ int mo_notice(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) { char* name; char* server; int i; int count; char* vector[MAXTARGETS]; assert(0 != cptr); assert(cptr == sptr); ClrFlag(sptr, FLAG_TS8); if (parc < 2 || EmptyString(parv[1])) return send_reply(sptr, ERR_NORECIPIENT, MSG_NOTICE); if (parc < 3 || EmptyString(parv[parc - 1])) return send_reply(sptr, ERR_NOTEXTTOSEND); if (parv[1][0] == '@' && IsChannelPrefix(parv[1][1])) { parv[1]++; /* Get rid of '@' */ return m_wallchops(cptr, sptr, parc, parv); } count = unique_name_vector(parv[1], ',', vector, MAXTARGETS); for (i = 0; i < count; ++i) { name = vector[i]; /* * channel msg? */ if (IsChannelPrefix(*name)) relay_channel_notice(sptr, name, parv[parc - 1], count); else if (*name == '$') relay_masked_notice(sptr, name, parv[parc - 1]); else if ((server = strchr(name, '@'))) relay_directed_notice(sptr, name, server, parv[parc - 1]); else relay_private_notice(sptr, name, parv[parc - 1]); } return 0; }