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	23 Nov 2005 12:11:41 -0000
@@ -3182,46 +3182,60 @@ static struct sip_pvt *find_call(struct 
 static int sip_register(char *value, int lineno)
 {
 	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++;
-	}
-	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);
-		return -1;
+	int portnum = 0;
+
+	if (!value) {
+error:
+		ast_log(LOG_WARNING, "Format for registration is %s at line %d\n",
+			"user[:secret[:authuser]]@host[:port][/contact]",
+			lineno);
+		return -1;
+	}
+	ast_copy_string(username, value, sizeof(username));
+	/* First split around the last '@' then parse the two components. */
+	hostname = strrchr(username, '@'); /* allow @ in the first part */
+	if (hostname == NULL) {		/* look in the peer section */
+		struct sip_peer *peer = find_peer(username, NULL, 1);
+		if (peer == NULL) {
+			ast_log(LOG_WARNING, "peer %s for register not found\n", username);
+			return -1;
+		}
+		/* build and split the register string */
+		snprintf(username, sizeof(username), "%s:%s@%s/%s",
+			peer->username, peer->secret, peer->tohost, peer->regexten);
+		hostname = strrchr(username, '@');
 	}
-	stringp=username;
-	username = strsep(&stringp, ":");
-	if (username) {
-		secret = strsep(&stringp, ":");
-		if (secret) 
-			authuser = strsep(&stringp, ":");
+	if (hostname)
+		*hostname++ = '\0';
+	if (ast_strlen_zero(username) || ast_strlen_zero(hostname))
+		goto error;
+	/* 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 +3257,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);
@@ -12455,8 +12440,10 @@ static int reload_config(void)
 				ast_log(LOG_WARNING, "Empty context specified at line %d for domain '%s'\n", v->lineno, domain);
 			else
 				add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, context ? ast_strip(context) : "");
+#if 0 /* XXX delay register */
 		} else if (!strcasecmp(v->name, "register")) {
 			sip_register(v->value, v->lineno);
+#endif
 		} 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);
@@ -12526,6 +12513,12 @@ static int reload_config(void)
 		}
 		cat = ast_category_browse(cfg, cat);
 	}
+
+	/* XXX luigi - handle register */
+ 	for (v = ast_variable_browse(cfg, "general"); v; v = v->next)
+ 		if (!strcasecmp(v->name, "register"))
+			sip_register(v->value, v->lineno);
+
 	if (ast_find_ourip(&__ourip, bindaddr)) {
 		ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
 		return 0;
