📄 dblfcns.c
字号:
int ii; int stat; int ft_lc; int status; unsigned short send_size; FILE_ENTRY *file_ptr = NULL; DB_TCHAR *tptr = NULL; DB_TCHAR **names; int *excl_ptr; int count; unsigned short nfiles = 0;#if defined(MULTI_TAFFILE) DB_TCHAR taffile[FILENMLEN]; DB_TCHAR *p;#endif if (!task->session_active) { stat = psp_lmcConnect(task->lockmgrn, task->dbuserid, task->dbtmp, task->lmc); if (stat != PSP_OKAY) { if (stat == PSP_DUPUSERID) return (dberr(S_DUPUSERID)); return (dberr(S_NOLOCKMGR)); } if ((login_pkt = psp_lmcAlloc(sizeof(LM_LOGIN))) == NULL) { dberr(S_NOMEMORY); goto ret_err; } vtstrcpy(login_pkt->dbuserid, task->dbuserid);#if defined(MULTI_TAFFILE) vtstrcpy(taffile, task->dbtaf); if (task->dboptions & MULTITAF) { /* If multiple TAF files are allow, send the TAF directory to the lock manager, not the filename, as the lock manager will not allow discrepancies in TAF file names */ if ((p = vtstrrchr(taffile, DIRCHAR)) == NULL) vtstrcpy(taffile, DB_TEXT(".")); else *p = DB_TEXT('\0'); } if ((tptr = psp_truename(taffile, 0)) == NULL)#else if ((tptr = psp_truename(task->dbtaf, 0)) == NULL)#endif { dberr(S_NOFILE); goto ret_err; } vtstrcpy(login_pkt->taffile, tptr); psp_freeMemory(tptr, 0); stat = psp_lmcTrans(L_LOGIN, login_pkt, sizeof(LM_LOGIN), NULL, NULL, &status, task->lmc); if (stat != PSP_OKAY || status != L_OKAY) { psp_lmcDisconnect(task->lmc); if (status == L_DUPUSER) return dberr(S_DUPUSERID); return dberr(S_NOLOCKMGR); } task->session_active = TRUE; } send_size = 0; ft_lc = task->size_ft - task->old_size_ft; if ((names = psp_getMemory(ft_lc * sizeof(DB_TCHAR *), 0)) == NULL) goto ret_err; nfiles = 0; file_ptr = &task->file_table[task->old_size_ft]; for (ii = 0; ii < ft_lc; ii++, file_ptr ++) { if (!(file_ptr->ft_flags & TEMPORARY)) { if ((names[nfiles] = psp_truename(file_ptr->ft_name, 0)) == NULL) { while (nfiles) psp_freeMemory(names[--nfiles], 0); psp_zFreeMemory(&names, 0); goto ret_err; } /* file name compression - if the first n characters of this filename are the same as the first n characters of the last filename, they are not sent - they are replace by a single character (DB_TCHAR) with n in it (even if n is zero) */ if (nfiles == 0) count = 0; else count = cmpfiles(names[nfiles], names[nfiles - 1]); send_size += (vtstrlen(names[nfiles++]) + 2 - count) * sizeof(DB_TCHAR); } } if (send_size == 0) return (task->db_status = S_OKAY); /* nothing to do */ send_size += sizeof(LM_DBOPEN); send_size += WORDPAD(send_size); /* pad to word boundry */ /* TODO: send_size is unsigned short & will silently overflow/wrap * before exceeeding MAX_ALLOC which is a constant -sp */ if (send_size > MAX_ALLOC) { dberr(S_NOMEMORY); goto ret_err; } if ((send_pkt = (LM_DBOPEN *) psp_lmcAlloc(send_size)) == NULL) { dberr(S_NOMEMORY); goto ret_err; } send_pkt->nfiles = nfiles; send_pkt->type = (short)task->type[0]; tptr = send_pkt->fnames; for (ii = 0; ii < nfiles; ii++) { if (ii) { count = cmpfiles(names[ii], names[ii - 1]); psp_freeMemory(names[ii - 1], 0); } else count = 0; *tptr++ = (DB_TCHAR) count; vtstrcpy(tptr, names[ii] + count); tptr += vtstrlen(names[ii] + count) + 1; } psp_freeMemory(names[ii - 1], 0); psp_freeMemory(names, 0); msg_trans(L_DBOPEN, send_pkt, send_size, (void **) &recv_pkt, NULL, task); if (task->db_status != S_OKAY) { psp_lmcFree(send_pkt); goto ret_err; } excl_ptr = &task->excl_locks[task->old_size_ft]; fref_ptr = &task->file_refs[task->old_size_ft]; file_ptr = &task->file_table[task->old_size_ft]; rcv_fref_ptr = recv_pkt->frefs; for (ii = 0; ii < ft_lc; ii++, fref_ptr++, excl_ptr++) { if (!(file_ptr->ft_flags & TEMPORARY)) *fref_ptr = *rcv_fref_ptr++; else if (task->dbopen == 1) { *fref_ptr = (FILE_NO) -1; ++(*excl_ptr); } } psp_lmcFree(recv_pkt); if (opentype == FIRST_OPEN && task->db_timeout != DB_TIMEOUT) dtimeout(task->db_timeout, task); return task->db_status;ret_err: if (opentype == FIRST_OPEN) { int s1 = task->db_status; psp_lmcDisconnect(task->lmc); task->lmc = NULL; task->session_active = FALSE; task->db_status = s1; } return task->db_status;}/* ====================================================================== Build application file lock tables*/static int INTERNAL_FCN bld_lock_tables(DB_TASK *task){ register int fd_lc; /* loop control */ register int st_lc; /* loop control */ int *file_used; int rec; int mem, memtot; register FILE_NO i; FILE_NO fl_cnt; struct lock_descr *ld_ptr; RECORD_ENTRY *rec_ptr; FIELD_ENTRY *fld_ptr; SET_ENTRY *set_ptr; MEMBER_ENTRY *mem_ptr; register int *fu_ptr; FILE_NO *fl_ptr; unsigned new_size; unsigned old; int old_keyl_cnt; new_size = task->size_ft * sizeof(int); old = task->old_size_ft * sizeof(int); if (alloc_table((void **) &task->app_locks, new_size, old, task) != S_OKAY) return task->db_status; if (alloc_table((void **) &task->excl_locks, new_size, old, task) != S_OKAY) return task->db_status; if (alloc_table((void **) &task->kept_locks, new_size, old, task) != S_OKAY) return task->db_status; if ((file_used = psp_cGetMemory(new_size, 0)) == NULL) return (dberr(S_NOMEMORY)); new_size = task->size_rt * sizeof(struct lock_descr); old = task->old_size_rt * sizeof(struct lock_descr); if (alloc_table((void **) &task->rec_locks, new_size, old, task) != S_OKAY) return task->db_status; if (task->size_st) { new_size = task->size_st * sizeof(struct lock_descr); old = task->old_size_st * sizeof(struct lock_descr); if (alloc_table((void **) &task->set_locks, new_size, old, task) != S_OKAY) return task->db_status; } /* build task->rec_locks table */ for (rec = task->old_size_rt, rec_ptr = &task->record_table[task->old_size_rt], ld_ptr = &task->rec_locks[task->old_size_rt]; rec < task->size_rt; ++rec, ++rec_ptr, ++ld_ptr) { ld_ptr->fl_type = 'f'; ld_ptr->fl_prev = 'f'; /* [367] init to free */ ld_ptr->fl_kept = FALSE; /* put record's data file in list */ file_used[rec_ptr->rt_file] = TRUE; /* add any key files to list */ fl_cnt = 1; /* count of used files */ for ( fd_lc = task->size_fd - rec_ptr->rt_fields, fld_ptr = &task->field_table[rec_ptr->rt_fields]; (--fd_lc >= 0) && (fld_ptr->fd_rec == rec); ++fld_ptr) { if (fld_ptr->fd_key != NOKEY) { fu_ptr = &file_used[fld_ptr->fd_keyfile]; if (!*fu_ptr) { *fu_ptr = TRUE; ++fl_cnt; } } } ld_ptr->fl_cnt = fl_cnt; if (ld_ptr->fl_list) psp_freeMemory(ld_ptr->fl_list, 0); ld_ptr->fl_list = (FILE_NO *) psp_getMemory(fl_cnt * sizeof(FILE_NO), 0); if (ld_ptr->fl_list == NULL) return (dberr(S_NOMEMORY)); fl_ptr = ld_ptr->fl_list; for (i = 0, fu_ptr = file_used; i < task->size_ft; ++i, ++fu_ptr) { if (*fu_ptr) { *fu_ptr = FALSE; *fl_ptr++ = i; } } } /* build task->set_locks table */ if (task->size_st) { for (st_lc = task->size_st - task->old_size_st, set_ptr = &task->set_table[task->old_size_st], ld_ptr = &task->set_locks[task->old_size_st]; --st_lc >= 0; ++set_ptr, ++ld_ptr) { /* add owner's data file */ file_used[task->record_table[set_ptr->st_own_rt].rt_file] = TRUE; ld_ptr->fl_type = 'f'; ld_ptr->fl_prev = 'f'; /* [367] init to free */ ld_ptr->fl_kept = FALSE; /* add member record data files to list */ fl_cnt = 1; /* count of used files */ for ( mem = set_ptr->st_members, memtot = mem + set_ptr->st_memtot, mem_ptr = &task->member_table[mem]; mem < memtot; ++mem, ++mem_ptr) { fu_ptr = &file_used[task->record_table[mem_ptr->mt_record].rt_file]; if (!*fu_ptr) { *fu_ptr = TRUE; ++fl_cnt; } } ld_ptr->fl_cnt = fl_cnt; if (ld_ptr->fl_list) psp_freeMemory(ld_ptr->fl_list, 0); ld_ptr->fl_list = (FILE_NO *) psp_getMemory(fl_cnt * sizeof(FILE_NO), 0); if (ld_ptr->fl_list == NULL) return (dberr(S_NOMEMORY)); fl_ptr = ld_ptr->fl_list; for (i = 0, fu_ptr = file_used; i < task->size_ft; ++i, ++fu_ptr) { if (*fu_ptr) { *fu_ptr = FALSE; *fl_ptr++ = i; } } } } /* build task->key_locks table */ old_keyl_cnt = task->keyl_cnt; for ( fd_lc = task->size_fd - task->old_size_fd, fld_ptr = &task->field_table[task->old_size_fd]; --fd_lc >= 0; ++fld_ptr) { /* count number of keys */ if (fld_ptr->fd_key != NOKEY) ++task->keyl_cnt; } if (task->keyl_cnt > old_keyl_cnt) { new_size = task->keyl_cnt * sizeof(struct lock_descr); old = old_keyl_cnt * sizeof(struct lock_descr); if (alloc_table((void **) &task->key_locks, new_size, old, task) != S_OKAY) return task->db_status; for ( fd_lc = task->size_fd - task->old_size_fd, fld_ptr = &task->field_table[task->old_size_fd], ld_ptr = &task->key_locks[old_keyl_cnt]; --fd_lc >= 0; ++fld_ptr) { if (fld_ptr->fd_key != NOKEY) { ld_ptr->fl_type = 'f'; ld_ptr->fl_prev = 'f'; ld_ptr->fl_kept = FALSE; ld_ptr->fl_cnt = 1; if (ld_ptr->fl_list) psp_freeMemory(ld_ptr->fl_list, 0); ld_ptr->fl_list = (FILE_NO *) psp_getMemory(ld_ptr->fl_cnt * sizeof(FILE_NO), 0); if (ld_ptr->fl_list == NULL) return (dberr(S_NOMEMORY)); *(ld_ptr->fl_list) = fld_ptr->fd_keyfile; ++ld_ptr; } } } if (alloc_lfpkts(task) != S_OKAY) return (dberr(S_NOMEMORY)); psp_freeMemory(file_used, 0); return (task->db_status);}/* ====================================================================== Incrementally close database*/int INTERNAL_FCN diclose(DB_TASK *task, int dbn){ FILE_NO file; DB_ENTRY *db_ptr = NULL; if (dbn == CURR_DB) dbn = task->curr_db; if (! task->dbopen) return (task->db_status); if (!task->pgzero) dio_init(task); /* in case they forgot to end the transaction */ if (task->trans_id[0]) dtrabort(task); else dio_flush(task); /* flush any x-locked files */ /* release any non x-locks and clear the cache */ free_dblocks(dbn, task); /* free locks first so they get cleared */ dio_clear(dbn, task); dio_ixclear(task); if (task->no_of_dbs == 1) dbn = ALL_DBS; if (dbn >= 0) db_ptr = &task->db_table[dbn]; /* close all files */ for ( file = (FILE_NO) ((dbn == ALL_DBS) ? 0 : db_ptr->ft_offset); file < ((dbn == ALL_DBS) ? task->size_ft : db_ptr->Size_ft + db_ptr->ft_offset); ++file) dio_close(file, task); dio_close(task->ov_file, task); key_close(dbn, task); dio_free(dbn, task); /* must be before o_free() due to task->ov_file reference */ o_free(dbn, task); if (task->db_lockmgr) termses(dbn, task); termfree(dbn, task); /* A d_setkey/d_makenew sequence cannot encompass a d_close */ sk_free(task); if (dbn == ALL_DBS) { /* free the country table */ if (task->ctbl_activ) ctbl_free(task); /* logout of taf before resetting task->db_lockmgr and task->dbopen */ if (!(task->dboptions & NORECOVER) && (taf_logout(task) != S_OKAY)) taf_close(task); if (task->dboptions & DELETELOG) { psp_fileRemove(task->dblog); if (psp_errno() == EACCES) return (dberr(S_EACCESS)); } task->cr_time = 0; task->curr_db = VOID_DB; task->set_db = VOID_DB;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -