diff options
Diffstat (limited to 'storage/connect/plugutil.cpp')
-rw-r--r-- | storage/connect/plugutil.cpp | 596 |
1 files changed, 596 insertions, 0 deletions
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp new file mode 100644 index 00000000000..d34b43a63d2 --- /dev/null +++ b/storage/connect/plugutil.cpp @@ -0,0 +1,596 @@ +/************** PlugUtil C Program Source Code File (.C) ***************/ +/* */ +/* PROGRAM NAME: PLUGUTIL */ +/* ------------- */ +/* Version 2.9 */ +/* */ +/* COPYRIGHT: */ +/* ---------- */ +/* (C) Copyright to the author Olivier BERTRAND 1993-2015 */ +/* */ +/* WHAT THIS PROGRAM DOES: */ +/* ----------------------- */ +/* This program are initialization and utility Plug routines. */ +/* */ +/* WHAT YOU NEED TO COMPILE THIS PROGRAM: */ +/* -------------------------------------- */ +/* */ +/* REQUIRED FILES: */ +/* --------------- */ +/* See Readme.C for a list and description of required SYSTEM files. */ +/* */ +/* PLUG.C - Source code */ +/* GLOBAL.H - Global declaration file */ +/* OPTION.H - Option declaration file */ +/* */ +/* REQUIRED LIBRARIES: */ +/* ------------------- */ +/* */ +/* OS2.LIB - OS2 libray */ +/* LLIBCE.LIB - Protect mode/standard combined large model C */ +/* library */ +/* */ +/* REQUIRED PROGRAMS: */ +/* ------------------ */ +/* */ +/* IBM C Compiler */ +/* IBM Linker */ +/* */ +/***********************************************************************/ + +/***********************************************************************/ +/* */ +/* Include relevant MariaDB header file. */ +/* */ +/***********************************************************************/ +#include "my_global.h" +#if defined(__WIN__) +//#include <windows.h> +#else +#if defined(UNIX) || defined(UNIV_LINUX) +#include <errno.h> +#include <unistd.h> +//#define __stdcall +#else +#include <dir.h> +#endif +#include <stdarg.h> +#endif + +#if defined(WIN) +#include <alloc.h> +#endif +#include <errno.h> /* definitions of ERANGE ENOMEM */ +#if !defined(UNIX) && !defined(UNIV_LINUX) +#include <direct.h> /* Directory management library */ +#endif + +/***********************************************************************/ +/* */ +/* Include application header files */ +/* */ +/* global.h is header containing all global declarations. */ +/* */ +/***********************************************************************/ +#define STORAGE /* Initialize global variables */ + +#include "osutil.h" +#include "global.h" +#if defined(NEWMSG) +#include "rcmsg.h" +#endif // NEWMSG + +#if defined(__WIN__) +extern HINSTANCE s_hModule; /* Saved module handle */ +#endif // __WIN__ + +#if defined(XMSG) +extern char *msg_path; +char *msglang(void); +#endif // XMSG + +/***********************************************************************/ +/* Local Definitions and static variables */ +/***********************************************************************/ +typedef struct { + ushort Segsize; + ushort Size; + } AREASIZE; + +ACTIVITY defActivity = { /* Describes activity and language */ + NULL, /* Points to user work area(s) */ + "Unknown"}; /* Application name */ + +#if defined(XMSG) || defined(NEWMSG) + static char stmsg[200]; +#endif // XMSG || NEWMSG + +#if defined(UNIX) || defined(UNIV_LINUX) +#include "rcmsg.h" +#endif // UNIX + +/**************************************************************************/ +/* Tracing output function. */ +/**************************************************************************/ +void htrc(char const *fmt, ...) + { + va_list ap; + va_start (ap, fmt); + + +//if (trace == 1) +// vfprintf(debug, fmt, ap); +//else + vfprintf(stderr, fmt, ap); + + va_end (ap); + } // end of htrc + +/***********************************************************************/ +/* Plug initialization routine. */ +/* Language points on initial language name and eventual path. */ +/* Return value is the pointer to the Global structure. */ +/***********************************************************************/ +PGLOBAL PlugInit(LPCSTR Language, uint worksize) + { + PGLOBAL g; + + if (trace > 1) + htrc("PlugInit: Language='%s'\n", + ((!Language) ? "Null" : (char*)Language)); + + if (!(g = (PGLOBAL)malloc(sizeof(GLOBAL)))) { + fprintf(stderr, MSG(GLOBAL_ERROR), (int)sizeof(GLOBAL)); + return NULL; + } else { + g->Sarea = NULL; + g->Createas = 0; + g->Alchecked = 0; + g->Mrr = 0; + g->Activityp = NULL; + g->Xchk = NULL; + g->N = 0; + g->More = 0; + strcpy(g->Message, ""); + + /*******************************************************************/ + /* Allocate the main work segment. */ + /*******************************************************************/ + if (worksize && !(g->Sarea = PlugAllocMem(g, worksize))) { + char errmsg[256]; + sprintf(errmsg, MSG(WORK_AREA), g->Message); + strcpy(g->Message, errmsg); + g->Sarea_Size = 0; + } else + g->Sarea_Size = worksize; + + } /* endif g */ + + g->jump_level = -1; /* New setting to allow recursive call of Plug */ + return(g); + } /* end of PlugInit */ + +/***********************************************************************/ +/* PlugExit: Terminate Plug operations. */ +/***********************************************************************/ +int PlugExit(PGLOBAL g) + { + int rc = 0; + + if (!g) + return rc; + + if (g->Sarea) + free(g->Sarea); + + free(g); + return rc; + } /* end of PlugExit */ + +/***********************************************************************/ +/* Remove the file type from a file name. */ +/* Note: this routine is not really implemented for Unix. */ +/***********************************************************************/ +LPSTR PlugRemoveType(LPSTR pBuff, LPCSTR FileName) + { +#if defined(__WIN__) + char drive[_MAX_DRIVE]; +#else + char *drive = NULL; +#endif + char direc[_MAX_DIR]; + char fname[_MAX_FNAME]; + char ftype[_MAX_EXT]; + + _splitpath(FileName, drive, direc, fname, ftype); + + if (trace > 1) { + htrc("after _splitpath: FileName=%s\n", FileName); + htrc("drive=%s dir=%s fname=%s ext=%s\n", + SVP(drive), direc, fname, ftype); + } // endif trace + + _makepath(pBuff, drive, direc, fname, ""); + + if (trace > 1) + htrc("buff='%s'\n", pBuff); + + return pBuff; + } // end of PlugRemoveType + + +BOOL PlugIsAbsolutePath(LPCSTR path) +{ +#if defined(__WIN__) + return ((path[0] >= 'a' && path[0] <= 'z') || + (path[0] >= 'A' && path[0] <= 'Z')) && path[1] == ':'; +#else + return path[0] == '/'; +#endif +} + +/***********************************************************************/ +/* Set the full path of a file relatively to a given path. */ +/* Note: this routine is not really implemented for Unix. */ +/***********************************************************************/ +LPCSTR PlugSetPath(LPSTR pBuff, LPCSTR prefix, LPCSTR FileName, LPCSTR defpath) + { + char newname[_MAX_PATH]; + char direc[_MAX_DIR], defdir[_MAX_DIR], tmpdir[_MAX_DIR]; + char fname[_MAX_FNAME]; + char ftype[_MAX_EXT]; +#if defined(__WIN__) + char drive[_MAX_DRIVE], defdrv[_MAX_DRIVE]; +#else + char *drive = NULL, *defdrv = NULL; +#endif + + if (trace > 1) + htrc("prefix=%s fn=%s path=%s\n", prefix, FileName, defpath); + + if (!strncmp(FileName, "//", 2) || !strncmp(FileName, "\\\\", 2)) { + strcpy(pBuff, FileName); // Remote file + return pBuff; + } // endif + + if (PlugIsAbsolutePath(FileName)) + { + strcpy(pBuff, FileName); // FileName includes absolute path + return pBuff; + } // endif + +#if !defined(__WIN__) + if (*FileName == '~') { + if (_fullpath(pBuff, FileName, _MAX_PATH)) { + if (trace > 1) + htrc("pbuff='%s'\n", pBuff); + + return pBuff; + } else + return FileName; // Error, return unchanged name + + } // endif FileName +#endif // !__WIN__ + + if (prefix && strcmp(prefix, ".") && !PlugIsAbsolutePath(defpath)) + { + char tmp[_MAX_PATH]; + int len= snprintf(tmp, sizeof(tmp) - 1, "%s%s%s", + prefix, defpath, FileName); + memcpy(pBuff, tmp, (size_t) len); + pBuff[len]= '\0'; + return pBuff; + } + + _splitpath(FileName, drive, direc, fname, ftype); + + if (defpath) { + char c = defpath[strlen(defpath) - 1]; + + strcpy(tmpdir, defpath); + + if (c != '/' && c != '\\') + strcat(tmpdir, "/"); + + } else + strcpy(tmpdir, "./"); + + _splitpath(tmpdir, defdrv, defdir, NULL, NULL); + + if (trace > 1) { + htrc("after _splitpath: FileName=%s\n", FileName); +#if defined(__WIN__) + htrc("drive=%s dir=%s fname=%s ext=%s\n", drive, direc, fname, ftype); + htrc("defdrv=%s defdir=%s\n", defdrv, defdir); +#else + htrc("dir=%s fname=%s ext=%s\n", direc, fname, ftype); +#endif + } // endif trace + + if (drive && !*drive) + strcpy(drive, defdrv); + + switch (*direc) { + case '\0': + strcpy(direc, defdir); + break; + case '\\': + case '/': + break; + default: + // This supposes that defdir ends with a SLASH + strcpy(direc, strcat(defdir, direc)); + } // endswitch + + _makepath(newname, drive, direc, fname, ftype); + + if (trace > 1) + htrc("newname='%s'\n", newname); + + if (_fullpath(pBuff, newname, _MAX_PATH)) { + if (trace > 1) + htrc("pbuff='%s'\n", pBuff); + + return pBuff; + } else + return FileName; // Error, return unchanged name + + } // end of PlugSetPath + +#if defined(XMSG) +/***********************************************************************/ +/* PlugGetMessage: get a message from the message file. */ +/***********************************************************************/ +char *PlugReadMessage(PGLOBAL g, int mid, char *m) + { + char msgfile[_MAX_PATH], msgid[32], buff[256]; + char *msg; + FILE *mfile = NULL; + +//GetPrivateProfileString("Message", msglang, "Message\\english.msg", +// msgfile, _MAX_PATH, plgini); +//strcat(strcat(strcpy(msgfile, msg_path), msglang()), ".msg"); + strcat(strcpy(buff, msglang()), ".msg"); + PlugSetPath(msgfile, NULL, buff, msg_path); + + if (!(mfile = fopen(msgfile, "rt"))) { + sprintf(stmsg, "Fail to open message file %s", msgfile); + goto err; + } // endif mfile + + for (;;) + if (!fgets(buff, 256, mfile)) { + sprintf(stmsg, "Cannot get message %d %s", mid, SVP(m)); + goto fin; + } else + if (atoi(buff) == mid) + break; + + if (sscanf(buff, " %*d %s \"%[^\"]", msgid, stmsg) < 2) { + // Old message file + if (!sscanf(buff, " %*d \"%[^\"]", stmsg)) { + sprintf(stmsg, "Bad message file for %d %s", mid, SVP(m)); + goto fin; + } else + m = NULL; + + } // endif sscanf + + if (m && strcmp(m, msgid)) { + // Message file is out of date + strcpy(stmsg, m); + goto fin; + } // endif m + + fin: + fclose(mfile); + + err: + if (g) { + // Called by STEP + msg = PlugDup(g, stmsg); + } else // Called by MSG or PlgGetErrorMsg + msg = stmsg; + + return msg; + } // end of PlugReadMessage + +#elif defined(NEWMSG) +/***********************************************************************/ +/* PlugGetMessage: get a message from the resource string table. */ +/***********************************************************************/ +char *PlugGetMessage(PGLOBAL g, int mid) + { + char *msg; + +#if 0 // was !defined(UNIX) && !defined(UNIV_LINUX) + int n = LoadString(s_hModule, (uint)mid, (LPTSTR)stmsg, 200); + + if (n == 0) { + DWORD rc = GetLastError(); + msg = (char*)PlugSubAlloc(g, NULL, 512); // Extend buf allocation + n = sprintf(msg, "Message %d, rc=%d: ", mid, rc); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0, + (LPTSTR)(msg + n), 512 - n, NULL); + return msg; + } // endif n + +#else // ALL + if (!GetRcString(mid, stmsg, 200)) + sprintf(stmsg, "Message %d not found", mid); +#endif // ALL + + if (g) { + // Called by STEP + msg = PlugDup(g, stmsg); + } else // Called by MSG or PlgGetErrorMsg + msg = stmsg; + + return msg; + } // end of PlugGetMessage +#endif // NEWMSG + +#if defined(__WIN__) +/***********************************************************************/ +/* Return the line length of the console screen buffer. */ +/***********************************************************************/ +short GetLineLength(PGLOBAL g) + { + CONSOLE_SCREEN_BUFFER_INFO coninfo; + HANDLE hcons = GetStdHandle(STD_OUTPUT_HANDLE); + BOOL b = GetConsoleScreenBufferInfo(hcons, &coninfo); + + return (b) ? coninfo.dwSize.X : 0; + } // end of GetLineLength +#endif // __WIN__ + +/***********************************************************************/ +/* Program for memory allocation of work and language areas. */ +/***********************************************************************/ +void *PlugAllocMem(PGLOBAL g, uint size) + { + void *areap; /* Pointer to allocated area */ + + /*********************************************************************/ + /* This is the allocation routine for the WIN32/UNIX/AIX version. */ + /*********************************************************************/ + if (!(areap = malloc(size))) + sprintf(g->Message, MSG(MALLOC_ERROR), "malloc"); + + if (trace > 1) { + if (areap) + htrc("Memory of %u allocated at %p\n", size, areap); + else + htrc("PlugAllocMem: %s\n", g->Message); + + } // endif trace + + return (areap); + } /* end of PlugAllocMem */ + +/***********************************************************************/ +/* Program for SubSet initialization of memory pools. */ +/* Here there should be some verification done such as validity of */ +/* the address and size not larger than memory size. */ +/***********************************************************************/ +BOOL PlugSubSet(PGLOBAL g __attribute__((unused)), void *memp, uint size) + { + PPOOLHEADER pph = (PPOOLHEADER)memp; + + pph->To_Free = (OFFSET)sizeof(POOLHEADER); + pph->FreeBlk = size - pph->To_Free; + + return FALSE; + } /* end of PlugSubSet */ + +/***********************************************************************/ +/* Program for sub-allocating one item in a storage area. */ +/* Note: SubAlloc routines of OS/2 are no more used to increase the */ +/* code portability and avoid problems when a grammar compiled under */ +/* one version of OS/2 is used under another version. */ +/* The simple way things are done here is also based on the fact */ +/* that no freeing of suballocated blocks is permitted in Plug. */ +/***********************************************************************/ +void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size) + { + PPOOLHEADER pph; /* Points on area header. */ + + if (!memp) + /*******************************************************************/ + /* Allocation is to be done in the Sarea. */ + /*******************************************************************/ + memp = g->Sarea; + + size = ((size + 7) / 8) * 8; /* Round up size to multiple of 8 */ + pph = (PPOOLHEADER)memp; + + if (trace > 3) + htrc("SubAlloc in %p size=%d used=%d free=%d\n", + memp, size, pph->To_Free, pph->FreeBlk); + + if ((uint)size > pph->FreeBlk) { /* Not enough memory left in pool */ + char *pname = "Work"; + + sprintf(g->Message, + "Not enough memory in %s area for request of %u (used=%d free=%d)", + pname, (uint)size, pph->To_Free, pph->FreeBlk); + + if (trace) + htrc("PlugSubAlloc: %s\n", g->Message); + +#if defined(USE_TRY) + throw 1234; +#else // !USE_TRY + /* Nothing we can do if longjmp is not initialized. */ + assert(g->jump_level >= 0); + longjmp(g->jumper[g->jump_level], 1); +#endif // !USE_TRY + } /* endif size OS32 code */ + + /*********************************************************************/ + /* Do the suballocation the simplest way. */ + /*********************************************************************/ + memp = MakePtr(memp, pph->To_Free); /* Points to suballocated block */ + pph->To_Free += (OFFSET)size; /* New offset of pool free block */ + pph->FreeBlk -= (uint)size; /* New size of pool free block */ + + if (trace > 3) + htrc("Done memp=%p used=%d free=%d\n", + memp, pph->To_Free, pph->FreeBlk); + + return (memp); + } /* end of PlugSubAlloc */ + +/***********************************************************************/ +/* Program for sub-allocating and copying a string in a storage area. */ +/***********************************************************************/ +char *PlugDup(PGLOBAL g, const char *str) + { + if (str) { + char *sm = (char*)PlugSubAlloc(g, NULL, strlen(str) + 1); + + strcpy(sm, str); + return sm; + } else + return NULL; + + } // end of PlugDup + +#if 0 +/***********************************************************************/ +/* This routine suballocate a copy of the passed string. */ +/***********************************************************************/ +char *PlugDup(PGLOBAL g, const char *str) + { + char *buf; + size_t len; + + if (str && (len = strlen(str))) { + buf = (char*)PlugSubAlloc(g, NULL, len + 1); + strcpy(buf, str); + } else + buf = NULL; + + return(buf); + } /* end of PlugDup */ +#endif // 0 + +/***********************************************************************/ +/* This routine makes a pointer from an offset to a memory pointer. */ +/***********************************************************************/ +void *MakePtr(void *memp, OFFSET offset) + { + return ((offset == 0) ? NULL : &((char *)memp)[offset]); + } /* end of MakePtr */ + +/***********************************************************************/ +/* This routine makes an offset from a pointer new format. */ +/***********************************************************************/ +#if 0 +OFFSET MakeOff(void *memp, void *ptr) + { + return ((!ptr) ? 0 : (OFFSET)((char *)ptr - (char *)memp)); + } /* end of MakeOff */ +#endif +/*--------------------- End of PLUGUTIL program -----------------------*/ |