diff --git a/asterisk.c b/asterisk.c
index bdf27e26763d99eb8fd92dc58a7776ca05755a64..5577fd73bac95d3bcca3d54e436b2b1bab219369 100644
--- a/asterisk.c
+++ b/asterisk.c
@@ -212,6 +212,7 @@ char ast_config_AST_CTL_PERMISSIONS[AST_CONFIG_MAX_PATH];
 char ast_config_AST_CTL_OWNER[AST_CONFIG_MAX_PATH] = "\0";
 char ast_config_AST_CTL_GROUP[AST_CONFIG_MAX_PATH] = "\0";
 char ast_config_AST_CTL[AST_CONFIG_MAX_PATH] = "asterisk.ctl";
+char ast_config_AST_SYSTEM_NAME[20]="";
 
 static char *_argv[256];
 static int shuttingdown = 0;
@@ -1982,6 +1983,8 @@ static void ast_readconfig(void) {
 		/* What group to run as */
 		} else if (!strcasecmp(v->name, "rungroup")) {
 			ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP));
+		} else if (!strcasecmp(v->name, "systemname")) {
+			ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME));
 		}
 		v = v->next;
 	}
diff --git a/channel.c b/channel.c
index 98590d0b8f26f5b4f8fe62f340057b7d5d3cf4b7..7495e88b646d196757d8d922885bc11e576c4195 100644
--- a/channel.c
+++ b/channel.c
@@ -670,7 +670,10 @@ struct ast_channel *ast_channel_alloc(int needqueue)
 	tmp->fin = global_fin;
 	tmp->fout = global_fout;
 	ast_mutex_lock(&uniquelock);
-	snprintf(tmp->uniqueid, sizeof(tmp->uniqueid), "%li.%d", (long) time(NULL), uniqueint++);
+	if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME))
+		ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), uniqueint++);
+	else
+		ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, (long) time(NULL), uniqueint++);
 	ast_mutex_unlock(&uniquelock);
 	headp = &tmp->varshead;
 	ast_mutex_init(&tmp->lock);
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index b8bc94f660eacbc9614d302cd57a117341124fef..d1213a5087243ab45a6b1b5517383ee7c4e24d74 100644
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -242,7 +242,7 @@ static AST_LIST_HEAD_STATIC(agents, agent_pvt);	/**< Holds the list of agents (l
 
 static struct ast_channel *agent_request(const char *type, int format, void *data, int *cause);
 static int agent_devicestate(void *data);
-static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, char *uniqueid, char *logcommand);
+static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, const char *uniqueid, char *logcommand);
 static int agent_digit(struct ast_channel *ast, char digit);
 static int agent_call(struct ast_channel *ast, char *dest, int timeout);
 static int agent_hangup(struct ast_channel *ast);
@@ -1430,7 +1430,7 @@ static int action_agents(struct mansession *s, struct message *m)
 	return 0;
 }
 
-static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, char *uniqueid, char *logcommand)
+static void agent_logoff_maintenance(struct agent_pvt *p, char *loginchan, long logintime, const char *uniqueid, char *logcommand)
 {
 	char *tmp = NULL;
 	char agent[AST_MAX_AGENT];
diff --git a/doc/asterisk-conf.txt b/doc/asterisk-conf.txt
index 4e210aacd3ae4c50afb2ae895efcd888757c61c7..1380291a04590395ca852effa3fede0c716e282c 100644
--- a/doc/asterisk-conf.txt
+++ b/doc/asterisk-conf.txt
@@ -62,6 +62,7 @@ maxload = 1.0					; The maximum load average we accept calls for
 maxcalls = 255					; The maximum number of concurrent calls you want to allow 
 execincludes = yes | no 			; Allow #exec entries in configuration files
 dontwarn = yes | no				; Don't over-inform the Asterisk sysadm, he's a guru
+systemname = <a_string>				; System name. Used to prefix CDR uniqueid and to fill ${SYSTEMNAME}
 
 [files]
 ; Changing the following lines may compromise your security
diff --git a/doc/channelvariables.txt b/doc/channelvariables.txt
index 3d76885eab2d43656ccd909cb4ca85dd5dd4410e..3b3a742b6231c5523be5a69e56912c054550cfb0 100644
--- a/doc/channelvariables.txt
+++ b/doc/channelvariables.txt
@@ -594,6 +594,7 @@ ${TIMESTAMP}	 	* Current date time in the format: YYYYMMDD-HHMMSS (Deprecated; u
 ${TRANSFER_CONTEXT} 	Context for transferred calls
 ${FORWARD_CONTEXT}     Context for forwarded calls
 ${UNIQUEID}	 	* Current call unique identifier
+${SYSTEMNAME}		* value of the systemname option of asterisk.conf
 
 Application return values
 -------------------------
diff --git a/include/asterisk.h b/include/asterisk.h
index a0ceeb40deb3205dcf74b34ba87d266115ac027a..1918af58ccc6366494e3c50be1b885bdd9bcbd1e 100644
--- a/include/asterisk.h
+++ b/include/asterisk.h
@@ -40,6 +40,7 @@ extern char ast_config_AST_CTL_PERMISSIONS[AST_CONFIG_MAX_PATH];
 extern char ast_config_AST_CTL_OWNER[AST_CONFIG_MAX_PATH];
 extern char ast_config_AST_CTL_GROUP[AST_CONFIG_MAX_PATH];
 extern char ast_config_AST_CTL[AST_CONFIG_MAX_PATH];
+extern char ast_config_AST_SYSTEM_NAME[20];
 
 /* Provided by asterisk.c */
 int ast_set_priority(int);
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index 6c00e2a874669b1160402c93b449ef9e1244cd4b..3c61a32acbc228d5f566c4363221f4f1f670dfa5 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -283,6 +283,7 @@ struct ast_channel {
 		AST_STRING_FIELD(musicclass);		/*! Default music class */
 		AST_STRING_FIELD(accountcode);		/*! Account code for billing */
 		AST_STRING_FIELD(call_forward);		/*! Where to forward to if asked to dial on this interface */
+		AST_STRING_FIELD(uniqueid);		/*! Unique Channel Identifier */
 	);
 	
 	/*! File descriptor for channel -- Drivers will poll on these file descriptors, so at least one must be non -1.  */
