Esempio n. 1
0
void SplitHostName(const char *hostname, String& host, int& port) {
	enum { DEFAULT_REMOTE_PORT = 2346 };
	const char *p = hostname;
	while(p && *p != ':')
		p++;
	host = String(hostname, p);
	if(*p++ == ':' && IsDigit(*p))
		port = stou(p);
	else
		port = DEFAULT_REMOTE_PORT;
}
Esempio n. 2
0
int ScanInt(const wchar *ptr, const wchar **endptr, int base)
{
	const wchar *s = ptr;
	bool minus = false;
	while(*s && *s <= ' ')
		s++;
	if(*s == '+' || *s == '-')
		minus = (*s++ == '-');
	unsigned u = stou(s, endptr, base);
	if(~u)
		return (minus ? -(int)u : (int)u);
	else
		return Null;
}
Esempio n. 3
0
One<SlaveProcess> StartProcess(const char *cmdline, const char *envptr, int timeout)
{
    if(*cmdline != '(')
        return StartLocalProcess(cmdline, envptr);
    const char *b = cmdline + 1, *p = b;
    while(*p && *p != ')' && *p != ':')
        p++;
    String host(b, p);
    int port = 0;
    if(*p == ':')
        port = stou(p + 1, &p);
    while(*p && *p++ != ')')
        ;
    if(*p == 0)
        throw Exc(NFormat(t_("Missing command line (host = %s)."), host));
    One<RemoteSlaveProcess> rsp = new RemoteSlaveProcess(host, port, p, envptr, timeout);
    return rsp.Detach();
}
Esempio n. 4
0
void RichQtfParser::Parse(const char *qtf, int _accesskey)
{
	accesskey = _accesskey;
	term = qtf;
	while(*term) {
		if(Key('[')) {
			Flush();
			fstack.Add(format);
			for(;;) {
				int c = *term;
				if(!c)
					Error("Unexpected end of text");
				term++;
				if(c == ' ' || c == '\n') break;
				switch(c) {
				case 's': {
					Uuid id;
					c = *term;
					if(Key('\"') || Key('\''))
						id = target.GetStyleId(GetText(c));
					else {
						int i = ReadNumber();
						if(i >= 0 && i < styleid.GetCount())
							id = styleid[i];
						else
							id = RichStyle::GetDefaultId();
					}
					const RichStyle& s = target.GetStyle(id);
					bool p = format.newpage;
					int lng = format.language;
					(RichPara::Format&) format = s.format;
					format.styleid = id;
					format.language = lng;
					format.newpage = p;
					break;
				}
				case '/': format.Italic(!format.IsItalic()); break;
				case '*': format.Bold(!format.IsBold()); break;
				case '_': format.Underline(!format.IsUnderline()); break;
				case 'T': format.NonAntiAliased(!format.IsNonAntiAliased()); break;
				case '-': format.Strikeout(!format.IsStrikeout()); break;
				case 'c': format.capitals = !format.capitals; break;
				case 'd': format.dashed = !format.dashed; break;
				case '`': format.sscript = format.sscript == 1 ? 0 : 1; break;
				case ',': format.sscript = format.sscript == 2 ? 0 : 2; break;
				case '^': format.link = GetText('^'); break;
				case 'I': format.indexentry = FromUtf8(GetText(';')); break;
				case '+': format.Height(GetNumber()); break;
				case '@': format.ink = GetColor(); break;
				case '$': format.paper = GetColor(); break;
				case 'A': format.Face(Font::ARIAL); break;
				case 'R': format.Face(Font::ROMAN); break;
				case 'C': format.Face(Font::COURIER); break;
				case 'G': format.Face(Font::STDFONT); break;
				case 'S':
#ifdef PLATFORM_WIN32
					format.Face(Font::SYMBOL);
#endif
					break;
				case '.': {
					int n = GetNumber();
					if(n >= Font::GetFaceCount())
						Error("Invalid face number");
					format.Face(n); break;
				}
				case '!': {
						String fn = GetText('!');
						int i = Font::FindFaceNameIndex(fn);
						if(i < 0)
							i = Font::ARIAL;
						format.Face(i);
					}
					break;
				case '{': {
						String cs = GetText('}');
						if(cs.GetLength() == 1) {
							int c = *cs;
							if(c == '_')
								format.charset = CHARSET_UTF8;
							if(c >= '0' && c <= '8')
								format.charset = c - '0' + CHARSET_WIN1250;
							if(c >= 'A' && c <= 'Z')
								format.charset = c - '0' + CHARSET_ISO8859_1;
						}
						else {
							for(int i = 0; i < CharsetCount(); i++)
								if(stricmp(CharsetName(i), cs) == 0) {
									format.charset = i;
									break;
								}
						}
						break;
					}
				case '%': {
						String h;
						if(*term == '-') {
							format.language = 0;
							term++;
						}
						else
						if(*term == '%') {
							format.language = LNG_ENGLISH;
							term++;
						}
						else {
							while(*term && h.GetLength() < 5)
								h.Cat(*term++);
							format.language = LNGFromText(h);
						}
						break;
					}
				case 'g':
					format.Face(Font::STDFONT);
					format.Height(GetRichTextScreenStdFontHeight());
					break;
				default:
					if(c >= '0' && c <= '9') {
						format.Height(QTFFontHeight[c - '0']);
						break;
					}
					switch(c) {
					case ':': format.label = GetText(':'); break;
					case '<': format.align = ALIGN_LEFT; break;
					case '>': format.align = ALIGN_RIGHT; break;
					case '=': format.align = ALIGN_CENTER; break;
					case '#': format.align = ALIGN_JUSTIFY; break;
					case 'l': format.lm = GetNumber(); break;
					case 'r': format.rm = GetNumber(); break;
					case 'i': format.indent = GetNumber(); break;
					case 'b': format.before = GetNumber(); break;
					case 'a': format.after = GetNumber(); break;
					case 'P': format.newpage = !format.newpage; break;
					case 'k': format.keep = !format.keep; break;
					case 'K': format.keepnext = !format.keepnext; break;
					case 'H': format.ruler = GetNumber(); break;
					case 'h': format.rulerink = GetColor(); break;
					case 'L': format.rulerstyle = GetNumber(); break;
					case 'Q': format.orphan = !format.orphan; break;
					case 'n': format.before_number = GetText(';'); break;
					case 'm': format.after_number = GetText(';'); break;
					case 'N': {
						memset(format.number, 0, sizeof(format.number));
						format.reset_number = false;
						int i = 0;
						while(i < 8) {
							int c;
							if(Key('-'))
								c = RichPara::NUMBER_NONE;
							else
							if(Key('1'))
								c = RichPara::NUMBER_1;
							else
							if(Key('0'))
								c = RichPara::NUMBER_0;
							else
							if(Key('a'))
								c = RichPara::NUMBER_a;
							else
							if(Key('A'))
								c = RichPara::NUMBER_A;
							else
							if(Key('i'))
								c = RichPara::NUMBER_i;
							else
							if(Key('I'))
								c = RichPara::NUMBER_I;
							else
								break;
							format.number[i++] = c;
						}
						if(Key('!'))
							format.reset_number = true;
						break;
					}
					case 'o': format.bullet = RichPara::BULLET_ROUND;
					          format.indent = 150; break;
					case 'O':
						if(Key('_'))
							format.bullet = RichPara::BULLET_NONE;
						else {
							int c = *term++;
							if(!c)
								Error("Unexpected end of text");
							format.bullet =
							                c == '1' ? RichPara::BULLET_ROUNDWHITE :
							                c == '2' ? RichPara::BULLET_BOX :
							                c == '3' ? RichPara::BULLET_BOXWHITE :
							                c == '9' ? RichPara::BULLET_TEXT :
							                           RichPara::BULLET_ROUND;
						}
						break;
					case 'p':
						switch(*term++) {
						case 0:   Error("Unexpected end of text");
						case 'h': format.linespacing = RichPara::LSP15; break;
						case 'd': format.linespacing = RichPara::LSP20; break;
						default:  format.linespacing = RichPara::LSP10;
						}
						break;
					case 't':
						if(*term == 'P') {
							term++;
							format.newhdrftr = true;
							format.header_qtf = GetText2('^', '^');
							format.footer_qtf = GetText2('^', '^');
						}
						else
						if(IsDigit(*term))
							format.tabsize = ReadNumber();
						break;
					case '~': {
							if(Key('~'))
								format.tab.Clear();
							else {
								RichPara::Tab tab;
								Key('<');
								if(Key('>'))
									tab.align = ALIGN_RIGHT;
								if(Key('='))
									tab.align = ALIGN_CENTER;
								if(Key('.'))
									tab.fillchar = 1;
								if(Key('-'))
									tab.fillchar = 2;
								if(Key('_'))
									tab.fillchar = 3;
								int rightpos = Key('>') ? RichPara::TAB_RIGHTPOS : 0;
								tab.pos = rightpos | ReadNumber();
								format.tab.Add(tab);
							}
						}
						break;
					default:
						continue;
					}
				}
			}
			SetFormat();
		}
		else
		if(Key(']')) {
			Flush();
			if(fstack.GetCount()) {
				format = fstack.Top();
				fstack.Drop();
			}
			else
				Error("Unmatched ']'");
		}
		else
		if(Key2('{')) {
			if(oldtab)
				Error("{{ in ++ table");
			if(text.GetLength() || paragraph.GetCount())
				EndPart();
			table.Add();
			int r = IsDigit(*term) ? ReadNumber() : 1;
			Table().AddColumn(r);
			while(Key(':'))
				Table().AddColumn(ReadNumber());
			if(breakpage) {
				RichTable& tab = Table();
				RichTable::Format tabformat = tab.GetFormat();
				tabformat.newpage = true;
				tab.SetFormat(tabformat);
				breakpage = false;
			}
			TableFormat();
			SetFormat();
		}
		else
		if(Key2('}')) {
			if(oldtab)
				Error("}} in ++ table");
			FinishTable();
		}
		else
		if(Key2('+'))
			if(oldtab)
				FinishOldTable();
			else {
				Flush();
				if(text.GetLength() || paragraph.GetCount())
					EndPart();
				Tab& b = table.Add();
				b.rown.Add(0);
				b.hspan = 1;
				b.Old();
				oldtab = true;
			}
		else
		if(Key2('|'))
			FinishCell();
		else
		if(Key2('-')) {
			FinishCell();
			table.Top().rown.Add(0);
		}
		else
		if(Key2(':')) {
			if(!oldtab)
				FinishCell();
			TableFormat(oldtab);
		}
		else
		if(Key2('^')) {
			EndPart();
			breakpage = true;
		}
		else
		if(Key2('@')) {
			ReadObject();
		}
		else
		if(Key2('@', '$')) {
			String xu;
			while(isxdigit(*term))
				xu.Cat(*term++);
			int c = stou(~xu, NULL, 16);
			if(c >= 32)
				Cat(c);
			if(*term == ';')
				term++;
			SetFormat();
		}
		else
		if(Key2('^', 'H'))
			target.SetHeaderQtf(GetText2('^', '^'));
		else
		if(Key2('^', 'F'))
			target.SetFooterQtf(GetText2('^', '^'));
		else
		if(Key2('{', ':')) {
			Flush();
			String field = GetText(':');
			String param = GetText(':');
			Id fid(field);
			if(RichPara::fieldtype().Find(fid) >= 0)
				paragraph.Cat(fid, param, format);
			Key('}');
		}
		else
		if(Key('&')) {
			SetFormat();
			EndPart();
		}
		else
		if(Key2('$')) {
			Flush();
			int i = GetNumber();
			Uuid id;
			RichStyle style;
			style.format = format;
			if(Key(','))
				stylenext.At(i, 0) = GetNumber();
			else
				stylenext.At(i, 0) = i;
			if(Key('#')) {
				String xu;
				while(isxdigit(*term))
					xu.Cat(*term++);
				if(xu.GetLength() != 32)
					Error("Invalid UUID !");
				id = ScanUuid(xu);
			}
			else
				if(i)
					id = Uuid::Create();
				else
					id = RichStyle::GetDefaultId();
			if(Key(':'))
				style.name = GetText(']');
			if(fstack.GetCount()) {
				format = fstack.Top();
				fstack.Drop();
			}
			target.SetStyle(id, style);
			styleid.At(i, RichStyle::GetDefaultId()) = id;
			if(id == RichStyle::GetDefaultId()) {
				bool p = format.newpage;
				int lng = format.language;
				(RichPara::Format&) format = style.format;
				format.styleid = id;
				format.language = lng;
				format.newpage = p;
			}
		}
		else
		if(*term == '_') {
			SetFormat();
			text.Cat(160);
			term++;
		}
		else
		if(Key2('-', '|')) {
			SetFormat();
			text.Cat(9);
		}
		else
		if(*term == '\1') {
			if(istable)
				EndPart();
			SetFormat();
			const char *b = ++term;
			for(; *term && *term != '\1'; term++) {
				if((byte)*term == '\n') {
					text.Cat(ToUnicode(b, (int)(term - b), format.charset));
					EndPart();
					b = term + 1;
				}
				if((byte)*term == '\t') {
					text.Cat(ToUnicode(b, (int)(term - b), format.charset));
					text.Cat(9);
					b = term + 1;
				}
			}
			text.Cat(ToUnicode(b, (int)(term - b), format.charset));
			if(*term == '\1')
				term++;
		}
		else {
			if(!Key('`')) Key('\\');
			if((byte)*term >= ' ') {
				SetFormat();
				do {
					if(istable)
						EndPart();
					if(format.charset == CHARSET_UTF8) {
						word code = (byte)*term++;
						if(code <= 0x7F)
							Cat(code);
						else
						if(code <= 0xDF) {
							if(*term == '\0') break;
							int c0 = (byte)*term++;
							if(c0 < 0x80)
								Error("Invalid UTF-8 sequence");
							Cat(((code - 0xC0) << 6) + c0 - 0x80);
						}
						else
						if(code <= 0xEF) {
							int c0 = (byte)*term++;
							int c1 = (byte)*term++;
							if(c0 < 0x80 || c1 < 0x80)
								Error("Invalid UTF-8 sequence");
							Cat(((code - 0xE0) << 12) + ((c0 - 0x80) << 6) + c1 - 0x80);
						}
						else
							Error("Invalid UTF-8 sequence");
					}
					else
						Cat(ToUnicode((byte)*term++, format.charset));
				}
				while((byte)*term >= 128 || s_nodeqtf[(byte)*term]);
			}
			else
			if(*term)
				term++;
		}
	}
//	if(paragraph.GetCount() == 0) // TRC 11/02/15: kills formatting of last paragraph in text
//		SetFormat();
	if(oldtab)
		FinishOldTable();
	else
		while(table.GetCount())
			FinishTable();
	EndPart();
	FlushStyles();
}
Esempio n. 5
0
void RichQtfParser::ReadObject()
{
	Flush();
	RichObject obj;
	if(*term == '#') {
		term++;
	#ifdef CPU_64
		obj = *(RichObject *)stou64(term, &term);
	#else
		obj = *(RichObject *)stou(term, &term);
	#endif
		term++;
	}
	else {
		String type;
		while(IsAlNum(*term) || *term == '_')
			type.Cat(*term++);
		Size sz;
		Key(':');
		sz.cx = ReadNumber();
		bool keepratio = false;
		if(Key('&'))
			keepratio = true;
		else
			Key('*');
		sz.cy = ReadNumber();
		int yd = 0;
		if(Key('/'))
			yd = GetNumber();
		while(*term && (byte)*term < 32)
			term++;
		String odata;
		if(Key('`'))
			while(*term) {
				if(*term == '`') {
					term++;
					if(*term == '`')
						odata.Cat('`');
					else
						break;
				}
				else
				if((byte)*term >= 32)
					odata.Cat(*term);
				term++;
			}
		else
		if(Key('(')) {
			const char *b = term;
			while(*term && *term != ')')
				term++;
			odata = Base64Decode(b, term);
			if(*term == ')')
				term++;
		}
		else {
			StringBuffer data;
			for(;;) {
				while(*term < 32 && *term > 0) term++;
				if((byte)*term >= ' ' && (byte)*term <= 127 || *term == '\0') break;
				byte seven = *term++;
				for(int i = 0; i < 7; i++) {
					while((byte)*term < 32 && (byte)*term > 0) term++;
					if((byte)*term >= ' ' && (byte)*term <= 127 || *term == '\0') break;
					data.Cat((*term++ & 0x7f) | ((seven << 7) & 0x80));
					seven >>= 1;
				}
			}
			odata = data;
		}
		obj.Read(type, odata, sz, context);
		obj.KeepRatio(keepratio);
		obj.SetYDelta(yd);
	}
	paragraph.Cat(obj, format);
}
Esempio n. 6
0
string CanIdTranslator::translateValidDataToHex(map<string, CanVariable> &data)
{
	string bin = "0000000000000000000000000000000000000000000000000000000000000000";
	int highestBit = 0;

	for (map<string, CanVariable>::iterator iter = data.begin(); iter != data.end(); iter++)
	{
		if (iter->second.getType() == "uint")
		{
			if (iter->second.getStartBit() + iter->second.getBitLength() > highestBit)
				highestBit = iter->second.getStartBit() + iter->second.getBitLength();

			unsigned int a = stou(iter->second.getValue());

			bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(a, iter->second.getBitLength()));
		}
		else if (iter->second.getType() == "float")
		{
			if (iter->second.getStartBit() + iter->second.getBitLength() > highestBit)
				highestBit = iter->second.getStartBit() + iter->second.getBitLength();

			bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), float2bin(stof(iter->second.getValue()), iter->second.getBitLength()));
		}
		else if (iter->second.getType() == "enum")
		{
			if (iter->second.getStartBit() + iter->second.getBitLength() > highestBit)
				highestBit = iter->second.getStartBit() + iter->second.getBitLength();

			string value = iter->second.getEnumIdValue();

			if (value == "")
			{
				throw new CanMessageException("Got enum that could not be converterd to a value. value = \"" + iter->second.getValue() + "\" enumString is \"" + iter->second.getEnumsString() + "\"\n");
			}
			else
			{
				bin.replace(iter->second.getStartBit(), iter->second.getBitLength(), uint2bin(stou(value), iter->second.getBitLength()));
			}
		}
		else if (iter->second.getType() == "ascii")
		{
			for (int n = 0; n < iter->second.getValue().length(); n++)
			{
				if (iter->second.getStartBit()+n*8 + 8 > highestBit)
					highestBit = iter->second.getStartBit()+n*8 + 8;

				//bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin((unsigned int)iter->second.getValue()[n], 8));
				unsigned int temp = iter->second.getValue()[n];
				if (temp > 0xff)
				{
					temp &= 0xff;
				}
				bin.replace(iter->second.getStartBit()+n*8, 8, uint2bin(temp, 8));
			}
		}
		else if (iter->second.getType() == "hexstring")
		{
			for (int n = 0; n < iter->second.getValue().length(); n++)
			{
				if (iter->second.getStartBit()+n*4 + 4 > highestBit)
					highestBit = iter->second.getStartBit()+n*4 + 4;

				string character;
				character += iter->second.getValue()[n];

				bin.replace(iter->second.getStartBit()+n*4, 4, hex2bin(character));
			}
		}
	}

	try
	{
		while (highestBit%8 != 0)
		{
		    highestBit++;
		}
		bin = bin.substr(0, highestBit);
	}
	catch (std::out_of_range& e)
	{
		cout << "DEBUG: translateValidDataToHex exception: " << e.what() << "\n";
		cout << "DEBUG: A bin=" << bin << " :: highestBit=" << highestBit << endl;
	}

	return bin2hex(bin);
}
Esempio n. 7
0
INT submit_elog(char *host, int port, int ssl, char *subdir, char *experiment,
                char *uname, char *upwd,
                int reply,
                int quote_on_reply,
                int edit,
                int download,
                int suppress,
                int encoding,
                char attrib_name[MAX_N_ATTR][NAME_LENGTH],
                char attrib[MAX_N_ATTR][NAME_LENGTH],
                int n_attr,
                char *text, char afilename[MAX_ATTACHMENTS][256],
                char *buffer[MAX_ATTACHMENTS], INT buffer_size[MAX_ATTACHMENTS])
