Index: channels/chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.915
diff -u -u -p -r1.915 chan_sip.c
--- channels/chan_sip.c	21 Nov 2005 00:57:35 -0000	1.915
+++ channels/chan_sip.c	24 Nov 2005 13:06:12 -0000
@@ -3179,49 +3179,57 @@ static struct sip_pvt *find_call(struct 
 }
 
 /*! \brief  sip_register: Parse register=> line in sip.conf and add to registry */
-static int sip_register(char *value, int lineno)
+static int sip_register(const char *value, int lineno,
+	const struct sip_peer *peer)
 {
 	struct sip_registry *reg;
-	char copy[256];
-	char *username=NULL, *hostname=NULL, *secret=NULL, *authuser=NULL;
+	char username[256];
+	char *hostname=NULL, *secret=NULL, *authuser=NULL;
 	char *porta=NULL;
 	char *contact=NULL;
-	char *stringp=NULL;
-	
-	if (!value)
-		return -1;
-	ast_copy_string(copy, value, sizeof(copy));
-	stringp=copy;
-	username = stringp;
-	hostname = strrchr(stringp, '@');
-	if (hostname) {
-		*hostname = '\0';
-		hostname++;
-	}
+	int portnum = 0;
+
+	if (peer) {	/* build string from peer info */
+		/* XXX authuser ? port ? contact is regexten... */
+		snprintf(username, sizeof(username), "%s:%s@%s/%s",
+			peer->username, peer->secret, peer->tohost, peer->regexten);
+	} else if (value)
+		ast_copy_string(username, value, sizeof(username));
+	else
+		username[0] = '\0';
+	/* First split around the last '@' then parse the two components. */
+	hostname = strrchr(username, '@'); /* allow @ in the first part */
+	if (hostname)
+		*hostname++ = '\0';
 	if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
-		ast_log(LOG_WARNING, "Format for registration is user[:secret[:authuser]]@host[:port][/contact] at line %d\n", lineno);
+		ast_log(LOG_WARNING, "Format for registration is %s at line %d\n",
+			"user[:secret[:authuser]]@host[:port][/contact]",
+			lineno);
 		return -1;
 	}
-	stringp=username;
-	username = strsep(&stringp, ":");
-	if (username) {
-		secret = strsep(&stringp, ":");
-		if (secret) 
-			authuser = strsep(&stringp, ":");
+	/* split user[:secret[:authuser]] */
+	secret = strchr(username, ':');
+	if (secret) {
+		*secret++ = '\0';
+		authuser = strchr(secret, ':');
+		if (authuser)
+			*authuser++ = '\0';
 	}
-	stringp = hostname;
-	hostname = strsep(&stringp, "/");
-	if (hostname) 
-		contact = strsep(&stringp, "/");
+	/* split host[:port][/contact] */
+	contact = strchr(hostname, '/');
+	if (contact)
+		*contact++ = '\0';
 	if (ast_strlen_zero(contact))
 		contact = "s";
-	stringp=hostname;
-	hostname = strsep(&stringp, ":");
-	porta = strsep(&stringp, ":");
-	
-	if (porta && !atoi(porta)) {
-		ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
-		return -1;
+	porta = strchr(hostname, ':');
+	if (porta) {
+		*porta++ = '\0';
+		portnum = atoi(porta);
+		if (portnum == 0) {
+			ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n",
+				porta, lineno);
+			return -1;
+		}
 	}
 	reg = malloc(sizeof(struct sip_registry));
 	if (!reg) {
@@ -3243,7 +3251,7 @@ static int sip_register(char *value, int
 	reg->expire = -1;
 	reg->timeout =  -1;
 	reg->refresh = default_expiry;
-	reg->portno = porta ? atoi(porta) : 0;
+	reg->portno = portnum;
 	reg->callid_valid = 0;
 	reg->ocseq = 101;
 	ASTOBJ_CONTAINER_LINK(&regl, reg);
@@ -11963,7 +11938,7 @@ static struct sip_peer *build_peer(const
 	struct ast_variable *tmpvar = NULL;
 	struct ast_flags peerflags = {(0)};
 	struct ast_flags mask = {(0)};
-
+	int register_lineno = 0;
 
 	if (!realtime)
 		/* Note we do NOT use find_peer here, to avoid realtime recursion */
@@ -12003,6 +11978,7 @@ static struct sip_peer *build_peer(const
 	if (peer->chanvars) {
 		ast_variables_destroy(peer->chanvars);
 		peer->chanvars = NULL;
+		/* XXX should unregister ? */
 	}
 	strcpy(peer->context, default_context);
 	strcpy(peer->subscribecontext, default_subscribecontext);
@@ -12183,6 +12159,8 @@ static struct sip_peer *build_peer(const
 				ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
 				peer->maxms = 0;
 			}
+		} else if (!strcasecmp(v->name, "register")) {
+			register_lineno = v->lineno;
 		}
 		/* else if (strcasecmp(v->name,"type"))
 		 *	ast_log(LOG_WARNING, "Ignoring %s\n", v->name);
@@ -12205,6 +12183,8 @@ static struct sip_peer *build_peer(const
 		reg_source_db(peer);
 	ASTOBJ_UNMARK(peer);
 	ast_free_ha(oldha);
+	if (register_lineno > 0)
+		sip_register(NULL, register_lineno, peer);
 	return peer;
 }
 
@@ -12456,7 +12436,7 @@ static int reload_config(void)
 			else
 				add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
 		} else if (!strcasecmp(v->name, "register")) {
-			sip_register(v->value, v->lineno);
+			sip_register(v->value, v->lineno, NULL);
 		} else if (!strcasecmp(v->name, "tos")) {
 			if (ast_str2tos(v->value, &tos))
 				ast_log(LOG_WARNING, "Invalid tos value at line %d, should be 'lowdelay', 'throughput', 'reliability', 'mincost', or 'none'\n", v->lineno);
