diff -ur asterisk-1.6.1.1/apps/app_meetme.c asterisk-1.6.1.1-hw/apps/app_meetme.c
--- asterisk-1.6.1.1/apps/app_meetme.c	2009-03-03 00:39:56.000000000 +0100
+++ asterisk-1.6.1.1-hw/apps/app_meetme.c	2009-08-17 22:50:39.630533478 +0200
@@ -172,6 +172,7 @@
 	OPT_ARG_DURATION_LIMIT = 3,
 	OPT_ARG_MOH_CLASS = 4,
 	OPT_ARG_ARRAY_SIZE = 5,
+	OPT_ARG_MUTETYPE = 6,
 };
 
 AST_APP_OPTIONS(meetme_opts, BEGIN_OPTIONS
@@ -188,7 +189,7 @@
 	AST_APP_OPTION('i', CONFFLAG_INTROUSER ),
 	AST_APP_OPTION('I', CONFFLAG_INTROUSERNOREVIEW ),
 	AST_APP_OPTION_ARG('M', CONFFLAG_MOH, OPT_ARG_MOH_CLASS ),
-	AST_APP_OPTION('m', CONFFLAG_STARTMUTED ),
+	AST_APP_OPTION_ARG('m', CONFFLAG_STARTMUTED, OPT_ARG_MUTETYPE ),
 	AST_APP_OPTION('o', CONFFLAG_OPTIMIZETALKER ),
 	AST_APP_OPTION('P', CONFFLAG_ALWAYSPROMPT ),
 	AST_APP_OPTION_ARG('p', CONFFLAG_KEYEXIT, OPT_ARG_EXITKEYS ),
@@ -253,7 +254,9 @@
 "      'i' -- announce user join/leave with review\n"
 "      'I' -- announce user join/leave without review\n"
 "      'l' -- set listen only mode (Listen only, no talking)\n"
-"      'm' -- set initially muted\n"
+"      'm[(<type>)]'\n"
+"          -- set initially muted. When type is 'a', initially set an admin\n"
+"             mute, otherwise set a normal self mute on the user.\n"
 "      'M[(<class>)]'\n"
 "          -- enable music on hold when the conference has a single caller.\n"
 "             Optionally, specify a musiconhold class to use.  If one is not\n"
@@ -277,7 +280,10 @@
 "      't' -- set talk only mode. (Talk only, no listening)\n"
 "      'T' -- set talker detection (sent to manager interface and meetme list)\n"
 "      'w[(<secs>)]'\n"
-"          -- wait until the marked user enters the conference\n"
+"          -- wait until the marked user enters the conference. Append a 'c' to the\n"
+"             timeout specification to cancel marked wait once a conference has been\n"
+"             started for this user (i.e., the user isn't dropped back into wait\n"
+"             mode when all marked users leave\n"
 "      'x' -- close the conference when last marked user exits\n"
 "      'X' -- allow user to exit the conference by entering a valid single\n"
 "             digit extension ${MEETME_EXIT_CONTEXT} or the current context\n"
@@ -1672,7 +1678,7 @@
 	struct dahdi_bufferinfo bi;
 	char __buf[CONF_SIZE + AST_FRIENDLY_OFFSET];
 	char *buf = __buf + AST_FRIENDLY_OFFSET;
-	char *exitkeys = NULL;
+	char *exitkeys = "#";
  	unsigned int calldurationlimit = 0;
  	long timelimit = 0;
  	long play_warning = 0;
@@ -1684,16 +1690,22 @@
  	struct timeval nexteventts = { 0, };
  	int to;
 	int setusercount = 0;
+	char* mutetype = "u";
+	int markedcancel = 0;
 
 	if (!(user = ast_calloc(1, sizeof(*user))))
 		return ret;
 
 	/* Possible timeout waiting for marked user */
 	if ((confflags & CONFFLAG_WAITMARKED) &&
-		!ast_strlen_zero(optargs[OPT_ARG_WAITMARKED]) &&
-		(sscanf(optargs[OPT_ARG_WAITMARKED], "%d", &opt_waitmarked_timeout) == 1) &&
-		(opt_waitmarked_timeout > 0)) {
-		timeout = time(NULL) + opt_waitmarked_timeout;
+	    !ast_strlen_zero(optargs[OPT_ARG_WAITMARKED])) {
+		/* Find possible timeout specification */
+		if ((sscanf(optargs[OPT_ARG_WAITMARKED], "%d", &opt_waitmarked_timeout) == 1) &&
+		    (opt_waitmarked_timeout > 0))
+			timeout = time(NULL) + opt_waitmarked_timeout;
+
+		/* Find possible cancel specification */
+		markedcancel = strchr(optargs[OPT_ARG_WAITMARKED], 'c');
 	}
 	 	
  	if ((confflags & CONFFLAG_DURATION_STOP) && !ast_strlen_zero(optargs[OPT_ARG_DURATION_STOP])) {
@@ -1766,8 +1778,12 @@
 	if ((confflags & CONFFLAG_KEYEXIT)) {
 		if (!ast_strlen_zero(optargs[OPT_ARG_EXITKEYS]))
 			exitkeys = ast_strdupa(optargs[OPT_ARG_EXITKEYS]);
-		else
-			exitkeys = ast_strdupa("#"); /* Default */
+	}
+
+	/* Get mute flag */
+	if ((confflags & CONFFLAG_STARTMUTED)) {
+		if (!ast_strlen_zero(optargs[OPT_ARG_MUTETYPE]))
+			mutetype = ast_strdupa(optargs[OPT_ARG_MUTETYPE]);
 	}
 	
 	if (confflags & CONFFLAG_RECORDCONF) {
@@ -1868,7 +1884,7 @@
 
 	user->chan = chan;
 	user->userflags = confflags;
-	user->adminflags = (confflags & CONFFLAG_STARTMUTED) ? ADMINFLAG_SELFMUTED : 0;
+	user->adminflags = (confflags & CONFFLAG_STARTMUTED) ? (strchr(mutetype, 'a') ? ADMINFLAG_MUTED : ADMINFLAG_SELFMUTED) : 0;
 	user->talking = -1;
 
 	ast_mutex_unlock(&conf->playlock);
@@ -2275,9 +2291,6 @@
 							ast_waitstream(chan, "");
 					}
 				}
-				if (conf->users == 1 && ! (confflags & CONFFLAG_MARKEDUSER))
-					if (!ast_streamfile(chan, "conf-onlyperson", chan->language))
-						ast_waitstream(chan, "");
 			}
 
 			/* Update the struct with the actual confflags */