/********************************************************************\

  Routine: submit_elog

  Purpose: Submit an ELog entry

  Input:
    char   *host            Host name where ELog server runs
    in     port             ELog server port number
    int    ssl              SSL flag
    char   *subdir          Subdirectoy to elog server
    char   *uname           User name
    char   *upwd            User password
    int    reply            Reply to existing message
    int    edit             Edit existing message
    int    download         Download existing message
    int    suppress         Suppress Email notification
    int    encoding         0:ELCode,1:plain,2:HTML
    char   *attrib_name     Attribute names
    char   *attrib          Attribute values
    char   *text            Message text

    char   afilename[]      File names of attachments
    char   *buffer[]        Attachment contents
    INT    buffer_size[]    Size of buffer in bytes

  Function value:
    EL_SUCCESS              Successful completion

\********************************************************************/
{
   int status, sock, i, n, header_length, content_length, index;
   char host_name[256], boundary[80], str[80], encrypted_passwd[256], *p, *old_encoding;
   char old_attrib_name[MAX_N_ATTR+1][NAME_LENGTH], old_attrib[MAX_N_ATTR+1][NAME_LENGTH];
   struct hostent *phe;
#ifdef HAVE_SSL
   SSL *ssl_con = NULL;
#endif

   /* get local host name */
   gethostname(host_name, sizeof(host_name));

   phe = gethostbyname(host_name);
   if (phe == NULL) {
      perror("Cannot retrieve host name");
      return -1;
   }
   phe = gethostbyaddr(phe->h_addr, sizeof(int), AF_INET);
   if (phe == NULL) {
      perror("Cannot retrieve host name");
      return -1;
   }

   /* if domain name is not in host name, hope to get it from phe */
   if (strchr(host_name, '.') == NULL)
      strcpy(host_name, phe->h_name);

   if (edit || download) {
      if (edit)
         status = retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, edit,
                                old_attrib_name, old_attrib, old_text);
      else
         status = retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, download,
                                old_attrib_name, old_attrib, old_text);

      if (status != 1)
         return status;

      /* update attributes */
      for (index = 0; index < n_attr; index++) {
         for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++)
            if (equal_ustring(attrib_name[index], old_attrib_name[i]))
               break;

         if (old_attrib_name[i][0])
            strlcpy(old_attrib[i], attrib[index], NAME_LENGTH);
      }

      /* copy attributes */
      for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++) {
         strlcpy(attrib_name[i], old_attrib_name[i], NAME_LENGTH);
         strlcpy(attrib[i], old_attrib[i], NAME_LENGTH);
      }

      n_attr = i;

      if (text[0] == 0)
         strlcpy(text, old_text, TEXT_SIZE);
   }
   
   if (download) {
      if (strstr(response, "$@MID@$:"))
         printf("%s", strstr(response, "$@MID@$:"));
      else
         printf("%s", response);
      return 1;
   }

   if (reply) {
      status =
          retrieve_elog(host, port, subdir, ssl, experiment, uname, upwd, reply,
                        old_attrib_name, old_attrib, old_text);

      if (status != 1)
         return status;

      /* update attributes */
      for (index = 0; index < n_attr; index++) {
         for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++)
            if (equal_ustring(attrib_name[index], old_attrib_name[i]))
               break;

         if (old_attrib_name[i][0])
            strlcpy(old_attrib[i], attrib[index], NAME_LENGTH);
      }

      /* copy attributes */
      for (i = 0; i < MAX_N_ATTR && old_attrib_name[i][0]; i++) {
         if (equal_ustring(old_attrib_name[i], "Reply to") || equal_ustring(old_attrib_name[i], "Date")) {
            attrib_name[i][0] = 0;
            attrib[i][0] = 0;
         } else {
            strlcpy(attrib_name[i], old_attrib_name[i], NAME_LENGTH);
            strlcpy(attrib[i], old_attrib[i], NAME_LENGTH);
         }
      }

      n_attr = i;

      /* check encoding */
      old_encoding = "plain";

      for (i = 0; i < n_attr; i++)
         if (equal_ustring(attrib_name[i], "encoding"))
            break;

      if (i < n_attr)
         old_encoding = attrib[i];

      if (quote_on_reply) {
         strlcpy(new_text, text, sizeof(new_text));

         /* precede old text with "> " */
         text[0] = 0;
         p = old_text;

         do {
            if (strchr(p, '\n')) {
               *strchr(p, '\n') = 0;

               if (old_encoding[0] == 'H') {
                  strlcat(text, "> ", TEXT_SIZE);
                  strlcat(text, p, TEXT_SIZE);
                  strlcat(text, "<br>\n", TEXT_SIZE);
               } else {
                  strlcat(text, "> ", TEXT_SIZE);
                  strlcat(text, p, TEXT_SIZE);
                  strlcat(text, "\n", TEXT_SIZE);
               }

               p += strlen(p) + 1;
               if (*p == '\n')
                  p++;
            } else {
               if (old_encoding[0] == 'H') {
                  strlcat(text, "> ", TEXT_SIZE);
                  strlcat(text, p, TEXT_SIZE);
                  strlcat(text, "<p>\n", TEXT_SIZE);
               } else {
                  strlcat(text, "> ", TEXT_SIZE);
                  strlcat(text, p, TEXT_SIZE);
                  strlcat(text, "\n\n", TEXT_SIZE);
               }

               break;
            }

         } while (1);

         strlcat(text, new_text, TEXT_SIZE);
      }
   }

   sock = elog_connect(host, port);
   if (sock < 0)
      return sock;

