--- say.c.orig	2005-07-12 18:58:25.000000000 +0400
+++ say.c	2005-07-31 00:05:14.000000000 +0400
@@ -282,6 +282,7 @@
       pt    - Portuguese
       se    - Swedish
       tw    - Taiwanese
+      ru    - Russian
 
  Gender:
  For Some languages the numbers differ for gender and plural
@@ -332,6 +333,7 @@
 static int ast_say_number_full_se(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd);
 static int ast_say_number_full_tw(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
 static int ast_say_number_full_gr(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
+static int ast_say_number_full_ru(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
 
 /* Forward declarations of language specific variants of ast_say_enumeration_full */
 static int ast_say_enumeration_full_en(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd);
@@ -424,7 +426,9 @@
 	} else if (!strcasecmp(language, "tw")) {	/* Taiwanese syntax */
 	   return(ast_say_number_full_tw(chan, num, ints, language, audiofd, ctrlfd));
 	} else if (!strcasecmp(language, "gr") ) {	/* Greek syntax */
-		return(ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd));
+	   return(ast_say_number_full_gr(chan, num, ints, language, audiofd, ctrlfd));
+	} else if (!strcasecmp(language, "ru") ) {	/* Russian syntax */
+	   return(ast_say_number_full_ru(chan, num, ints, language, audiofd, ctrlfd));
 	}
 
 	/* Default to english */
@@ -2140,6 +2144,116 @@
 	return res;
 }
 
+
+/*--- determine last digits for thousands/millions (ru) */
+static int get_lastdigits_ru(int num);
+static int get_lastdigits_ru(int num) {
+	if (num < 20) {
+		return num;
+	} else if (num < 100) {
+		return get_lastdigits_ru(num % 10);
+	} else if (num < 1000) {
+		return get_lastdigits_ru(num % 100);
+	}
+	return 0;	/* number too big */
+}
+
+
+/*--- ast_say_number_full_ru: Russian syntax */
+/*--- additional files:
+	n00.gsm			(one hundred, two hundred, ...)
+	n-thousand.sgm
+	n-million.gsm
+	thousands.gsm
+	millions.gsm
+    
+	where 'n' from 1 to 9
+*/
+static int ast_say_number_full_ru(struct ast_channel *chan, int num, const char *ints, const char *language, int audiofd, int ctrlfd)
+{
+	int res = 0;
+	int lastdigits = 0;
+	char fn[256] = "";
+	if (!num) 
+		return ast_say_digits_full(chan, 0,ints, language, audiofd, ctrlfd);
+
+	while(!res && (num)) {
+		if (num < 0) {
+			snprintf(fn, sizeof(fn), "digits/minus");
+			if ( num > INT_MIN ) {
+				num = -num;
+			} else {
+				num = 0;
+			}	
+		} else	if (num < 20) {
+			snprintf(fn, sizeof(fn), "digits/%d", num);
+			num = 0;
+		} else	if (num < 100) {
+			snprintf(fn, sizeof(fn), "digits/%d", num - (num % 10));
+			num %= 10;
+		} else 	if (num < 1000){
+			snprintf(fn, sizeof(fn), "digits/%d", num - (num % 100));
+			num %= 100;
+		} else 	if (num < 1000000) { /* 1,000,000 */
+			lastdigits = get_lastdigits_ru(num / 1000);
+			if (lastdigits > 9) { /* from 10 to 19 */
+				res = ast_say_number_full_ru(chan, lastdigits, ints, language, audiofd, ctrlfd);
+				if (res)
+					return res;
+				snprintf(fn, sizeof(fn), "digits/thousands");
+			} else if (lastdigits < 10 && lastdigits != 0) { /* from 1 to 9, actual numbers more than 19 */
+				if (((num / 1000) - lastdigits) > 19) {
+					res = ast_say_number_full_ru(chan, (num / 1000) - lastdigits, ints, language, audiofd, ctrlfd);
+					if (res)
+						return res;
+				}
+				snprintf(fn, sizeof(fn), "digits/%d-thousand", lastdigits);
+			} else if (lastdigits == 0) {
+				res = ast_say_number_full_ru(chan, (num / 1000), ints, language, audiofd, ctrlfd);
+				if (res)
+					return res;
+				snprintf(fn, sizeof(fn), "digits/thousands");
+			}
+			num %= 1000;
+		} else 	if (num < 1000000000) {	/* 1,000,000,000 */
+			lastdigits = get_lastdigits_ru(num / 1000000);
+			if (lastdigits > 9) { /* from 10 to 19 */
+				res = ast_say_number_full_ru(chan, lastdigits, ints, language, audiofd, ctrlfd);
+				if (res)
+					return res;
+				snprintf(fn, sizeof(fn), "digits/millions");
+			} else if (lastdigits < 10 && lastdigits != 0) { /* from 1 to 9, actual numbers more than 19 */
+				if (((num / 1000000) - lastdigits) > 19) {
+					res = ast_say_number_full_ru(chan, (num / 1000000) - lastdigits, ints, language, audiofd, ctrlfd);
+					if (res)
+						return res;
+				}
+				snprintf(fn, sizeof(fn), "digits/%d-million", lastdigits);
+			} else if (lastdigits == 0) {
+				res = ast_say_number_full_ru(chan, (num / 1000000), ints, language, audiofd, ctrlfd);
+				if (res)
+					return res;
+				snprintf(fn, sizeof(fn), "digits/millions");
+			}
+			num %= 1000000;
+		} else {
+			ast_log(LOG_DEBUG, "Number '%d' is too big for me\n", num);
+				res = -1;
+		}
+		if (!res) {
+			if (!ast_streamfile(chan, fn, language)) {
+				if ((audiofd  > -1) && (ctrlfd > -1))
+					res = ast_waitstream_full(chan, ints, audiofd, ctrlfd);
+				else
+					res = ast_waitstream(chan, ints);
+			}
+			ast_stopstream(chan);
+		}
+	}
+	return res;
+}
+
+
 /*--- ast_say_enumeration_full: call language-specific functions */
 /* Called from AGI */
 int ast_say_enumeration_full(struct ast_channel *chan, int num, const char *ints, const char *language, const char *options, int audiofd, int ctrlfd)
