+ join_next:
+ /* next channel? */
+ channame = strtok_r(NULL, ",", &lastchan);
+ if (channame && key)
+ key = strtok_r(NULL, ",", &lastkey);
+ }
+ return CONNECTED;
+} /* IRC_JOIN */
+
+
+/**
+ * Handler for the IRC "PART" command.
+ *
+ * See RFC 2812, 3.2.2: "Part message".
+ *
+ * @param Client The client from which this command has been received
+ * @param Req Request structure with prefix and all parameters
+ * @returns CONNECTED or DISCONNECTED
+ */
+GLOBAL bool
+IRC_PART(CLIENT * Client, REQUEST * Req)
+{
+ CLIENT *target;
+ char *chan;
+
+ assert(Client != NULL);
+ assert(Req != NULL);
+
+ if (Req->argc < 1 || Req->argc > 2)
+ return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Client), Req->command);
+
+ /* Get the sender */
+ if (Client_Type(Client) == CLIENT_SERVER)
+ target = Client_Search(Req->prefix);
+ else
+ target = Client;
+ if (!target)
+ return IRC_WriteStrClient(Client, ERR_NOSUCHNICK_MSG,
+ Client_ID(Client), Req->prefix);
+
+ /* Loop over all the given channel names */
+ chan = strtok(Req->argv[0], ",");
+
+ /* Make sure that "chan" is not the empty string ("PART :") */
+ if (! chan)
+ return IRC_WriteStrClient(Client, ERR_NEEDMOREPARAMS_MSG,
+ Client_ID(Client), Req->command);
+
+ while (chan) {
+ Channel_Part(target, Client, chan,
+ Req->argc > 1 ? Req->argv[1] : Client_ID(target));
+ chan = strtok(NULL, ",");