#ifdef HAVE_SSL
   if (ssl)
      if (ssl_connect(sock, &ssl_con) < 0) {
         printf("elogd server does not run SSL protocol\n");
         return -1;
      }
#endif

   content_length = 100000;
   for (i = 0; i < MAX_ATTACHMENTS; i++)
      if (afilename[i][0])
         content_length += buffer_size[i];
   content = (char *)malloc(content_length);
   if (content == NULL) {
      printf("Not enough memory\n");
      return -1;
   }

   /* compose content */
   srand((unsigned) time(NULL));
   sprintf(boundary, "---------------------------%04X%04X%04X", rand(), rand(), rand());
   strcpy(content, boundary);
   strcat(content, "\r\nContent-Disposition: form-data; name=\"cmd\"\r\n\r\nSubmit\r\n");

   if (uname[0])
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"unm\"\r\n\r\n%s\r\n", boundary, uname);

   if (upwd[0]) {
      do_crypt(upwd, encrypted_passwd, sizeof(encrypted_passwd));
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"upwd\"\r\n\r\n%s\r\n", boundary,
              encrypted_passwd);
   }

   if (experiment[0])
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"exp\"\r\n\r\n%s\r\n", boundary, experiment);

   if (reply)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"reply_to\"\r\n\r\n%d\r\n", boundary, reply);

   if (edit) {
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"edit_id\"\r\n\r\n%d\r\n", boundary, edit);
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"skiplock\"\r\n\r\n1\r\n", boundary);
   }

   if (suppress)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"suppress\"\r\n\r\n1\r\n", boundary);

   if (encoding == 0)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nELCode\r\n", boundary);
   else if (encoding == 1)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nplain\r\n", boundary);
   else if (encoding == 2)
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"encoding\"\r\n\r\nHTML\r\n", boundary);

   for (i = 0; i < n_attr; i++) {
      strcpy(str, attrib_name[i]);
      if (str[0]) {
         stou(str);
         sprintf(content + strlen(content),
                 "%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n%s\r\n", boundary, str, attrib[i]);
      }
   }

   if (text[0])
      sprintf(content + strlen(content),
              "%s\r\nContent-Disposition: form-data; name=\"Text\"\r\n\r\n%s\r\n%s\r\n",
              boundary, text, boundary);

   content_length = strlen(content);
   p = content + content_length;

   for (i = 0; i < MAX_ATTACHMENTS; i++)
      if (afilename[i][0]) {
         sprintf(p,
                 "Content-Disposition: form-data; name=\"attfile%d\"; filename=\"%s\"\r\n\r\n",
                 i + 1, afilename[i]);

         content_length += strlen(p);
         p += strlen(p);
         memcpy(p, buffer[i], buffer_size[i]);
         p += buffer_size[i];
         strcpy(p, boundary);
         strcat(p, "\r\n");

         content_length += buffer_size[i] + strlen(p);
         p += strlen(p);
      }

   /* compose request */
   strcpy(request, "POST /");
   if (subdir[0])
      sprintf(request + strlen(request), "%s/", subdir);
   if (experiment[0]) {
      strcpy(str, experiment);
      url_encode(str, sizeof(str));
      sprintf(request + strlen(request), "%s/", str);
   }
   strcat(request, " HTTP/1.0\r\n");

   sprintf(request + strlen(request), "Content-Type: multipart/form-data; boundary=%s\r\n", boundary);
   if (port != 80)
      sprintf(str, "%s:%d", host, port);
   else
      sprintf(str, "%s", host);
   sprintf(request + strlen(request), "Host: %s\r\n", str);
   sprintf(request + strlen(request), "User-Agent: ELOG\r\n");
   sprintf(request + strlen(request), "Content-Length: %d\r\n", content_length);

   strcat(request, "\r\n");

   header_length = strlen(request);

   /*
      {
      FILE *f;
      f = fopen("elog.log", "w");
      fwrite(request, header_length+content_length, 1, f);
      fclose(f);
      }
    */

   /* send request */
