Example #1
0
static alice_str* alloc_string(const TEXT** ptr)
{
	AliceGlobals* tdgbl = AliceGlobals::getSpecific();

	const TEXT* p = *ptr;

	const USHORT length = (USHORT) *p++;
	alice_str* string = FB_NEW_RPT(*tdgbl->getDefaultPool(), length + 1) alice_str;
	memcpy(string->str_data, p, length);
	string->str_data[length] = 0;
	*ptr = p + length;

	return string;
}
Example #2
0
static void parse_fullpath(tdr* trans)
{
	AliceGlobals* tdgbl = AliceGlobals::getSpecific();

	// start at the end of the full pathname

 	const TEXT* p = (TEXT*) trans->tdr_fullpath->str_data;
	const TEXT* const start = p;
	while (*p)
		p++;
	const TEXT* const end = p;

	// Check for a named pipes name - \\node\path\db or //node/path/db
	while (p > start && !(*p == '/' && p[-1] == '/') && !(*p == '\\' && p[-1] == '\\'))
	{
		--p;
	}

	if (p > start)
	{
		// Increment p past slash, & search forward for end of node name
		p = p + 1;
		const TEXT* q = p;

		while (*q && *q != '/' && *q != '\\')
			q++;
		if (*q)
		{
			trans->tdr_filename = q + 1;

			trans->tdr_remote_site = FB_NEW_RPT(*tdgbl->getDefaultPool(), q - p + 1) alice_str;
			strncpy((char*) trans->tdr_remote_site->str_data, (char*) p, q - p);
			trans->tdr_remote_site->str_data[q - p] = '\0';
		}
	}
	else
	{
		p = end;

		// If not named pipes, check the other protocols
		// work backwards until we find a remote protocol specifier


		while (p >= start && (*p != '^' && *p != ':' && *p != '@'))
			p--;
		// dimitr:	make sure that the remote path is parsed correctly
		//			for win32 servers, i.e. the drive separator is taken into account
		if ((p - 2 >= start) && p[-2] == ':' && (p[0] == ':'))
			p -= 2;
		trans->tdr_filename = p + 1;

		// now find the last remote node in the chain

		while (p > start && (*p == ':' || *p == '^' || *p == '@'))
			p--;

		USHORT length = 0;
		for (; p >= start && (*p != '^' && *p != ':' && *p != '@'); ++length)
			--p;
		++p;

		if (length)
		{
			trans->tdr_remote_site = FB_NEW_RPT(*tdgbl->getDefaultPool(), length + 1) alice_str;
			TEXT* q = (TEXT *) trans->tdr_remote_site->str_data;
			while (length--)
				*q++ = *p++;
			*q = 0;
		}
	}
}
Example #3
0
static tdr* get_description(ISC_QUAD* blob_id)
{
	TEXT buffer[1024];
	TEXT* bigger_buffer = 0;
	AliceGlobals* tdgbl = AliceGlobals::getSpecific();

	const TEXT* p = buffer;
	const USHORT length = snarf_blob(blob_id, (USHORT) sizeof(buffer), buffer);
	if (length)
	{
		p = bigger_buffer = (TEXT *) gds__alloc((SLONG) length);
		if (!p)
		{
			tdgbl->status[0] = isc_arg_gds;
			tdgbl->status[1] = isc_virmemexh;
			tdgbl->status[2] = isc_arg_end;

			ALICE_print_status(true, tdgbl->status);
			return NULL;
		}
		snarf_blob(blob_id, length, bigger_buffer);
	}

	tdr* trans = NULL;
	alice_str* host_site = NULL;
	alice_str* database_path = NULL;

	// skip version number
	++p;

	tdr* ptr = NULL; // silence uninitialized warning
	SLONG id_length, id;

	while (*p)
	{
		switch (*p++)
		{
		case TDR_HOST_SITE:
			host_site = alloc_string(&p);
			break;

		case TDR_DATABASE_PATH:
			database_path = alloc_string(&p);
			break;

		case TDR_TRANSACTION_ID:
			id_length = *p++;
			id = gds__vax_integer(reinterpret_cast<const UCHAR*>(p), id_length);
			p += id_length;
			if (!trans) {
				trans = ptr = FB_NEW(*tdgbl->getDefaultPool()) tdr;
			}
			else
			{
				ptr->tdr_next = FB_NEW(*tdgbl->getDefaultPool()) tdr;
				ptr = ptr->tdr_next;
			}
			ptr->tdr_host_site = host_site;
			ptr->tdr_fullpath = database_path;
			parse_fullpath(ptr);
			ptr->tdr_id = id;
			database_path = NULL;
			break;

		default:
			ALICE_print(108);
			// msg 108: Transaction description item unknown.

			if (length) {
				gds__free(bigger_buffer);
			}
			return NULL;
		}
	}

	if (length) {
		gds__free(bigger_buffer);
	}

	return trans;
}
Example #4
0
static void reattach_database(tdr* trans)
{
    ISC_STATUS_ARRAY status_vector;
    char buffer[1024];
    // sizeof(buffer) - 1 => leave space for the terminator.
    const char* const end = buffer + sizeof(buffer) - 1;
    AliceGlobals* tdgbl = AliceGlobals::getSpecific();

    ISC_get_host(buffer, sizeof(buffer));

    if (trans->tdr_fullpath)
    {
        // if this is being run from the same host,
        // try to reconnect using the same pathname

        if (!strcmp(buffer, reinterpret_cast<const char*>(trans->tdr_host_site->str_data)))
        {
            if (TDR_attach_database(status_vector, trans,
                                    reinterpret_cast<char*>(trans->tdr_fullpath->str_data)))
            {
                return;
            }
        }
        else if (trans->tdr_host_site)
        {
            //  try going through the previous host with all available
            //  protocols, using chaining to try the same method of
            //  attachment originally used from that host
            char* p = buffer;
            const UCHAR* q = trans->tdr_host_site->str_data;
            while (*q && p < end)
                *p++ = *q++;
            *p++ = ':';
            q = trans->tdr_fullpath->str_data;
            while (*q && p < end)
                *p++ = *q++;
            *p = 0;
            if (TDR_attach_database(status_vector, trans, buffer))
            {
                return;
            }
        }

        // attaching using the old method didn't work;
        // try attaching to the remote node directly

        if (trans->tdr_remote_site)
        {
            char* p = buffer;
            const UCHAR* q = trans->tdr_remote_site->str_data;
            while (*q && p < end)
                *p++ = *q++;
            *p++ = ':';
            q = reinterpret_cast<const UCHAR*>(trans->tdr_filename);
            while (*q && p < end)
                *p++ = *q++;
            *p = 0;
            if (TDR_attach_database (status_vector, trans, buffer))
            {
                return;
            }
        }

    }
    // we have failed to reattach; notify the user
    // and let them try to succeed where we have failed

    ALICE_print(86, SafeArg() << trans->tdr_id);
    // msg 86: Could not reattach to database for transaction %ld.
    ALICE_print(87, SafeArg() << (trans->tdr_fullpath ? (char*)(trans->tdr_fullpath->str_data) : "is unknown"));
    // msg 87: Original path: %s

    if (tdgbl->uSvc->isService())
    {
        ALICE_exit(FINI_ERROR, tdgbl);
    }

    for (;;)
    {
        ALICE_print(88);	// msg 88: Enter a valid path:
        char* p = buffer;
        while (p < end && (*p = getchar()) != '\n' && !feof(stdin) && !ferror(stdin))
            ++p;
        *p = 0;
        if (!buffer[0])
            break;
        p = buffer;
        while (*p == ' ')
            ++p;
        if (TDR_attach_database(status_vector, trans, p))
        {
            const size_t p_len = strlen(p);
            alice_str* string = FB_NEW_RPT(*tdgbl->getDefaultPool(), p_len + 1) alice_str;
            strcpy(reinterpret_cast<char*>(string->str_data), p);
            string->str_length = static_cast<USHORT>(p_len);
            trans->tdr_fullpath = string;
            trans->tdr_filename = (TEXT *) string->str_data;
            return;
        }
        ALICE_print(89);	// msg 89: Attach unsuccessful.
    }
}