--- app_meetme.c.orig	2004-05-05 19:08:16.000000000 -0400
+++ app_meetme.c	2004-05-06 19:30:57.000000000 -0400
@@ -63,7 +63,10 @@
 "             (Note: This does not work with non-Zap channels in the same conference)\n"
 "      Not implemented yet:\n"
 "      's' -- send user to admin/user menu if '*' is received\n"
-"      'a' -- set admin mode\n";
+"      'a' -- set admin mode\n"
+"      'A' -- set wait for admin mode\n"
+"      'h' -- set hangup if admin leave\n"
+"      'r' -- set retry on error\n";
 
 static char *descrip2 =
 "  MeetMeCount(confno[|var]): Plays back the number of users in the specifiedi\n"
@@ -82,6 +85,7 @@
 	int users;			/* Number of active users */
 	time_t start;			/* Start time (s) */
 	int isdynamic;			/* Created on the fly? */
+	int admin;			/* Admin in */
 	char pin[AST_MAX_EXTENSION];			/* If protected by a PIN */
 	struct ast_conference *next;
 } *confs;
@@ -96,6 +100,8 @@
 
 #define CONF_SIZE 160
 
+#define MAXRETRY    3
+
 #define CONFFLAG_ADMIN	(1 << 1)	/* If set the user has admin access on the conference */
 #define CONFFLAG_MONITOR (1 << 2)	/* If set the user can only receive audio from the conference */
 #define CONFFLAG_POUNDEXIT (1 << 3)	/* If set asterisk will exit conference when '#' is pressed */
@@ -105,7 +111,8 @@
 #define CONFFLAG_VIDEO (1 << 7)		/* Set to enable video mode */
 #define CONFFLAG_AGI (1 << 8)		/* Set to run AGI Script in Background */
 #define CONFFLAG_MOH (1 << 9)		/* Set to have music on hold when */