#ifdef HAVE_SSL
   if (ssl)
      SSL_write(ssl_con, request, header_length);
   else
#endif
      send(sock, request, header_length, 0);
   if (verbose) {
      printf("Request sent to host:\n");
      puts(request);
   }

   /* send content */
#ifdef HAVE_SSL
   if (ssl)
      SSL_write(ssl_con, content, content_length);
   else
#endif
      send(sock, content, content_length, 0);
   if (verbose) {
      printf("Content sent to host:\n");
      puts(content);
   }

   /* receive response */
   memset(response, 0, sizeof(response));
#ifdef HAVE_SSL
   if (ssl)
      i = SSL_read(ssl_con, response, sizeof(response) - 1);
   else
#endif
      i = recv(sock, response, sizeof(response) - 1, 0);
   if (i < 0) {
      perror("Cannot receive response");
      return -1;
   }

   /* discard remainder of response */
   n = i;
   while (i > 0) {
#ifdef HAVE_SSL
      if (ssl)
         i = SSL_read(ssl_con, response + n, sizeof(response) - 1 - n);
      else
#endif
         i = recv(sock, response + n, sizeof(response) - 1 - n, 0);
      if (i > 0)
         n += i;
   }
   response[n] = 0;

#ifdef HAVE_SSL
   if (ssl) {
      SSL_shutdown(ssl_con);
      SSL_free(ssl_con);
   }
