++/** Change a welcome message.
++ * @param[in] cptr Local client that sent us the welcome.
++ * @param[in] sptr Originator of the welcome.
++ * @param[in] name Name of the message.
++ * @param[in] nameint Name of the message.
++ * @param[in] namearray Array entry.
++ * @param[in] who Who set this message.
++ * @param[in] timestamp Timestamp of when the message was set.
++ * @param[in] flags Flags to set on welcome.
++ * @return Zero
++ */
++int
++welcome_insert(struct Client *cptr, struct Client *sptr, char *name, int nameint,
++ int namearray, char *who, time_t timestamp, unsigned int flags)
++{
++ char *text = ""; /* empty text to clear to feed to welcome_do */
++ char *last = "10"; /* last welcome message to feed to welcome_do */
++ char msg[BUFSIZE]; /* msg for snomask, logging, etc. */
++ unsigned int newflags = flags; /* new flags to feed back to welcome_do */
++ int i; /* loop variable */
++ int empty = -1; /* first empty spot array after arrayname */
++ int end = WELCOME_MAX_ENTRIES -1; /* last element to check in array */
++
++ assert(NULL != cptr);
++ assert(NULL != sptr);
++ assert(flags & WELCOME_INSERT);
++ assert(namearray >= 0 && namearray <= 2 * WELCOME_MAX_ENTRIES - 1);
++
++ /* debug */
++ Debug((DEBUG_DEBUG, "welcome_insert(\"%s\", \"%s\", \"%s\", %d, %d, \"%s\", %Tu, 0x%04x)",
++ cli_name(cptr), cli_name(sptr), name, nameint, namearray, who, timestamp, flags));
++
++ /* not set yet, do not insert */
++ if (WelcomeArray[namearray].timestamp == 0)
++ return 0;
++
++ /* last global entry */
++ if (!(flags & WELCOME_LOCAL) && (nameint == WELCOME_MAX_ENTRIES))
++ return 0;
++
++ /* last local entry */
++ if ((flags & WELCOME_LOCAL) && (nameint == 2 * WELCOME_MAX_ENTRIES))
++ return 0;
++
++ /* correct end for local offset */
++ if (flags & WELCOME_LOCAL)
++ end += WELCOME_MAX_ENTRIES;
++
++ /* found first empty spot */
++ for (i = namearray; i <= end; i++) {
++ if (*WelcomeArray[i].text == 0) {
++ empty = i;
++ break;
++ }
++ }
++
++ /* no empty spot, need to unset last, do not insert or announce */
++ if (empty == -1) {
++ newflags &= ~WELCOME_INSERT;
++ newflags &= ~WELCOME_ANNOUNCE;
++ welcome_do(cptr, sptr, last, text, who, timestamp, newflags, 1);
++ empty = end;
++ }
++
++ /* move entries down */
++ for (i = empty; i > namearray; i--)
++ welcome_make(i, WelcomeArray[i-1].text, WelcomeArray[i-1].who, WelcomeArray[i-1].timestamp);
++
++ /* correct empty for local offset */
++ if (flags & WELCOME_LOCAL)
++ empty -= WELCOME_MAX_ENTRIES;
++
++ /* create msg for snomask, logging, etc. */
++ if (nameint == empty)
++ ircd_snprintf(0, msg, 0, "moving %s WELCOME message %d one place down",
++ (flags & WELCOME_LOCAL) ? "local" : "global", nameint);
++ else
++ ircd_snprintf(0, msg, 0, "moving %s WELCOME message %d %s %d one place down",
++ (flags & WELCOME_LOCAL) ? "local" : "global", nameint, (empty - nameint > 1) ? "to" : "and" , empty);
++
++ /* inform ops */
++ sendto_opmask_butone(0, SNO_OLDSNO, "%s %s",
++ (feature_bool(FEAT_HIS_SNOTICES) || IsServer(sptr)) ?
++ get_client_name_and_opername(sptr) : cli_name((cli_user(sptr))->server), msg);
++
++ /* log it */
++ log_write(LS_NETWORK, L_INFO, LOG_NOSNOTICE, "%#C (%s) %s", sptr, who, msg);
++
++ /* welcome set by remote user, inform oper */
++ if ((flags & WELCOME_LOCAL) && IsUser(sptr) && !MyUser(sptr)) {
++ sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s %s",
++ sptr, get_client_name_and_opername(sptr), msg);
++
++ /* TODO: wallops all local changes, by both local and remote opers? */
++ /* tell all opers about the local message being set remotely */
++ sendwallto_group_butone(&me, WALL_WALLOPS, 0, "%s %s", get_client_name_and_opername(sptr), msg);
++ }
++ return 0;
++}
++
++