int gtcm_cn_acpt(omi_conn_ll *cll, int now) /* now --> current time in seconds */ { int i; omi_conn *cptr; omi_fd fd; int rc; char *tmp_time; #ifdef BSD_TCP GTM_SOCKLEN_TYPE sln; struct sockaddr_storage sas; int optsize; const boolean_t keepalive = TRUE; /* Accept the connection from the network layer */ sln = SIZEOF(sas); if ((fd = accept(cll->nve, (struct sockaddr *)&sas, (GTM_SOCKLEN_TYPE *)&sln)) < 0) return -1; #endif /* defined(BSD_TCP) */ /* Build the client data structure */ if (!(cptr = (omi_conn *)malloc(SIZEOF(omi_conn))) || !(cptr->buff = (char *)malloc(OMI_BUFSIZ))) { if (cptr) free(cptr); CLOSEFILE_RESET(fd, rc); /* resets "fd" to FD_INVALID */ return -1; } /* Initialize the connection structure */ cptr->next = (omi_conn *)0; cptr->fd = fd; cptr->ping_cnt = 0; cptr->timeout = now + conn_timeout; cptr->bsiz = OMI_BUFSIZ; cptr->bptr = cptr->buff; cptr->xptr = (char *)0; cptr->blen = 0; cptr->exts = 0; cptr->state = OMI_ST_DISC; cptr->ga = (ga_struct *)0; /* struct gd_addr_struct */ cptr->of = (oof_struct *) malloc(SIZEOF(struct rc_oflow)); memset(cptr->of, 0, SIZEOF(struct rc_oflow)); cptr->pklog = FD_INVALID; /* Initialize the statistics */ memcpy(&cptr->stats.sas, &sas, sln); cptr->stats.ai.ai_addr = (struct sockaddr *)&cptr->stats.sas; cptr->stats.ai.ai_addrlen = sln; cptr->stats.bytes_recv = 0; cptr->stats.bytes_send = 0; cptr->stats.start = time((time_t *)0); for (i = 0; i < OMI_OP_MAX; i++) cptr->stats.xact[i] = 0; for (i = 0; i < OMI_ER_MAX; i++) cptr->stats.errs[i] = 0; /* if we only allowing one connection per internet address, close any existing ones with the same addr. */ if (one_conn_per_inaddr) { omi_conn *this, *prev; for (prev = NULL, this = cll->head; this; prev = this, this = this->next) { if (0 == memcmp((sockaddr_ptr)(&this->stats.sas), (sockaddr_ptr)&sas, sln)) { if (cll->tail == this) cll->tail = cptr; if (prev) prev->next = cptr; else cll->head = cptr; cptr->next = this->next; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: dropping old connection to %s\n", SRVR_NAME, gtcm_hname(&cptr->stats.ai))); gtcm_cn_disc(this, cll); break; } } /* not found - add to the end of the list */ if (!this) { if (cll->tail) { cll->tail->next = cptr; cll->tail = cptr; } else cll->head = cll->tail = cptr; } } else { /* Insert the client into the list of connections */ if (cll->tail) { cll->tail->next = cptr; cll->tail = cptr; } else cll->head = cll->tail = cptr; } cptr->stats.id = ++cll->stats.conn; DEBUG_ONLY( if (omi_pklog) { int errno_save; char pklog[1024]; (void)SPRINTF(pklog, "%s.%04d", omi_pklog, cptr->stats.id); if (INV_FD_P((cptr->pklog = OPEN3(pklog, O_WRONLY|O_CREAT|O_APPEND|O_TRUNC, 0644)))) { errno_save = errno; OMI_DBG_STMP; OMI_DBG((omi_debug, "%s: unable to open packet log \"%s\"\n\t%s\n", SRVR_NAME, pklog, STRERROR(errno_save))); } } )
void iob_read(BFILE *bf, char *buf, int nbytes) { int4 nread, nreread; int rc; error_def(ERR_IOEOF); if (bf->write_mode) { iob_flush(bf); bf->write_mode = FALSE; } #ifdef DEBUG_IOB PRINTF("iob_read:\tiob_read(%x, %x, %d), bf->remaining = %d\n", bf, buf, nbytes, bf->remaining); #endif while (nbytes > bf->remaining) { /* copy bytes remaining in buffer */ memcpy(buf, bf->bptr, bf->remaining); nbytes -= bf->remaining; buf += bf->remaining; /* refill */ DOREADRL(bf->fd, bf->buf, bf->bufsiz, nread); #ifdef DEBUG_IOB PRINTF("iob_read:\t\tread(%d, %x, %d) = %d\n", bf->fd, bf->buf, bf->bufsiz, nread); #endif bf->bptr = bf->buf; bf->remaining = nread; if (nread == -1) { rts_error(VARLSTCNT(1) errno); return; } else if (nread == 0 || nread % bf->blksiz) { CLOSEFILE_RESET(bf->fd, rc); /* resets "bf->fd" to FD_INVALID */ rts_error(VARLSTCNT(1) ERR_IOEOF); /* if we continued from here, assume that this is a magnetic tape and we have loaded the next volume. Re-open and finish the read operation. */ while (FD_INVALID == (bf->fd = OPEN3(bf->path,bf->oflag,bf->mode))) rts_error(VARLSTCNT(1) errno); DOREADRL(bf->fd, bf->buf + nread, bf->bufsiz - nread, nreread); #ifdef DEBUG_IOB PRINTF("iob_read:\t\tread(%d, %x, %d) = %d\n", bf->fd, bf->buf, bf->bufsiz, nread); #endif if (nreread < bf->bufsiz - nread) { rts_error(VARLSTCNT(1) errno); return; } bf->remaining = nread; } } memcpy(buf, bf->bptr, nbytes); bf->bptr += nbytes; bf->remaining -= nbytes; }
unsigned char mu_cre_file(void) { char *cc = NULL, path[MAX_FBUFF + 1], errbuff[512]; unsigned char buff[DISK_BLOCK_SIZE]; int fd = -1, i, lower, upper, status, padded_len, padded_vbn, norm_vbn; uint4 raw_dev_size; /* size of a raw device, in bytes */ int4 blocks_for_create, blocks_for_extension, save_errno; GTM_BAVAIL_TYPE avail_blocks; file_control fc; mstr file; parse_blk pblk; unix_db_info udi_struct, *udi; char *fgets_res; gd_segment *seg; error_def(ERR_NOSPACECRE); error_def(ERR_LOWSPACECRE); assert((-(sizeof(uint4) * 2) & sizeof(sgmnt_data)) == sizeof(sgmnt_data)); cs_addrs = &udi_struct.s_addrs; cs_data = (sgmnt_data_ptr_t)NULL; /* for CLEANUP */ memset(&pblk, 0, sizeof(pblk)); pblk.fop = (F_SYNTAXO | F_PARNODE); pblk.buffer = path; pblk.buff_size = MAX_FBUFF; file.addr = (char*)gv_cur_region->dyn.addr->fname; file.len = gv_cur_region->dyn.addr->fname_len; strncpy(path,file.addr,file.len); *(path+file.len) = '\0'; if (is_raw_dev(path)) { /* do not use a default extension for raw device files */ pblk.def1_buf = DEF_NODBEXT; pblk.def1_size = sizeof(DEF_NODBEXT) - 1; } else { pblk.def1_buf = DEF_DBEXT; pblk.def1_size = sizeof(DEF_DBEXT) - 1; } if (1 != (parse_file(&file, &pblk) & 1)) { PRINTF("Error translating filename %s.\n", gv_cur_region->dyn.addr->fname); return EXIT_ERR; } path[pblk.b_esl] = 0; if (pblk.fnb & F_HAS_NODE) { /* Remote node specification given */ assert(pblk.b_node); PRINTF("Database file for region %s not created; cannot create across network.\n", path); return EXIT_WRN; } udi = &udi_struct; udi->raw = is_raw_dev(pblk.l_dir); if (udi->raw) { fd = OPEN(pblk.l_dir,O_EXCL | O_RDWR); if (-1 == fd) { SPRINTF_AND_PERROR("Error opening file %s\n"); return EXIT_ERR; } if (-1 != (status = (ssize_t)lseek(fd, 0, SEEK_SET))) { DOREADRC(fd, buff, sizeof(buff), status); } else status = errno; if (0 != status) { SPRINTF_AND_PERROR("Error reading header for file %s\n"); return EXIT_ERR; } if (!memcmp(buff, GDS_LABEL, STR_LIT_LEN(GDS_LABEL))) { char rsp[80]; PRINTF("Database already exists on device %s\n", path); PRINTF("Do you wish to re-initialize (all current data will be lost) [y/n] ? "); FGETS(rsp, 79, stdin, fgets_res); if ('y' != *rsp) return EXIT_NRM; } PRINTF("Determining size of raw device...\n"); for(i = 1; read(fd, buff, sizeof(buff)) == sizeof(buff);) { i *= 2; lseek(fd, (off_t)i * BUFSIZ, SEEK_SET); } lower = i / 2; upper = i; while ((lower + upper) / 2 != lower) { i = (lower + upper) / 2; lseek(fd, (off_t)i * BUFSIZ, SEEK_SET); if (read(fd, buff, sizeof(buff)) == sizeof(buff)) lower = i; else upper = i; } raw_dev_size = i * BUFSIZ; } else { fd = OPEN3(pblk.l_dir, O_CREAT | O_EXCL | O_RDWR, 0600); if (-1 == fd) { SPRINTF_AND_PERROR("Error opening file %s\n"); return EXIT_ERR; } if (0 != (save_errno = disk_block_available(fd, &avail_blocks, FALSE))) { errno = save_errno; SPRINTF_AND_PERROR("Error checking available disk space for %s\n"); CLEANUP(EXIT_ERR); return EXIT_ERR; } seg = gv_cur_region->dyn.addr; /* blocks_for_create is in the unit of DISK_BLOCK_SIZE */ blocks_for_create = DIVIDE_ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE) + 1 + (seg->blk_size / DISK_BLOCK_SIZE * ((DIVIDE_ROUND_UP(seg->allocation, BLKS_PER_LMAP - 1)) + seg->allocation)); if ((uint4)avail_blocks < blocks_for_create) { gtm_putmsg(VARLSTCNT(6) ERR_NOSPACECRE, 4, LEN_AND_STR(path), blocks_for_create, (uint4)avail_blocks); send_msg(VARLSTCNT(6) ERR_NOSPACECRE, 4, LEN_AND_STR(path), blocks_for_create, (uint4)avail_blocks); CLEANUP(EXIT_ERR); return EXIT_ERR; } blocks_for_extension = (seg->blk_size / DISK_BLOCK_SIZE * ((DIVIDE_ROUND_UP(EXTEND_WARNING_FACTOR * seg->ext_blk_count, BLKS_PER_LMAP - 1)) + EXTEND_WARNING_FACTOR * seg->ext_blk_count)); if ((uint4)(avail_blocks - blocks_for_create) < blocks_for_extension) { gtm_putmsg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, LEN_AND_STR(path), EXTEND_WARNING_FACTOR, blocks_for_extension, DISK_BLOCK_SIZE, (uint4)(avail_blocks - blocks_for_create)); send_msg(VARLSTCNT(8) ERR_LOWSPACECRE, 6, LEN_AND_STR(path), EXTEND_WARNING_FACTOR, blocks_for_extension, DISK_BLOCK_SIZE, (uint4)(avail_blocks - blocks_for_create)); } } gv_cur_region->dyn.addr->file_cntl = &fc; fc.file_info = (void*)&udi_struct; udi->fd = fd; cs_data = (sgmnt_data_ptr_t)malloc(sizeof(sgmnt_data)); memset(cs_data, 0, sizeof(*cs_data)); cs_data->createinprogress = TRUE; cs_data->semid = INVALID_SEMID; cs_data->shmid = INVALID_SHMID; /* We want our datablocks to start on what would be a block boundary within the file so pad the fileheader if necessary to make this happen. */ padded_len = ROUND_UP(sizeof(sgmnt_data), BLK_SIZE); padded_vbn = DIVIDE_ROUND_UP(padded_len, DISK_BLOCK_SIZE) + 1; norm_vbn = DIVIDE_ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE) + 1; cs_data->start_vbn = padded_vbn; cs_data->free_space += (padded_vbn - norm_vbn) * DISK_BLOCK_SIZE; cs_data->acc_meth = gv_cur_region->dyn.addr->acc_meth; if (udi->raw) { /* calculate total blocks, reduce to make room for the * database header (size rounded up to a block), then * make into a multiple of BLKS_PER_LMAP to have a complete bitmap * for each set of blocks. */ cs_data->trans_hist.total_blks = raw_dev_size - ROUND_UP(sizeof(sgmnt_data), DISK_BLOCK_SIZE); cs_data->trans_hist.total_blks /= (uint4)(((gd_segment *)gv_cur_region->dyn.addr)->blk_size); if (0 == (cs_data->trans_hist.total_blks - DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, BLKS_PER_LMAP - 1) % (BLKS_PER_LMAP - 1))) cs_data->trans_hist.total_blks -= 1; /* don't create a bitmap with no data blocks */ cs_data->extension_size = 0; PRINTF("Raw device size is %dK, %d GDS blocks\n", raw_dev_size / 1000, cs_data->trans_hist.total_blks); } else { cs_data->trans_hist.total_blks = gv_cur_region->dyn.addr->allocation; /* There are (bplmap - 1) non-bitmap blocks per bitmap, so add (bplmap - 2) to number of non-bitmap blocks * and divide by (bplmap - 1) to get total number of bitmaps for expanded database. (must round up in this * manner as every non-bitmap block must have an associated bitmap) */ cs_data->trans_hist.total_blks += DIVIDE_ROUND_UP(cs_data->trans_hist.total_blks, BLKS_PER_LMAP - 1); cs_data->extension_size = gv_cur_region->dyn.addr->ext_blk_count; } mucregini(cs_data->trans_hist.total_blks); cs_data->createinprogress = FALSE; LSEEKWRITE(udi->fd, 0, cs_data, sizeof(sgmnt_data), status); if (0 != status) { SPRINTF_AND_PERROR("Error writing out header for file %s\n"); CLEANUP(EXIT_ERR); return EXIT_ERR; } cc = (char*)malloc(DISK_BLOCK_SIZE); memset(cc, 0, DISK_BLOCK_SIZE); LSEEKWRITE(udi->fd, (cs_data->start_vbn - 1) * DISK_BLOCK_SIZE + ((off_t)(cs_data->trans_hist.total_blks) * cs_data->blk_size), cc, DISK_BLOCK_SIZE, status); if (0 != status) { SPRINTF_AND_PERROR("Error writing out end of file %s\n"); CLEANUP(EXIT_ERR); return EXIT_ERR; } if ((!udi->raw) && (-1 == CHMOD(pblk.l_dir, 0666))) { SPRINTF_AND_PERROR("Error changing file mode on file %s\n"); CLEANUP(EXIT_WRN); return EXIT_WRN; } CLEANUP(EXIT_NRM); PRINTF("Created file %s\n", path); return EXIT_NRM; }