#endif

   closesocket(sock);

   if (verbose) {
      printf("Response received:\n");
      puts(response);
   }

   /* check response status */
   if (strstr(response, "302 Found")) {
      if (strstr(response, "Location:")) {
         if (strstr(response, "has moved"))
            printf("Error: elogd server has moved to another location\n");
         else if (strstr(response, "fail"))
            printf("Error: Invalid user name or password\n");
         else {
            strncpy(str, strstr(response, "Location:") + 10, sizeof(str));
            if (strchr(str, '?'))
               *strchr(str, '?') = 0;
            if (strchr(str, '\n'))
               *strchr(str, '\n') = 0;
            if (strchr(str, '\r'))
               *strchr(str, '\r') = 0;

            if (strrchr(str, '/'))
               printf("Message successfully transmitted, ID=%s\n", strrchr(str, '/') + 1);
            else
               printf("Message successfully transmitted, ID=%s\n", str);
         }
      } else
         printf("Message successfully transmitted\n");
   } else if (strstr(response, "Logbook Selection"))
      printf("Error: No logbook specified\n");
   else if (strstr(response, "enter password"))
      printf("Error: Missing or invalid password\n");
   else if (strstr(response, "form name=form1"))
      printf("Error: Missing or invalid user name/password\n");
   else if (strstr(response, "Error: Attribute")) {
      if (strstr(response, "not existing")) {
         strncpy(str, strstr(response, "Error: Attribute") + 27, sizeof(str));
         if (strchr(str, '<'))
            *strchr(str, '<') = 0;
         printf("Error: Non existing attribute option \"%s\"\n", str);
      } else {
         strncpy(str, strstr(response, "Error: Attribute") + 20, sizeof(str));
         if (strchr(str, '<'))
            *strchr(str, '<') = 0;
         printf("Error: Missing required attribute \"%s\"\n", str);
      }
   } else
      printf("Error transmitting message\n");

   return 1;
}
Esempio n. 8
0
/**
 * Reads the segments[] array (see applyPattern()) and parses the
 * segments[1..3] into a Format* object.  Stores the format object in
 * the subformats[] array.  Updates the argTypes[] array type
 * information for the corresponding argument.
 *
 * @param formatNumber index into subformats[] for this format
 * @param segments array of strings with the parsed pattern segments
 * @param parseError parse error data (output param)
 * @param ec error code
 */