@@ -2328,6 +2341,10 @@
 						if (!ast_streamfile(chan, "conf-placeintoconf", chan->language))
 							ast_waitstream(chan, "");
 						conf_play(chan, conf, ENTER);
+
+						/* Check whether we're supposed to cancel the marked wait for channel */
+						if (markedcancel)
+							confflags &= ~CONFFLAG_WAITMARKED;
 					}
 				}
 			}
@@ -3325,6 +3342,8 @@
 					res = -1;
 				}
 			} else {
+				/* No more retries needed here */
+				allowretry = 0;
 				if ((!ast_strlen_zero(cnf->pin) &&
 				     !ast_test_flag(&confflags, CONFFLAG_ADMIN)) ||
 				    (!ast_strlen_zero(cnf->pinadmin) &&
@@ -3339,17 +3358,17 @@
 							res = 0;
 						} else {
 							/* Prompt user for pin if pin is required */
-							res = ast_app_getdata(chan, "conf-getpin", pin + strlen(pin), sizeof(pin) - 1 - strlen(pin), 0);
+							res = ast_app_getdata(chan, "conf-getpin", pin, sizeof(pin) - 1, 0);
 						}
 						if (res >= 0) {
-							if (!strcasecmp(pin, cnf->pin) ||
+							if ((!ast_strlen_zero(cnf->pin) &&
+							     !ast_test_flag(&confflags, CONFFLAG_ADMIN) &&
+							     !strcasecmp(pin, cnf->pin)) ||
 							    (!ast_strlen_zero(cnf->pinadmin) &&
 							     !strcasecmp(pin, cnf->pinadmin))) {
-								/* Pin correct */
-								allowretry = 0;
+								/* Pin correct; either no admin and user pin entered, or admin pin entered */
 								if (!ast_strlen_zero(cnf->pinadmin) && !strcasecmp(pin, cnf->pinadmin)) 
 									ast_set_flag(&confflags, CONFFLAG_ADMIN);
-								/* Run the conference */
 								res = conf_run(chan, cnf, confflags.flags, optargs);
 								break;
 							} else {
@@ -3364,17 +3383,12 @@
 								}
 								if (res < 0)
 									break;
-								pin[0] = res;
-								pin[1] = '\0';
+								pin[0] = '\0';
 								res = -1;
-								if (allowretry)
-									confno[0] = '\0';
 							}
 						} else {
-							/* failed when getting the pin */
+							/* failed when getting the pin and get rid of conference */
 							res = -1;
-							allowretry = 0;
-							/* see if we need to get rid of the conference */
 							break;
 						}
 
@@ -3384,14 +3398,9 @@
 						}
 					}
 				} else {
-					/* No pin required */
-					allowretry = 0;
-
-					/* Run the conference */
+					/* Run the conference, no pin needed for user mode */
 					res = conf_run(chan, cnf, confflags.flags, optargs);
 				}
-				dispose_conf(cnf);
-				cnf = NULL;
 			}
 		}
 	} while (allowretry);
Only in asterisk-1.6.1.1-hw/apps: app_meetme.c~