@@ -395,9 +396,6 @@ struct ast_channel {
 	unsigned int fin;
 	unsigned int fout;
 
-	/* Unique Channel Identifier */
-	char uniqueid[32];
-
 	/* Why is the channel hanged up */
 	int hangupcause;
 	
diff --git a/pbx.c b/pbx.c
index 6e3c8df565e7935717b6e0e2fe5542b53d9cb2e3..04f9a312a5a41109cb7f141ae8bdc082480bcddf 100644
--- a/pbx.c
+++ b/pbx.c
@@ -890,7 +890,7 @@ static char *substring(const char *value, int offset, int length, char *workspac
 void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, char *workspace, int workspacelen, struct varshead *headp)
 {
 	const char not_found = '\0';
-	char tmpvar[80];
+	char *tmpvar;
 	const char *s;	/* the result */
 	int offset, length;
 	int i, need_substring;
@@ -904,7 +904,7 @@ void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, c
 	 * Then if called directly, we might need to run substring() on the result;
 	 * remember this for later in 'need_substring', 'offset' and 'length'
 	 */
-	ast_copy_string(tmpvar, var, sizeof(tmpvar));	/* parse_variable_name modifies the string */
+	tmpvar = ast_strdupa(var);	/* parse_variable_name modifies the string */
 	need_substring = parse_variable_name(tmpvar, &offset, &length, &i /* ignored */);
 
 	/*
@@ -960,6 +960,8 @@ void pbx_retrieve_variable(struct ast_channel *c, const char *var, char **ret, c
 		if (!strcmp(var, "EPOCH")) {
 			snprintf(workspace, workspacelen, "%u",(int)time(NULL));
 			s = workspace;
+		} else if (!strcmp(var, "SYSTEMNAME")) {
+			ast_copy_string(workspace, ast_config_AST_SYSTEM_NAME, workspacelen);
 		}
 	}
 	/* if not found, look into chanvars or global vars */