mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Version 0.1.11 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@417 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -48,6 +48,23 @@ | ||||
|  | ||||
| #define VM_SPOOL_DIR AST_SPOOL_DIR "/vm" | ||||
|  | ||||
| #define BASEMAXINLINE 256 | ||||
|  | ||||
| #define BASELINELEN 72 | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #define BASEMAXINLINE 256 | ||||
| #define BASELINELEN 72 | ||||
| #define eol "\r\n" | ||||
|  | ||||
| int iocp; | ||||
| int iolen; | ||||
| int linelength; | ||||
| int ateof; | ||||
| unsigned char iobuf[BASEMAXINLINE]; | ||||
|  | ||||
| static char *tdesc = "Comedian Mail (Voicemail System)"; | ||||
|  | ||||
| @@ -106,6 +123,7 @@ static int announce_message(struct ast_channel *chan, char *dir, int msgcnt) | ||||
| { | ||||
| 	char *fn; | ||||
| 	int res; | ||||
|  | ||||
| 	res = ast_streamfile(chan, "vm-message", chan->language); | ||||
| 	if (!res) { | ||||
| 		res = ast_waitstream(chan, AST_DIGIT_ANY); | ||||
| @@ -126,15 +144,141 @@ static int announce_message(struct ast_channel *chan, char *dir, int msgcnt) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| static int sendmail(char *srcemail, char *email, char *name, int msgnum, char *mailbox, char *callerid) | ||||
| static int | ||||
| inbuf(FILE *fi) | ||||
| { | ||||
| 	int l; | ||||
|  | ||||
| 	if(ateof) | ||||
| 		return 0; | ||||
|  | ||||
| 	if ( (l = fread(iobuf,1,BASEMAXINLINE,fi)) <= 0) { | ||||
| 		if(ferror(fi)) | ||||
| 			return -1; | ||||
|  | ||||
| 		ateof = 1; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	iolen= l; | ||||
| 	iocp= 0; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int  | ||||
| inchar(FILE *fi) | ||||
| { | ||||
| 	if(iocp>=iolen) | ||||
| 		if(!inbuf(fi)) | ||||
| 			return EOF; | ||||
|  | ||||
| 	return iobuf[iocp++]; | ||||
| } | ||||
|  | ||||
| static int | ||||
| ochar(int c, FILE *so) | ||||
| { | ||||
| 	if(linelength>=BASELINELEN) { | ||||
| 		if(fputs(eol,so)==EOF) | ||||
| 			return -1; | ||||
|  | ||||
| 		linelength= 0; | ||||
| 	} | ||||
|  | ||||
| 	if(putc(((unsigned char)c),so)==EOF) | ||||
| 		return -1; | ||||
|  | ||||
| 	linelength++; | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int base_encode(char *filename, FILE *so) | ||||
| { | ||||
| 	unsigned char dtable[BASEMAXINLINE]; | ||||
| 	int i,hiteof= 0; | ||||
| 	FILE *fi; | ||||
|  | ||||
| 	linelength = 0; | ||||
| 	iocp = BASEMAXINLINE; | ||||
| 	iolen = 0; | ||||
| 	ateof = 0; | ||||
|  | ||||
| 	if ( !(fi = fopen(filename, "rb"))) { | ||||
| 		ast_log(LOG_WARNING, "Failed to open log file: %s: %s\n", filename, strerror(errno)); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	for(i= 0;i<9;i++){ | ||||
| 		dtable[i]= 'A'+i; | ||||
| 		dtable[i+9]= 'J'+i; | ||||
| 		dtable[26+i]= 'a'+i; | ||||
| 		dtable[26+i+9]= 'j'+i; | ||||
| 	} | ||||
| 	for(i= 0;i<8;i++){ | ||||
| 		dtable[i+18]= 'S'+i; | ||||
| 		dtable[26+i+18]= 's'+i; | ||||
| 	} | ||||
| 	for(i= 0;i<10;i++){ | ||||
| 		dtable[52+i]= '0'+i; | ||||
| 	} | ||||
| 	dtable[62]= '+'; | ||||
| 	dtable[63]= '/'; | ||||
|  | ||||
| 	while(!hiteof){ | ||||
| 		unsigned char igroup[3],ogroup[4]; | ||||
| 		int c,n; | ||||
|  | ||||
| 		igroup[0]= igroup[1]= igroup[2]= 0; | ||||
|  | ||||
| 		for(n= 0;n<3;n++){ | ||||
| 			if ( (c = inchar(fi)) == EOF) { | ||||
| 				hiteof= 1; | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| 			igroup[n]= (unsigned char)c; | ||||
| 		} | ||||
|  | ||||
| 		if(n> 0){ | ||||
| 			ogroup[0]= dtable[igroup[0]>>2]; | ||||
| 			ogroup[1]= dtable[((igroup[0]&3)<<4)|(igroup[1]>>4)]; | ||||
| 			ogroup[2]= dtable[((igroup[1]&0xF)<<2)|(igroup[2]>>6)]; | ||||
| 			ogroup[3]= dtable[igroup[2]&0x3F]; | ||||
|  | ||||
| 			if(n<3) { | ||||
| 				ogroup[3]= '='; | ||||
|  | ||||
| 				if(n<2) | ||||
| 					ogroup[2]= '='; | ||||
| 			} | ||||
|  | ||||
| 			for(i= 0;i<4;i++) | ||||
| 				ochar(ogroup[i], so); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(fputs(eol,so)==EOF) | ||||
| 		return 0; | ||||
|  | ||||
| 	fclose(fi); | ||||
|  | ||||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int sendmail(char *srcemail, char *email, char *name, int msgnum, char *mailbox, char *callerid, char *attach, char *format) | ||||
| { | ||||
| 	FILE *p; | ||||
| 	char date[256]; | ||||
| 	char host[256]; | ||||
| 	char who[256]; | ||||
| 	char bound[256]; | ||||
| 	char fname[256]; | ||||
| 	time_t t; | ||||
| 	struct tm *tm; | ||||
| 	p = popen(SENDMAIL, "w"); | ||||
|  | ||||
| 	if (p) { | ||||
| 		if (strchr(srcemail, '@')) | ||||
| 			strncpy(who, srcemail, sizeof(who)-1); | ||||
| @@ -146,16 +290,35 @@ static int sendmail(char *srcemail, char *email, char *name, int msgnum, char *m | ||||
| 		tm = localtime(&t); | ||||
| 		strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S %z", tm); | ||||
| 		fprintf(p, "Date: %s\n", date); | ||||
| 		fprintf(p, "Message-ID: <Asterisk-%d-%s-%d@%s>\n", msgnum, mailbox, getpid(), host); | ||||
| 		fprintf(p, "From: Asterisk PBX <%s>\n", who); | ||||
| 		fprintf(p, "To: %s <%s>\n", name, email); | ||||
| 		fprintf(p, "Subject: [PBX]: New message %d in mailbox %s\n\n", msgnum, mailbox); | ||||
| 		fprintf(p, "Subject: [PBX]: New message %d in mailbox %s\n", msgnum, mailbox); | ||||
| 		fprintf(p, "Message-ID: <Asterisk-%d-%s-%d@%s>\n", msgnum, mailbox, getpid(), host); | ||||
| 		fprintf(p, "MIME-Version: 1.0\n"); | ||||
|  | ||||
| 		// Something unique. | ||||
| 		snprintf(bound, sizeof(bound), "Boundary=%d%s%d", msgnum, mailbox, getpid()); | ||||
|  | ||||
| 		fprintf(p, "Content-Type: MULTIPART/MIXED; BOUNDARY=\"%s\"\n\n\n", bound); | ||||
|  | ||||
| 		fprintf(p, "--%s\n", bound); | ||||
| 		fprintf(p, "Content-Type: TEXT/PLAIN; charset=US-ASCII\n\n"); | ||||
| 		strftime(date, sizeof(date), "%A, %B %d, %Y at %r", tm); | ||||
| 		fprintf(p, "Dear %s:\n\n\tJust wanted to let you know you were just left a message (number %d)\n" | ||||
|  | ||||
| 		           "in mailbox %s from %s, on %s so you might\n" | ||||
| 				   "want to check it when you get a chance.  Thanks!\n\n\t\t\t\t--Asterisk\n", name,  | ||||
| 				   "want to check it when you get a chance.  Thanks!\n\n\t\t\t\t--Asterisk\n\n", name,  | ||||
| 			msgnum, mailbox, (callerid ? callerid : "an unknown caller"), date); | ||||
| 		fprintf(p, ".\n"); | ||||
|  | ||||
| 		fprintf(p, "--%s\n", bound); | ||||
| 		fprintf(p, "Content-Type: TEXT/PLAIN; charset=US-ASCII; name=\"msg%04d\"\n", msgnum); | ||||
| 		fprintf(p, "Content-Transfer-Encoding: BASE64\n"); | ||||
| 		fprintf(p, "Content-Description: Voicemail sound attachment.\n"); | ||||
| 		fprintf(p, "Content-Disposition: attachment; filename=\"msg%04d.%s\"\n\n", msgnum, format); | ||||
|  | ||||
| 		snprintf(fname, sizeof(fname), "%s.%s", attach, format); | ||||
| 		base_encode(fname, p); | ||||
| 		fprintf(p, "\n\n--%s--\n.\n", bound); | ||||
| 		pclose(p); | ||||
| 	} else { | ||||
| 		ast_log(LOG_WARNING, "Unable to launch '%s'\n", SENDMAIL); | ||||
| @@ -207,13 +370,14 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int | ||||
| 	int res = -1, fmtcnt=0, x; | ||||
| 	int msgnum; | ||||
| 	int outmsg=0; | ||||
| 	int wavother=0; | ||||
| 	struct ast_frame *f; | ||||
| 	char date[256]; | ||||
| 	char dir[256]; | ||||
| 	char fn[256]; | ||||
| 	char prefile[256]=""; | ||||
| 	char *astemail; | ||||
| 	 | ||||
|  | ||||
| 	cfg = ast_load(VOICEMAIL_CONFIG); | ||||
| 	if (!cfg) { | ||||
| 		ast_log(LOG_WARNING, "No such configuration file %s\n", VOICEMAIL_CONFIG); | ||||
| @@ -241,7 +405,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int | ||||
| 			ast_log(LOG_WARNING, "mkdir '%s' failed: %s\n", dir, strerror(errno)); | ||||
| 		/* Play the beginning intro if desired */ | ||||
| 		if (strlen(prefile)) { | ||||
| 			if (ast_fileexists(prefile, NULL, NULL) < 0) { | ||||
| 			if (ast_fileexists(prefile, NULL, NULL) > 0) { | ||||
| 				if (ast_streamfile(chan, prefile, chan->language) > -1)  | ||||
| 				    silent = ast_waitstream(chan, "#"); | ||||
| 			} else { | ||||
| @@ -333,6 +497,8 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int | ||||
| 									free(sfmt[y]); | ||||
| 								break; | ||||
| 							} | ||||
| 							if(!strcasecmp(sfmt[x], "wav")) | ||||
| 								wavother++; | ||||
| 							free(sfmt[x]); | ||||
| 						} | ||||
| 						if (x == fmtcnt) { | ||||
| @@ -340,7 +506,22 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int | ||||
| 							   we read a # or get a hangup */ | ||||
| 							if (option_verbose > 2)  | ||||
| 								ast_verbose( VERBOSE_PREFIX_3 "Recording to %s\n", fn); | ||||
| 							while((f = ast_read(chan))) { | ||||
| 							f = NULL; | ||||
| 							for(;;) { | ||||
| 								res = ast_waitfor(chan, 2000); | ||||
| 								if (!res) { | ||||
| 									ast_log(LOG_WARNING, "No audio available on %s??\n", chan->name); | ||||
| 									res = -1; | ||||
| 								} | ||||
| 								 | ||||
| 								if (res < 0) { | ||||
| 									f = NULL; | ||||
| 									break; | ||||
| 								} | ||||
|  | ||||
| 								f = ast_read(chan); | ||||
| 								if (!f) | ||||
| 									break; | ||||
| 								if (f->frametype == AST_FRAME_VOICE) { | ||||
| 									/* Write the primary format */ | ||||
| 									res = ast_writestream(writer, f); | ||||
| @@ -378,6 +559,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int | ||||
| 							ast_log(LOG_WARNING, "Error creating writestream '%s', format '%s'\n", fn, sfmt[x]);  | ||||
| 							free(sfmt[x]); | ||||
| 						} | ||||
|  | ||||
| 						ast_closestream(writer); | ||||
| 						for (x=0;x<fmtcnt;x++) { | ||||
| 							if (!others[x]) | ||||
| @@ -391,8 +573,7 @@ static int leave_voicemail(struct ast_channel *chan, char *ext, int silent, int | ||||
| 								ast_waitstream(chan, ""); | ||||
| 							} | ||||
| 							/* Send e-mail if applicable */ | ||||
| 							if (email)  | ||||
| 								sendmail(astemail, email, name, msgnum, ext, chan->callerid); | ||||
| 								sendmail(astemail, email, name, msgnum, ext, chan->callerid, fn, wavother ? "wav" : fmts); | ||||
| 						} | ||||
| 					} else { | ||||
| 						if (msgnum < MAXMSG) | ||||
| @@ -1014,6 +1195,45 @@ static int get_folder(struct ast_channel *chan, int start) | ||||
| 	return d; | ||||
| } | ||||
|  | ||||
| static int | ||||
| forward_message(struct ast_channel *chan, struct ast_config *cfg, char *dir, int curmsg) | ||||
| { | ||||
| 	char username[70]; | ||||
| 	char sys[256]; | ||||
| 	char todir[256]; | ||||
| 	int todircount=0; | ||||
|  | ||||
| 	while(1) { | ||||
| 		ast_streamfile(chan, "vm-extension", chan->language); | ||||
|  | ||||
| 		if (ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0) | ||||
| 			return 0; | ||||
| 		if (ast_variable_retrieve(cfg, NULL, username)) { | ||||
| 			printf("Got %d\n", atoi(username)); | ||||
| 			if (play_and_wait(chan, "vm-savedto")) | ||||
| 				break; | ||||
|  | ||||
| 			snprintf(todir, sizeof(todir), "%s/%s/INBOX", VM_SPOOL_DIR, username); | ||||
| 			snprintf(sys, sizeof(sys), "mkdir -p %s\n", todir); | ||||
| 			puts(sys); | ||||
| 			system(sys); | ||||
|  | ||||
| 			todircount = count_messages(todir); | ||||
|  | ||||
| 			snprintf(sys, sizeof(sys), "cp %s/msg%04d.gsm %s/msg%04d.gsm\n", dir, curmsg, todir, todircount); | ||||
| 			puts(sys); | ||||
| 			system(sys); | ||||
|  | ||||
| 			break; | ||||
| 		} else { | ||||
| 			if ( play_and_wait(chan, "pbx-invalid")) | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| #define WAITCMD(a) do { \ | ||||
| 	d = (a); \ | ||||
| 	if (d < 0) \ | ||||
| @@ -1132,7 +1352,7 @@ static int vm_execmain(struct ast_channel *chan, void *data) | ||||
| 	int box; | ||||
| 	int useadsi = 0; | ||||
| 	struct ast_config *cfg; | ||||
| 	 | ||||
|  | ||||
| 	LOCAL_USER_ADD(u); | ||||
| 	cfg = ast_load(VOICEMAIL_CONFIG); | ||||
| 	if (!cfg) { | ||||
| @@ -1155,7 +1375,7 @@ static int vm_execmain(struct ast_channel *chan, void *data) | ||||
| 	 | ||||
| 	do { | ||||
| 		/* Prompt for, and read in the username */ | ||||
| 		if (ast_readstring(chan, username, sizeof(username), 2000, 10000, "#") < 0) { | ||||
| 		if (ast_readstring(chan, username, sizeof(username) - 1, 2000, 10000, "#") < 0) { | ||||
| 			ast_log(LOG_WARNING, "Couldn't read username\n"); | ||||
| 			goto out; | ||||
| 		}			 | ||||
| @@ -1171,7 +1391,7 @@ static int vm_execmain(struct ast_channel *chan, void *data) | ||||
| 			ast_log(LOG_WARNING, "Unable to stream password file\n"); | ||||
| 			goto out; | ||||
| 		} | ||||
| 		if (ast_readstring(chan, password, sizeof(password), 2000, 10000, "#") < 0) { | ||||
| 		if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) { | ||||
| 			ast_log(LOG_WARNING, "Unable to read password\n"); | ||||
| 			goto out; | ||||
| 		} | ||||
| @@ -1219,6 +1439,7 @@ static int vm_execmain(struct ast_channel *chan, void *data) | ||||
| 		if (newmessages) { | ||||
| 			WAITCMD(say_and_wait(chan, newmessages)); | ||||
| 			WAITCMD(play_and_wait(chan, "vm-INBOX")); | ||||
|  | ||||
| 			if (oldmessages) | ||||
| 				WAITCMD(play_and_wait(chan, "vm-and")); | ||||
| 			else { | ||||
| @@ -1339,6 +1560,11 @@ cmd: | ||||
| 			else | ||||
| 				WAITCMD(play_and_wait(chan, "vm-undeleted")); | ||||
| 			goto instructions; | ||||
| 		case '8': | ||||
| 			if(lastmsg > -1) | ||||
| 				if(forward_message(chan, cfg, curdir, curmsg) < 0) | ||||
| 					goto out; | ||||
| 			goto instructions; | ||||
| 		case '9': | ||||
| 			if (useadsi) | ||||
| 				adsi_folders(chan, 1, "Save to folder..."); | ||||
| @@ -1406,6 +1632,7 @@ static int vm_exec(struct ast_channel *chan, void *data) | ||||
| 	struct localuser *u; | ||||
| 	char *ext = (char *)data; | ||||
| 	 | ||||
|  | ||||
| 	if (!data) { | ||||
| 		ast_log(LOG_WARNING, "vm requires an argument (extension)\n"); | ||||
| 		return -1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user