void
MessageFormat::makeFormat(int32_t formatNumber, 
                          UnicodeString* segments,
                          UParseError& parseError,
                          UErrorCode& ec) {
    if (U_FAILURE(ec)) {
        return;
    }

    // Parse the argument number
    int32_t argumentNumber = stou(segments[1]); // always unlocalized!
    if (argumentNumber < 0) {
        ec = U_INVALID_FORMAT_ERROR;
        return;
    }

    // Parse the format, recording the argument type and creating a
    // new Format object (except for string arguments).
    Formattable::Type argType;
    Format *fmt = NULL;
    int32_t typeID, styleID;
    DateFormat::EStyle style;

    switch (typeID = findKeyword(segments[2], TYPE_IDS)) {

    case 0: // string
        argType = Formattable::kString;
        break;

    case 1: // number
        argType = Formattable::kDouble;

        switch (findKeyword(segments[3], NUMBER_STYLE_IDS)) {
        case 0: // default
            fmt = NumberFormat::createInstance(fLocale, ec);
            break;
        case 1: // currency
            fmt = NumberFormat::createCurrencyInstance(fLocale, ec);
            break;
        case 2: // percent
            fmt = NumberFormat::createPercentInstance(fLocale, ec);
            break;
        case 3: // integer
            argType = Formattable::kLong;
            fmt = createIntegerFormat(fLocale, ec);
            break;
        default: // pattern
            fmt = NumberFormat::createInstance(fLocale, ec);
            if (fmt &&
                fmt->getDynamicClassID() == DecimalFormat::getStaticClassID()) {
                ((DecimalFormat*)fmt)->applyPattern(segments[3],parseError,ec);
            }
            break;
        }
        break;

    case 2: // date
    case 3: // time
        argType = Formattable::kDate;
        styleID = findKeyword(segments[3], DATE_STYLE_IDS);
        style = (styleID >= 0) ? DATE_STYLES[styleID] : DateFormat::kDefault;

        if (typeID == 2) {
            fmt = DateFormat::createDateInstance(style, fLocale);
        } else {
            fmt = DateFormat::createTimeInstance(style, fLocale);
        }

        if (styleID < 0 &&
            fmt != NULL &&
            fmt->getDynamicClassID() == SimpleDateFormat::getStaticClassID()) {
            ((SimpleDateFormat*)fmt)->applyPattern(segments[3]);
        }
        break;

    case 4: // choice
        argType = Formattable::kDouble;

        fmt = new ChoiceFormat(segments[3], parseError, ec);
        break;

    case 5: // spellout
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_SPELLOUT, fLocale, segments[3], ec);
        break;
    case 6: // ordinal
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_ORDINAL, fLocale, segments[3], ec);
        break;
    case 7: // duration
        argType = Formattable::kDouble;
        fmt = makeRBNF(URBNF_DURATION, fLocale, segments[3], ec);
        break;
    default:
        argType = Formattable::kString;
        ec = U_ILLEGAL_ARGUMENT_ERROR;
        break;
    }

    if (fmt==NULL && argType!=Formattable::kString && U_SUCCESS(ec)) {
        ec = U_MEMORY_ALLOCATION_ERROR;
    }
    
    if (!allocateSubformats(formatNumber+1) ||
        !allocateArgTypes(argumentNumber+1)) {
        ec = U_MEMORY_ALLOCATION_ERROR;
    }

    if (U_FAILURE(ec)) {
        delete fmt;
        return;
    }

    // Parse succeeded; record results in our arrays
    subformats[formatNumber].format = fmt;
    subformats[formatNumber].offset = segments[0].length();
    subformats[formatNumber].arg = argumentNumber;
    subformatCount = formatNumber+1;

    // Careful here: argumentNumber may in general arrive out of
    // sequence, e.g., "There was {2} on {0,date} (see {1,number})."
    argTypes[argumentNumber] = argType;
    if (argumentNumber+1 > argTypeCount) {
        argTypeCount = argumentNumber+1;
    }
}
Esempio n. 9
0
void msgs_cfg()
{
	static int dflt,msgs_dflt,bar;
	char	str[256],str2[256],done=0;
	char*	p;
	char*	tp;
    char	tmp[128];
	char	tmp_code[32];
	int		j,k,q,s;
	int		i,file,ptridx,n;
	unsigned total_subs;
	long	ported;
	sub_t	tmpsub;
	static grp_t savgrp;
	FILE*	stream;

while(1) {
	for(i=0;i<cfg.total_grps && i<MAX_OPTS;i++)
		sprintf(opt[i],"%-25s",cfg.grp[i]->lname);
	opt[i][0]=0;
	j=WIN_ORG|WIN_ACT|WIN_CHE;
	if(cfg.total_grps)
		j|=WIN_DEL|WIN_DELACT|WIN_GET;
	if(cfg.total_grps<MAX_OPTS)
		j|=WIN_INS|WIN_INSACT|WIN_XTR;
	if(savgrp.sname[0])
		j|=WIN_PUT;
	uifc.helpbuf=
		"`Message Groups:`\n"
		"\n"
		"This is a listing of message groups for your BBS. Message groups are\n"
		"used to logically separate your message `sub-boards` into groups. Every\n"
		"sub-board belongs to a message group. You must have at least one message\n"
		"group and one sub-board configured.\n"
		"\n"
		"One popular use for message groups is to separate local sub-boards and\n"
		"networked sub-boards. One might have a `Local` message group that contains\n"
		"non-networked sub-boards of various topics and also have a `FidoNet`\n"
		"message group that contains sub-boards that are echoed across FidoNet.\n"
		"Some sysops separate sub-boards into more specific areas such as `Main`,\n"
		"`Technical`, or `Adult`. If you have many sub-boards that have a common\n"
		"subject denominator, you may want to have a separate message group for\n"
		"those sub-boards for a more organized message structure.\n"
	;
	i=uifc.list(j,0,0,45,&msgs_dflt,&bar,"Message Groups",opt);
	if(i==-1) {
		j=save_changes(WIN_MID);
		if(j==-1)
		   continue;
		if(!j) {
			write_msgs_cfg(&cfg,backup_level);
            refresh_cfg(&cfg);
        }
		return;
    }
	if((i&MSK_ON)==MSK_INS) {
		i&=MSK_OFF;
		uifc.helpbuf=
			"`Group Long Name:`\n"
			"\n"
			"This is a description of the message group which is displayed when a\n"
			"user of the system uses the `/*` command from the main menu.\n"
		;
		strcpy(str,"Main");
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Group Long Name",str,LEN_GLNAME
			,K_EDIT)<1)
			continue;
		uifc.helpbuf=
			"`Group Short Name:`\n"
			"\n"
			"This is a short description of the message group which is used for the\n"
			"main menu and reading message prompts.\n"
		;
		sprintf(str2,"%.*s",LEN_GSNAME,str);
		if(uifc.input(WIN_MID,0,0,"Group Short Name",str2,LEN_GSNAME,K_EDIT)<1)
			continue;
		if((cfg.grp=(grp_t **)realloc(cfg.grp,sizeof(grp_t *)*(cfg.total_grps+1)))==NULL) {
            errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_grps+1);
			cfg.total_grps=0;
			bail(1);
            continue; 
		}

		if(cfg.total_grps) {	/* was cfg.total_subs (?) */
            for(j=cfg.total_grps;j>i;j--)   /* insert above */
                cfg.grp[j]=cfg.grp[j-1];
            for(j=0;j<cfg.total_subs;j++)   /* move sub group numbers */
                if(cfg.sub[j]->grp>=i)
                    cfg.sub[j]->grp++; 
		}

		if((cfg.grp[i]=(grp_t *)malloc(sizeof(grp_t)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(grp_t));
			continue; 
		}
		memset((grp_t *)cfg.grp[i],0,sizeof(grp_t));
		strcpy(cfg.grp[i]->lname,str);
		strcpy(cfg.grp[i]->sname,str2);
		cfg.total_grps++;
		uifc.changes=1;
		continue; 
	}
	if((i&MSK_ON)==MSK_DEL) {
		i&=MSK_OFF;
		uifc.helpbuf=
			"`Delete All Data in Group:`\n"
			"\n"
			"If you wish to delete the messages in all the sub-boards in this group,\n"
			"select `Yes`.\n"
		;
		j=1;
		strcpy(opt[0],"Yes");
		strcpy(opt[1],"No");
		opt[2][0]=0;
		j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0,"Delete All Data in Group",opt);
		if(j==-1)
			continue;
		if(j==0)
			for(j=0;j<cfg.total_subs;j++)
				if(cfg.sub[j]->grp==i) {
					sprintf(str,"%s%s.s*"
						,cfg.grp[cfg.sub[j]->grp]->code_prefix
						,cfg.sub[j]->code_suffix);
					strlwr(str);
					if(!cfg.sub[j]->data_dir[0])
						sprintf(tmp,"%ssubs/",cfg.data_dir);
					else
						strcpy(tmp,cfg.sub[j]->data_dir);
					delfiles(tmp,str);
					clearptrs(j); 
				}
		free(cfg.grp[i]);
		for(j=0;j<cfg.total_subs;) {
			if(cfg.sub[j]->grp==i) {	/* delete subs of this group */
				free(cfg.sub[j]);
				cfg.total_subs--;
				k=j;
				while(k<cfg.total_subs) {	/* move all subs down */
					cfg.sub[k]=cfg.sub[k+1];
					for(q=0;q<cfg.total_qhubs;q++)
						for(s=0;s<cfg.qhub[q]->subs;s++)
							if(cfg.qhub[q]->sub[s]==k)
								cfg.qhub[q]->sub[s]--;
					k++; 
				} 
			}
			else j++; 
		}
		for(j=0;j<cfg.total_subs;j++)	/* move sub group numbers down */
			if(cfg.sub[j]->grp>i)
				cfg.sub[j]->grp--;
		cfg.total_grps--;
		while(i<cfg.total_grps) {
			cfg.grp[i]=cfg.grp[i+1];
			i++; 
		}
		uifc.changes=1;
		continue; 
	}
	if((i&MSK_ON)==MSK_GET) {
		i&=MSK_OFF;
		savgrp=*cfg.grp[i];
		continue; 
	}
	if((i&MSK_ON)==MSK_PUT) {
		i&=MSK_OFF;
		*cfg.grp[i]=savgrp;
		uifc.changes=1;
		continue; 
	}
	done=0;
	while(!done) {
		j=0;
		sprintf(opt[j++],"%-27.27s%s","Long Name",cfg.grp[i]->lname);
		sprintf(opt[j++],"%-27.27s%s","Short Name",cfg.grp[i]->sname);
		sprintf(opt[j++],"%-27.27s%s","Internal Code Prefix",cfg.grp[i]->code_prefix);
		sprintf(opt[j++],"%-27.27s%.40s","Access Requirements"
			,cfg.grp[i]->arstr);
		strcpy(opt[j++],"Clone Options");
		strcpy(opt[j++],"Export Areas...");
		strcpy(opt[j++],"Import Areas...");
		strcpy(opt[j++],"Message Sub-boards...");
		opt[j][0]=0;
		sprintf(str,"%s Group",cfg.grp[i]->sname);
		uifc.helpbuf=
			"`Message Group Configuration:`\n"
			"\n"
			"This menu allows you to configure the security requirements for access\n"
			"to this message group. You can also add, delete, and configure the\n"
			"sub-boards of this group by selecting the `Messages Sub-boards...` option.\n"
		;
		switch(uifc.list(WIN_ACT,6,4,60,&dflt,0,str,opt)) {
			case -1:
				done=1;
				break;
			case 0:
				uifc.helpbuf=
					"`Group Long Name:`\n"
					"\n"
					"This is a description of the message group which is displayed when a\n"
					"user of the system uses the `/*` command from the main menu.\n"
				;
				strcpy(str,cfg.grp[i]->lname);	/* save incase setting to null */
				if(!uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Listings"
					,cfg.grp[i]->lname,LEN_GLNAME,K_EDIT))
					strcpy(cfg.grp[i]->lname,str);
				break;
			case 1:
				uifc.helpbuf=
					"`Group Short Name:`\n"
					"\n"
					"This is a short description of the message group which is used for\n"
					"main menu and reading messages prompts.\n"
				;
				uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Prompts"
					,cfg.grp[i]->sname,LEN_GSNAME,K_EDIT);
				break;
			case 2:
				uifc.helpbuf=
					"`Internal Code Prefix:`\n"
					"\n"
					"This is an `optional` code prefix used to help generate unique internal\n"
					"codes for the sub-boards in this message group. If this option\n"
					"is used, sub-board internal codes will be constructed from this prefix\n"
					"and the specified code suffix for each sub-board.\n"
				;
				uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code Prefix"
					,cfg.grp[i]->code_prefix,LEN_CODE,K_EDIT|K_UPPER);
				break;
			case 3:
				sprintf(str,"%s Group",cfg.grp[i]->sname);
				getar(str,cfg.grp[i]->arstr);
				break;
			case 4: 	/* Clone Options */
				j=0;
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				uifc.helpbuf=
					"`Clone Sub-board Options:`\n"
					"\n"
					"If you want to clone the options of the first sub-board of this group\n"
					"into all sub-boards of this group, select `Yes`.\n"
					"\n"
					"The options cloned are posting requirements, reading requirements,\n"
					"operator requirments, moderated user requirments, toggle options,\n"
					"network options (including EchoMail origin line, EchoMail address,\n"
					"and QWK Network tagline), maximum number of messages, maximum number\n"
					"of CRCs, maximum age of messages, storage method, and data directory.\n"
				;
				j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
					,"Clone Options of First Sub-board into All of Group",opt);
				if(j==0) {
					k=-1;
					for(j=0;j<cfg.total_subs;j++)
						if(cfg.sub[j]->grp==i) {
							if(k==-1)
								k=j;
							else {
								uifc.changes=1;
								cfg.sub[j]->misc=(cfg.sub[k]->misc|SUB_HDRMOD);
								strcpy(cfg.sub[j]->post_arstr,cfg.sub[k]->post_arstr);
								strcpy(cfg.sub[j]->read_arstr,cfg.sub[k]->read_arstr);
								strcpy(cfg.sub[j]->op_arstr,cfg.sub[k]->op_arstr);
								strcpy(cfg.sub[j]->mod_arstr,cfg.sub[k]->mod_arstr);
								strcpy(cfg.sub[j]->origline,cfg.sub[k]->origline);
								strcpy(cfg.sub[j]->tagline,cfg.sub[k]->tagline);
								strcpy(cfg.sub[j]->data_dir,cfg.sub[k]->data_dir);
								strcpy(cfg.sub[j]->post_sem,cfg.sub[k]->post_sem);
								cfg.sub[j]->maxmsgs=cfg.sub[k]->maxmsgs;
								cfg.sub[j]->maxcrcs=cfg.sub[k]->maxcrcs;
								cfg.sub[j]->maxage=cfg.sub[k]->maxage;

								cfg.sub[j]->faddr=cfg.sub[k]->faddr; 
							} 
						} 
				}
				break;
			case 5:
				k=0;
				ported=0;
				q=uifc.changes;
				strcpy(opt[k++],"SUBS.TXT    (Synchronet)");
				strcpy(opt[k++],"AREAS.BBS   (MSG)");
				strcpy(opt[k++],"AREAS.BBS   (SBBSecho)");
				strcpy(opt[k++],"FIDONET.NA  (Fido)");
				opt[k][0]=0;
				uifc.helpbuf=
					"`Export Area File Format:`\n"
					"\n"
					"This menu allows you to choose the format of the area file you wish to\n"
					"export the current message group into.\n"
				;
				k=0;
				k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
					,"Export Area File Format",opt);
				if(k==-1)
					break;
				if(k==0)
					sprintf(str,"%sSUBS.TXT",cfg.ctrl_dir);
				else if(k==1)
					sprintf(str,"AREAS.BBS");
				else if(k==2)
					sprintf(str,"%sAREAS.BBS",cfg.data_dir);
				else if(k==3)
					sprintf(str,"FIDONET.NA");
				if(k && k<3)
					if(uifc.input(WIN_MID|WIN_SAV,0,0,"Uplinks"
						,str2,sizeof(str2)-1,0)<=0) {
						uifc.changes=q;
						break; 
					}
				if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
					,str,sizeof(str)-1,K_EDIT)<=0) {
					uifc.changes=q;
					break; 
				}
				if(fexist(str)) {
					strcpy(opt[0],"Overwrite");
					strcpy(opt[1],"Append");
					opt[2][0]=0;
					j=0;
					j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
						,"File Exists",opt);
					if(j==-1)
						break;
					if(j==0) j=O_WRONLY|O_TRUNC;
					else	 j=O_WRONLY|O_APPEND; 
				}
				else
					j=O_WRONLY|O_CREAT;
				if((stream=fnopen(&file,str,j))==NULL) {
					sprintf(str,"Open Failure: %d (%s)"
						,errno,strerror(errno));
					uifc.msg(str);
					uifc.changes=q;
					break; 
				}
				uifc.pop("Exporting Areas...");
				for(j=0;j<cfg.total_subs;j++) {
					if(cfg.sub[j]->grp!=i)
						continue;
					ported++;
					if(k==1) {		/* AREAS.BBS *.MSG */
						sprintf(str,"%s%s%s/"
							,cfg.echomail_dir
							,cfg.grp[cfg.sub[j]->grp]->code_prefix
							,cfg.sub[j]->code_suffix);
						fprintf(stream,"%-30s %-20s %s\r\n"
							,str,stou(cfg.sub[j]->sname),str2);
						continue; 
					}
					if(k==2) {		/* AREAS.BBS SBBSecho */
						fprintf(stream,"%s%-30s %-20s %s\r\n"
							,cfg.grp[cfg.sub[j]->grp]->code_prefix
							,cfg.sub[j]->code_suffix
							,stou(cfg.sub[j]->sname)
							,str2);
						continue; 
					}
					if(k==3) {		/* FIDONET.NA */
						fprintf(stream,"%-20s %s\r\n"
							,stou(cfg.sub[j]->sname),cfg.sub[j]->lname);
						continue; 
					}
					fprintf(stream,"%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
							"%s\r\n%s\r\n%s\r\n"
						,cfg.sub[j]->lname
						,cfg.sub[j]->sname
						,cfg.sub[j]->qwkname
						,cfg.sub[j]->code_suffix
						,cfg.sub[j]->data_dir
						,cfg.sub[j]->arstr
						,cfg.sub[j]->read_arstr
						,cfg.sub[j]->post_arstr
						,cfg.sub[j]->op_arstr
						);
					fprintf(stream,"%"PRIX32"\r\n%s\r\n%s\r\n%s\r\n%s\r\n%s\r\n"
						,cfg.sub[j]->misc
						,cfg.sub[j]->tagline
						,cfg.sub[j]->origline
						,cfg.sub[j]->post_sem
						,cfg.sub[j]->newsgroup
						,smb_faddrtoa(&cfg.sub[j]->faddr,tmp)
						);
					fprintf(stream,"%"PRIu32"\r\n%"PRIu32"\r\n%u\r\n%u\r\n%s\r\n"
						,cfg.sub[j]->maxmsgs
						,cfg.sub[j]->maxcrcs
						,cfg.sub[j]->maxage
						,cfg.sub[j]->ptridx
						,cfg.sub[j]->mod_arstr
						);
					fprintf(stream,"***END-OF-SUB***\r\n\r\n"); 
				}
				fclose(stream);
				uifc.pop(0);
				sprintf(str,"%lu Message Areas Exported Successfully",ported);
				uifc.msg(str);
				uifc.changes=q;
				break;
			case 6:
				ported=0;
				k=0;
				strcpy(opt[k++],"SUBS.TXT    (Synchronet)");
				strcpy(opt[k++],"AREAS.BBS   (Generic)");
				strcpy(opt[k++],"AREAS.BBS   (SBBSecho)");
				strcpy(opt[k++],"FIDONET.NA  (Fido)");
				opt[k][0]=0;
				uifc.helpbuf=
					"`Import Area File Format:`\n"
					"\n"
					"This menu allows you to choose the format of the area file you wish to\n"
					"import into the current message group.\n"
				;
				k=0;
				k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
					,"Import Area File Format",opt);
				if(k==-1)
					break;
				if(k==0)
					sprintf(str,"%sSUBS.TXT",cfg.ctrl_dir);
				else if(k==1)
					sprintf(str,"AREAS.BBS");
				else if(k==2)
					sprintf(str,"%sAREAS.BBS",cfg.data_dir);
				else if(k==3)
					sprintf(str,"FIDONET.NA");
				if(uifc.input(WIN_MID|WIN_SAV,0,0,"Filename"
					,str,sizeof(str)-1,K_EDIT)<=0)
                    break;
				if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
					uifc.msg("Open Failure");
                    break; 
				}
				uifc.pop("Importing Areas...");
				total_subs = cfg.total_subs;	 /* Save original number of subs */
				ptridx = 0;
				while(!feof(stream)) {
					if(!fgets(str,sizeof(str),stream)) break;
					truncsp(str);
					if(!str[0])
						continue;
					if(k) {
						p=str;
						while(*p && *p<=' ') p++;
						if(!*p || *p==';')
							continue;
						memset(&tmpsub,0,sizeof(sub_t));
						tmpsub.misc|=
							(SUB_FIDO|SUB_NAME|SUB_TOUSER|SUB_QUOTE|SUB_HYPER);
						if(k==1) {		/* AREAS.BBS Generic/*.MSG */
							p=str;
							SKIP_WHITESPACE(p);			/* Find path	*/
							FIND_WHITESPACE(p);			/* Skip path	*/
							SKIP_WHITESPACE(p);			/* Find tag		*/
							truncstr(p," \t");			/* Truncate tag */
							SAFECOPY(tmp_code,p);		/* Copy tag to internal code */
							SAFECOPY(tmpsub.lname,utos(p));
							SAFECOPY(tmpsub.sname,tmpsub.lname);
							SAFECOPY(tmpsub.qwkname,tmpsub.qwkname);
						}
						else if(k==2) { /* AREAS.BBS SBBSecho */
							p=str;
							SKIP_WHITESPACE(p);			/* Find internal code */
							tp=p;
							FIND_WHITESPACE(tp);
							*tp=0;						/* Truncate internal code */
							SAFECOPY(tmp_code,p);		/* Copy internal code suffix */
							p=tp+1;
							SKIP_WHITESPACE(p);			/* Find echo tag */
							truncstr(p," \t");			/* Truncate tag */
							SAFECOPY(tmpsub.lname,utos(p));
							SAFECOPY(tmpsub.sname,tmpsub.lname);
							SAFECOPY(tmpsub.qwkname,tmpsub.sname);
						}
						else if(k==3) { /* FIDONET.NA */
                            p=str;
							SKIP_WHITESPACE(p);			/* Find echo tag */
							tp=p;
							FIND_WHITESPACE(tp);		/* Find end of tag */
							*tp=0;						/* Truncate echo tag */
							SAFECOPY(tmp_code,p);		/* Copy tag to internal code suffix */
							SAFECOPY(tmpsub.sname,utos(p));	/* ... to short name, converting underscores to spaces */
							SAFECOPY(tmpsub.qwkname,tmpsub.sname);	/* ... to QWK name .... */
							p=tp+1;
							SKIP_WHITESPACE(p);			/* Find description */
							SAFECOPY(tmpsub.lname,p);	/* Copy description to long name */
						}
					}
					else {
						memset(&tmpsub,0,sizeof(sub_t));
						tmpsub.grp=i;
						sprintf(tmpsub.lname,"%.*s",LEN_SLNAME,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.sname,"%.*s",LEN_SSNAME,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.qwkname,"%.*s",10,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						SAFECOPY(tmp_code,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.data_dir,"%.*s",LEN_DIR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.read_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.post_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.op_arstr,"%.*s",LEN_ARSTR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.misc=ahtoul(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.tagline,"%.*s",80,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.origline,"%.*s",50,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.post_sem,"%.*s",LEN_DIR,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						SAFECOPY(tmpsub.newsgroup,str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.faddr=atofaddr(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.maxmsgs=atol(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.maxcrcs=atol(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.maxage=atoi(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						tmpsub.ptridx=atoi(str);
						if(!fgets(str,128,stream)) break;
						truncsp(str);
						sprintf(tmpsub.mod_arstr,"%.*s",LEN_ARSTR,str);

						while(!feof(stream)
							&& strcmp(str,"***END-OF-SUB***")) {
							if(!fgets(str,128,stream)) break;
							truncsp(str); 
						} 
					}

                    SAFECOPY(tmpsub.code_suffix, prep_code(tmp_code,cfg.grp[i]->code_prefix));
					truncsp(tmpsub.sname);
					truncsp(tmpsub.lname);
					truncsp(tmpsub.qwkname);

					if(tmpsub.code_suffix[0]==0
						|| tmpsub.sname[0]==0
						|| tmpsub.lname[0]==0
						|| tmpsub.qwkname[0]==0)
						continue;

					for(j=0;j<total_subs;j++) {
						if(cfg.sub[j]->grp!=i)
							continue;
						if(!stricmp(cfg.sub[j]->code_suffix,tmpsub.code_suffix))
							break; 
					}
					if(j==total_subs) {
						j=cfg.total_subs;
						if((cfg.sub=(sub_t **)realloc(cfg.sub
							,sizeof(sub_t *)*(cfg.total_subs+1)))==NULL) {
							errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_subs+1);
							cfg.total_subs=0;
							bail(1);
							break; 
						}

						if((cfg.sub[j]=(sub_t *)malloc(sizeof(sub_t)))
							==NULL) {
							errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(sub_t));
							break; 
						}
						memset(cfg.sub[j],0,sizeof(sub_t)); 
					}
					if(!k) {
						n=cfg.sub[j]->ptridx;	/* save original ptridx */
						memcpy(cfg.sub[j],&tmpsub,sizeof(sub_t));
						cfg.sub[j]->ptridx=n;	/* restore original ptridx */
					} else {
                        cfg.sub[j]->grp=i;
						if(cfg.total_faddrs)
							cfg.sub[j]->faddr=cfg.faddr[0];
						strcpy(cfg.sub[j]->code_suffix,tmpsub.code_suffix);
						strcpy(cfg.sub[j]->sname,tmpsub.sname);
						strcpy(cfg.sub[j]->lname,tmpsub.lname);
						strcpy(cfg.sub[j]->qwkname,tmpsub.qwkname);
						strcpy(cfg.sub[j]->data_dir,tmpsub.data_dir);
						if(j==cfg.total_subs)
							cfg.sub[j]->maxmsgs=1000;
					}
					if(j==cfg.total_subs) {	/* adding new sub-board */
						for(;ptridx<USHRT_MAX;ptridx++) {
							for(n=0;n<total_subs;n++)
								if(cfg.sub[n]->ptridx==ptridx)
									break;
							if(n==total_subs)
								break; 
						}
						cfg.sub[j]->ptridx=ptridx;	/* use new ptridx */
						cfg.sub[j]->misc=tmpsub.misc;
						cfg.total_subs++; 
						ptridx++;	/* don't use the same ptridx for next sub */
					}
					uifc.changes=1; 
					ported++;
				}
				fclose(stream);
				uifc.pop(0);
				sprintf(str,"%lu Message Areas Imported Successfully",ported);
                uifc.msg(str);
				break;

			case 7:
                sub_cfg(i);
				break; 
			} 
		} 
	}
}