fis-gtm/sr_unix/dtgbldir.c

294 lines
8.3 KiB
C

/****************************************************************
* *
* Copyright 2001, 2009 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "main_pragma.h"
#undef malloc
#undef free
#undef GTM_FD_TRACE /* this is a standalone executable so do not convert OPEN3 to gtm_open3 for FD tracing */
#include "gtm_string.h"
#include "gtm_fcntl.h"
#include "gtm_stat.h"
#include "gtm_stdio.h"
#include "gtm_stdlib.h"
#include "gtm_unistd.h"
#include <errno.h>
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "gdsblk.h"
#include "mlkdef.h"
#include "filestruct.h"
#include "gbldirnam.h"
#include "hashtab_mname.h"
#ifdef __MVS__
#include "gtm_zos_io.h"
#endif
#define asc2i(str,len) atoi((const char*)str)
#ifdef BIGENDIAN
# define FIRST_ONE 0x2329FFFF
# define SECOND_ONE 0x25FFFFFF
#else
# define FIRST_ONE 0xFFFF2923
# define SECOND_ONE 0xFFFFFF25
#endif
#ifdef GTM64
#define SAVE_ADDR_REGION \
{ \
int4 *tmp = (int *)&(addr->regions); \
*int4_ptr++ = *(tmp + lsb_index); \
int4_ptr++; \
}
#else /* GTM64 */
#define SAVE_ADDR_REGION \
*int4_ptr++ = (int4)addr->regions;
#endif /* GTM64 */
int main(int argc, char **argv)
{
int fd;
header_struct *header;
gd_addr *addr;
gd_region *region;
gd_region *region_top;
gd_segment *segment;
int4 *int4_ptr;
uint4 t_offset, size;
int i, alloc, extend, block, global, key, lock, record;
ZOS_ONLY(int realfiletag;)
argv++;
alloc = 100;
extend = 100;
block = 1024;
global = 128;
lock = 20;
record = 256;
key = 64;
for (i = argc; i > 1; i--)
{
if (argv[0][0] != '-' || argv[0][1] == 'h')
{
PRINTF("syntax is dtgbldir [-abegklr] with each qualifier followed by a number\n");
PRINTF("and separated by spaces. i.e. dtgbldir -a100 -b2048 -l30\n");
PRINTF("-a is alloc [100] -b is block size [1024] -e is ext [100]\n");
PRINTF("-g is glo buff [128] -k is keysize [64] -l is lock [20]\n");
PRINTF("-r is rec size [256] -h prints this message\n");
PRINTF("The global directory is created as ./mumps.gld\n");
return 0;
}
switch (argv[0][1])
{
case 'a': if (-1 == (alloc = asc2i((uchar_ptr_t)&argv[0][2],STRLEN(argv[0]) - 2)))
{
PRINTF("Invalid value for -a: %s\n", &argv[0][2]);
return 0;
}
break;
case 'b': if (-1 == (block = asc2i((uchar_ptr_t)&argv[0][2],STRLEN(argv[0]) - 2)))
{
PRINTF("Invalid value for -b: %s\n", &argv[0][2]);
return 0;
}
break;
case 'e': if (-1 == (extend = asc2i((uchar_ptr_t)&argv[0][2],STRLEN(argv[0]) - 2)))
{
PRINTF("Invalid value for -e: %s\n", &argv[0][2]);
return 0;
}
break;
case 'g': if (-1 == (global = asc2i((uchar_ptr_t)&argv[0][2], STRLEN(argv[0]) - 2)))
{
PRINTF("Invalid value for -g: %s\n", &argv[0][2]);
return 0;
}
break;
case 'k': if (-1 == (key = asc2i((uchar_ptr_t)&argv[0][2], STRLEN(argv[0]) - 2)))
{
PRINTF("Invalid value for -k: %s\n", &argv[0][2]);
return 0;
}
break;
case 'l': if (-1 == (lock = asc2i((uchar_ptr_t)&argv[0][2], STRLEN(argv[0]) - 2)))
{
PRINTF("Invalid value for -l: %s\n", &argv[0][2]);
return 0;
}
break;
case 'r': if (-1 == (record = asc2i((uchar_ptr_t)&argv[0][2], STRLEN(argv[0]) - 2)))
{
PRINTF("Invalid value for -r: %s\n", &argv[0][2]);
return 0;
}
break;
default: PRINTF("unrecognized qualifier %s\n",argv[0]);
return 0;
}
argv++;
}
if (argc == 1)
{
PRINTF("syntax is dtgbldir [-abegklr] with each qualifier followed by a number\n");
PRINTF("and separated by spaces. i.e. dtgbldir -a100 -b2048 -l30\n");
PRINTF("-a is alloc [100] -b is block size [1024] -e is ext [100]\n");
PRINTF("-g is glo buff [128] -k is keysize [64] -l is lock [20]\n");
PRINTF("-r is rec size [256] -h prints this message\n");
PRINTF("The global directory is created as ./mumps.gld\n");
PRINTF("\n\nCreating default global directory\n");
}
if (record > (block / 2) - 4)
{
PRINTF("Record size %d is too large, block size %d will only support record size of %d\n",
record, block, (block / 2) - 4);
return 0;
}
if (key >= record)
{
PRINTF("Key size %d is too large, record size %d will only support key size of %d\n",
key, record, record - 1);
return 0;
}
if (lock > 100 || lock < 4)
{
PRINTF("Lock size %d is invalid, must be between 4 and 100\n", lock);
return 0;
}
if (block % DISK_BLOCK_SIZE)
{
PRINTF("Block size %d is invalid, must be a multiple of %d\n", block, DISK_BLOCK_SIZE);
return 0;
}
if (global < 64 || global > 4096)
{
PRINTF("Global value %d is invalid, must be between 64 and 4096\n", global);
return 0;
}
if (FD_INVALID == (fd = OPEN3("./mumps.gld", O_CREAT | O_EXCL | O_RDWR, 0600)))
{
PERROR("Error opening file");
return 0;
}
#if defined(__MVS__)
if (-1 == gtm_zos_set_tag(fd, TAG_BINARY, TAG_NOTTEXT, TAG_FORCE, &realfiletag))
PERROR("Error tagging file with TAG_BINARY");
#endif
size = SIZEOF(header_struct) + SIZEOF(gd_addr) + 3 * SIZEOF(gd_binding) + 1 * SIZEOF(gd_region) + 1 * SIZEOF(gd_segment);
header = (header_struct *)malloc(ROUND_UP(size, DISK_BLOCK_SIZE));
memset(header, 0, ROUND_UP(size, DISK_BLOCK_SIZE));
header->filesize = size;
size = ROUND_UP(size, DISK_BLOCK_SIZE);
MEMCPY_LIT(header->label, GDE_LABEL_LITERAL);
addr = (gd_addr *)((char *)header + SIZEOF(header_struct));
addr->max_rec_size = 256;
addr->maps = (gd_binding*)(SIZEOF(gd_addr));
addr->n_maps = 3;
addr->regions = (gd_region *)((INTPTR_T)(addr->maps) + 3 * SIZEOF(gd_binding));
addr->n_regions = 1;
addr->segments = (gd_segment *)((INTPTR_T)(addr->regions) + SIZEOF(gd_region));
addr->n_segments = 1;
addr->link = 0;
addr->tab_ptr = 0;
addr->id = 0;
addr->local_locks = 0;
addr->end = (INTPTR_T)((char *)addr->segments + 1 * SIZEOF(gd_segment));
int4_ptr = (int4*)((char *)addr + (INTPTR_T)(addr->maps));
*int4_ptr++ = FIRST_ONE;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
SAVE_ADDR_REGION
*int4_ptr++ = SECOND_ONE;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
SAVE_ADDR_REGION
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
*int4_ptr++ = 0xFFFFFFFF;
SAVE_ADDR_REGION
region = (gd_region*)((char *)addr + (INTPTR_T)(addr->regions));
segment = (gd_segment*)((char *)addr + (INTPTR_T)(addr->segments));
region->rname_len = 7;
memcpy(region->rname,"DEFAULT",7);
for (region_top = region + addr->n_regions; region < region_top ; region++)
{ t_offset = region->dyn.offset;
region->dyn.addr = (gd_segment *)(INTPTR_T)t_offset;
}
region = (gd_region*)((char *)addr + (INTPTR_T)(addr->regions));
region->dyn.offset = (int4)(INTPTR_T)addr->segments;
region->max_rec_size = record;
region->max_key_size = key;
region->open = region->lock_write = region->null_subs = region->jnl_state = 0;
region->jnl_alq = 0x64;
region->jnl_deq = 0x64;
region->jnl_buffer_size = 0x80;
region->jnl_before_image = 1;
region->jnl_file_len = region->node = region->cmx_regnum = 0;
region->sec_size = 0;
segment->sname_len = 7;
memcpy(segment->sname,"DEFAULT",7);
memcpy(segment->fname,"mumps.dat",9);
segment->fname_len = 9;
segment->blk_size = block;
segment->allocation = alloc;
segment->ext_blk_count = extend;
segment->cm_blk = 0;
segment->lock_space = lock;
memcpy(segment->defext,".DAT",4);
segment->global_buffers = global;
segment->buckets = 0;
segment->windows = 0;
segment->acc_meth = dba_bg;
segment->defer_time = 0;
segment->file_cntl = 0;
if (lseek(fd, (off_t)0, SEEK_SET))
{
PERROR("Error seeking on file");
return 0;
}
if (write(fd, header, size) != size)
{
PERROR("Error writing to file");
return 0;
}
return 1;
}