-
+#define CONFFLAG_WAITADMIN (1 << 10)	/* Set to wait for Admin */
+#define CONFFLAG_HANGUPADMIN (1 << 11)	/* Set to hangup when Admin Leave */
 
 static int careful_write(int fd, unsigned char *data, int len)
 {
@@ -257,6 +264,7 @@
 	int retryzap;
 	int origfd;
 	int musiconhold = 0;
+	int lastadmin = 0;
 	int firstpass = 0;
 	int ret = -1;
 	int x;
@@ -270,9 +278,18 @@
 	char *buf = __buf + AST_FRIENDLY_OFFSET;
 	
 	conf->users++;
-	if (!(confflags & CONFFLAG_QUIET) && conf->users == 1) {
-		if (!ast_streamfile(chan, "conf-onlyperson", chan->language))
-			ast_waitstream(chan, "");
+	if (confflags & CONFFLAG_ADMIN) 
+		conf->admin++;
+
+	if (confflags & CONFFLAG_QUIET) {
+	} else {
+		if (conf->users == 1 && ! (confflags & CONFFLAG_WAITADMIN)) 
+			if (!ast_streamfile(chan, "conf-onlyperson", chan->language))
+				ast_waitstream(chan, "");
+
+		if (confflags & CONFFLAG_WAITADMIN && conf->admin == 0 )
+			if (!ast_streamfile(chan, "conf-waitforchairman", chan->language))
+				ast_waitstream(chan, "");
 	}
 
 	if (confflags & CONFFLAG_VIDEO) {	
@@ -383,7 +400,8 @@
 	if (!firstpass && !(confflags & CONFFLAG_MONITOR) && !(confflags & CONFFLAG_ADMIN)) {
 		firstpass = 1;
 		if (!(confflags & CONFFLAG_QUIET))
-			conf_play(conf, ENTER);
+			if (confflags & CONFFLAG_WAITADMIN && conf->admin >=1 )
+				conf_play(conf, ENTER);
 	}
 
 	if (confflags & CONFFLAG_AGI) {
@@ -416,9 +434,10 @@
 	} else for(;;) {
 		outfd = -1;
 		ms = -1;
+		lastadmin = conf->admin;
 		c = ast_waitfor_nandfds(&chan, 1, &fd, nfds, NULL, &outfd, &ms);
-		/* trying to add moh for single person conf */
-		if (confflags & CONFFLAG_MOH) {
+
+		if (confflags & CONFFLAG_MOH && ! (confflags & CONFFLAG_WAITADMIN)) {
 			if (conf->users == 1) {
 				if (musiconhold == 0) {
 					ast_moh_start(chan, NULL);
@@ -431,7 +450,60 @@
 				}
 			}
 		}
-		/* end modifications */
+		if (confflags & CONFFLAG_WAITADMIN) {
+			if(conf->admin == 0) {
+				if (lastadmin != 0) {
+					if (!(confflags & CONFFLAG_QUIET))
+						if (!ast_streamfile(chan, "conf-adminhasleft", chan->language))
+							ast_waitstream(chan, "");
+					if(confflags & CONFFLAG_HANGUPADMIN)
+						break;
+					else {
+						ztc.confmode = ZT_CONF_CONF;
+						if (ioctl(fd, ZT_SETCONF, &ztc)) {
+							ast_log(LOG_WARNING, "Error setting conference\n");
+							close(fd);
+							goto outrun;
+						}
+					}
+			
+				}
+				if (musiconhold == 0 && confflags & CONFFLAG_MOH) {
+					ast_moh_start(chan, NULL);
+					musiconhold = 1;
+				} else {
+					ztc.confmode = ZT_CONF_CONF;
+					if (ioctl(fd, ZT_SETCONF, &ztc)) {
+						ast_log(LOG_WARNING, "Error setting conference\n");
+						close(fd);
+						goto outrun;
+					}
+
+				}
+			} else if(conf->admin >= 1 && lastadmin == 0) {
+				if (confflags & CONFFLAG_MONITOR)
+					ztc.confmode = ZT_CONF_CONFMON | ZT_CONF_LISTENER;
+				else if (confflags & CONFFLAG_TALKER)
+					ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER;
+				else
+					ztc.confmode = ZT_CONF_CONF | ZT_CONF_TALKER | ZT_CONF_LISTENER;
+				if (ioctl(fd, ZT_SETCONF, &ztc)) {
+					ast_log(LOG_WARNING, "Error setting conference\n");
+					close(fd);
+					goto outrun;
+				}
+				if (musiconhold && confflags & CONFFLAG_MOH) {
+					ast_moh_stop(chan);
+					musiconhold = 0;
+				}
+				if ( !(confflags & CONFFLAG_QUIET)) {
+					if (!ast_streamfile(chan, "conf-placeintoconf", chan->language))
+						ast_waitstream(chan, "");
+					conf_play(conf, ENTER);
+				}
+			}			
+			
+		}	
 
 		if (c) {
 			if (c->fds[0] != origfd) {
@@ -498,11 +570,16 @@
 		}
 	}
 	if (!(confflags & CONFFLAG_QUIET) && !(confflags & CONFFLAG_MONITOR) && !(confflags & CONFFLAG_ADMIN))
-		conf_play(conf, LEAVE);
+		if (confflags & CONFFLAG_WAITADMIN && conf->admin == 1 )
+			conf_play(conf, LEAVE);
 
 outrun:
 
 	ast_mutex_lock(&conflock);
+	/*  set 0 if admin leave so we hangup everyone */
+	if (confflags & CONFFLAG_ADMIN && conf->admin == 1) 
+		conf->admin--;
+
 	/* Clean up */
 	conf->users--;
 	if (!conf->users) {
@@ -632,6 +709,7 @@
 	int res=-1;
 	struct localuser *u;
 	char confno[AST_MAX_EXTENSION] = "";
+	char originconfno[AST_MAX_EXTENSION] = "";
 	int allowretry = 0;
 	int retrycnt = 0;
 	struct ast_conference *cnf;
@@ -657,7 +735,10 @@
 		strncpy(confno, tmp, sizeof(confno));
 		if (strlen(confno) == 0) {
 			allowretry = 1;
+		} else {
+			strncpy(originconfno,confno,sizeof(confno));
 		}
+		
 	}
 	if (info)
 		inflags = strsep(&info, "|");
@@ -685,6 +766,12 @@
 			confflags |= CONFFLAG_AGI;
 		if (strchr(inflags, 'd'))
 			dynamic = 1;
+		if (strchr(inflags, 'A'))
+			confflags |= CONFFLAG_WAITADMIN;
+		if (strchr(inflags, 'r'))
+			allowretry = 1;
+		if (strchr(inflags, 'h'))
+			confflags |= CONFFLAG_HANGUPADMIN;
 		if (strchr(inflags, 'D')) {
 			dynamic = 1;
 			if (! inpin) {
@@ -700,7 +787,7 @@
 	}
 
 	do {
-		if (retrycnt > 3)
+		if (retrycnt > MAXRETRY)
 			allowretry = 0;
 		if (empty) {
 			int i, map[1024];
@@ -789,7 +876,7 @@
 				}
 			}
 		}
-		while (allowretry && (!strlen(confno)) && (++retrycnt < 4)) {
+		while (allowretry && (!strlen(confno)) && (++retrycnt <= MAXRETRY)) {
 			/* Prompt user for conference number */
 			res = ast_app_getdata(chan, "conf-getconfno", confno, sizeof(confno) - 1, 0);
 			if (res < 0) {
@@ -818,7 +905,8 @@
 						res = 0;
 					} else {
 						/* Prompt user for pin if pin is required */
-						res = ast_app_getdata(chan, "conf-getpin", pin, sizeof(pin) - 1, 0);
+						if (++retrycnt <= MAXRETRY)
+							res = ast_app_getdata(chan, "conf-getpin", pin, sizeof(pin) - 1, 0);
 					}
 					if (res >= 0) {
 						if (!strcasecmp(pin, cnf->pin)) {
@@ -832,7 +920,7 @@
 							if (!res)
 								ast_waitstream(chan, "");
 							res = -1;
-							if (allowretry)
+							if (allowretry && sizeof(originconfno) == 0)
 								strcpy(confno, "");
 						}
 					} else {
