+ if(topic[pos] == ' ')
+ {
+ //leading number found, cut off and store value in advtopic_index
+ topic[pos] = 0;
+ advtopic_index = atoi(topic) - 1; //no zerobase
+ topic = &topic[pos+1];
+ /* If they say "!topic 2 *", unset advtopic id 2. */
+ if((topic[0] == '*') && (topic[1] == 0))
+ topic[0] = 0;
+ }
+ if(!isdigit(topic[pos]))
+ break;
+ }
+ if(advtopic_index < 0 || advtopic_index >= MAXADVTOPICENTRIES)
+ {
+ //invalid id!
+ reply("CSMSG_ADVTOPIC_INVALID_ID", advtopic_index+1);
+ return 0;
+ }
+ if(cData->advtopic[advtopic_index])
+ free(cData->advtopic[advtopic_index]);
+ cData->advtopic[advtopic_index] = (topic[0] ? strdup(topic) : NULL);
+ char *ptr = topic_mask;
+ while(*ptr && (dpos <= TOPICLEN))
+ {
+ switch(*ptr)
+ {
+ case '%':
+ ptr++;
+ for(numpos = 0; isdigit(*ptr) && numpos < 3; ptr++) {
+ numbuf[numpos++] = *ptr;
+ }
+ numbuf[numpos] = 0;
+ if(!numpos || (advtopic_index = atoi(numbuf)) <= 0 || advtopic_index > MAXADVTOPICENTRIES) {
+ ptr -= numpos+1;
+ new_topic[dpos++] = *ptr; //is % again
+ break;
+ }
+ advtopic_index--; //no zero base
+ if(!cData->advtopic[advtopic_index])
+ break; //just leave it empty
+ len = strlen(cData->advtopic[advtopic_index]);
+ if((dpos + len) > TOPICLEN)
+ len = TOPICLEN + 1 - dpos;
+ memcpy(new_topic+dpos, cData->advtopic[advtopic_index], len);
+ dpos += len;
+ break;
+ case '\\':
+ ptr++; /* and fall through */
+ if(!*ptr) break;
+ default:
+ new_topic[dpos++] = *ptr;
+ ptr++;
+ break;
+ }
+ }
+ } else {
+ while((tchar = topic_mask[pos++]) && (dpos <= TOPICLEN))
+ {
+ switch(tchar)
+ {
+ case '*':
+ if(starpos != -1)
+ goto bad_mask;
+ len = strlen(topic);
+ if((dpos + len) > TOPICLEN)
+ len = TOPICLEN + 1 - dpos;
+ memcpy(new_topic+dpos, topic, len);
+ dpos += len;
+ starpos = pos;
+ break;
+ case '\\': tchar = topic_mask[pos++]; /* and fall through */
+ default: new_topic[dpos++] = tchar; break;
+ }
+ }
+ if((dpos > TOPICLEN) || tchar)
+ {
+ bad_mask:
+ reply("CSMSG_TOPICMASK_CONFLICT1", channel->name, topic_mask);
+ reply("CSMSG_TOPICMASK_CONFLICT2", TOPICLEN);
+ return 0;