int nisam_log(int activate_log) { int error=0; char buff[FN_REFLEN]; DBUG_ENTER("nisam_log"); log_type=activate_log; if (activate_log) { if (nisam_log_file < 0) { if ((nisam_log_file = my_create(fn_format(buff,nisam_log_filename, "",".log",4), 0,(O_RDWR | O_BINARY | O_APPEND),MYF(0))) < 0) DBUG_RETURN(1); } } else if (nisam_log_file >= 0) { error=my_close(nisam_log_file,MYF(0)); nisam_log_file= -1; } DBUG_RETURN(error); }
void rename_test(){ int fd; show_file_list(); char filename[40]; char changename[40]; printf("\n"); if(my_rename("/usr/data/data1/file1", "/usr/data/data1/file1_1") != OK){ printf("rename error!!\n"); return; } show_file_list(); printf("\n"); if(my_mkdir("usr/data/manyfile") != OK){ printf("mkdir error!!\n"); return; } show_file_list(); printf("\n"); int i = 35; memset(filename, 0, 40); memset(changename, 0, 40); strcpy(filename, "usr/data/manyfile/file"); strcpy(changename, "usr/data/manyfile/file"); int length = strlen(filename); for(; i < 65; ++i){ filename[length] = (char)i; if(fd = my_create(filename) < 0){ my_close(fd); printf("create file error when i = %d\n", i); return; } my_close(fd); } show_file_list(); printf("\n"); /* int i = 30; */ /* changename[length] = (char)70; */ /* printf("changename is %s, length is %d\n",changename, length); */ /* printf("filename is %s, length is %d\n",filename, length); */ /* exit(0); */ for( i = 35; i < 65; ++i){ filename[length] = (char)i; changename[length] = (char)(100 - i); if(my_rename(filename, changename) != OK){ printf("rename error when i = %d!!\n", i); return; } } show_file_list(); printf("\n"); }
/* hard links are also tested a bunch in test_rename */ void test_link(char *workdir) { char file1[1024], file2[1024], file3[1024]; struct stat sb; printf("Testing link\n"); sprintf(file1, "%s/original", workdir); sprintf(file2, "%s/link", workdir); my_create(file1); my_stat(file1, &sb); my_link(file1, file2); verify_inum(file2, &sb); my_unlink(file2); verify_inum(file1, &sb); /* Test deletion of the original file after a hard link has been created */ my_link(file1, file2); my_unlink(file1); verify_inum(file2, &sb); /* Make sure the original file really isn't accessible */ verify_no_exist(file1); my_unlink(file2); verify_no_exist(file2); /* Try renaming a hard link */ my_create(file1); my_stat(file1, &sb); my_link(file1, file2); sprintf(file3, "%s/file3", workdir); my_rename(file2, file3); verify_inum(file3, &sb); verify_no_exist(file2); my_unlink(file3); verify_no_exist(file3); my_unlink(file1); }
int myrg_create(const char *name, const char **table_names, uint insert_method, my_bool fix_names) { int save_errno; uint errpos; File file; char buff[FN_REFLEN],*end; DBUG_ENTER("myrg_create"); errpos=0; if ((file = my_create(fn_format(buff,name,"",MYRG_NAME_EXT,4),0, O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) goto err; errpos=1; if (table_names) { for ( ; *table_names ; table_names++) { strmov(buff,*table_names); if (fix_names) fn_same(buff,name,4); *(end=strend(buff))='\n'; end[1]=0; if (my_write(file,buff,(uint) (end-buff+1), MYF(MY_WME | MY_NABP))) goto err; } } if (insert_method != MERGE_INSERT_DISABLED) { end=strxmov(buff,"#INSERT_METHOD=", get_type(&merge_insert_method,insert_method-1),"\n",NullS); if (my_write(file,buff,(uint) (end-buff),MYF(MY_WME | MY_NABP))) goto err; } if (my_close(file,MYF(0))) goto err; DBUG_RETURN(0); err: save_errno=my_errno ? my_errno : -1; switch (errpos) { case 1: VOID(my_close(file,MYF(0))); } DBUG_RETURN(my_errno=save_errno); } /* myrg_create */
void file_test(){ my_mkdir("usr/data"); show_file_list(); printf("\n"); my_mkdir("src"); my_mkdir("../usr/./data/data1"); show_file_list(); printf("\n"); int fd; fd = my_create("usr/.././usr/data/.././data/data1/file1"); show_file_list(); my_close(fd); fd = my_open("usr/.././usr/data/.././data/data1/file1"); my_close(fd); show_file_list(); }
int mrg_create(const char *name, const char**table_names) { int save_errno; uint errpos; File file; char buff[FN_REFLEN],*end; DBUG_ENTER("mrg_create"); errpos=0; if ((file = my_create(fn_format(buff,name,"",MRG_NAME_EXT,4),0, O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) goto err; errpos=1; if (table_names) for ( ; *table_names ; table_names++) { strmov(buff,*table_names); fn_same(buff,name,4); *(end=strend(buff))='\n'; if (my_write(file,*table_names,(uint) (end-buff+1), MYF(MY_WME | MY_NABP))) goto err; } if (my_close(file,MYF(0))) goto err; DBUG_RETURN(0); err: save_errno=my_errno; switch (errpos) { case 1: VOID(my_close(file,MYF(0))); } my_errno=save_errno; /* Return right errocode */ DBUG_RETURN(-1); } /* mrg_create */
File my_create_with_symlink(const char *linkname, const char *filename, int createflags, int access_flags, myf MyFlags) { File file; int tmp_errno; /* Test if we should create a link */ int create_link; char abs_linkname[FN_REFLEN]; DBUG_ENTER("my_create_with_symlink"); DBUG_PRINT("enter", ("linkname: %s filename: %s", linkname ? linkname : "(null)", filename ? filename : "(null)")); if (my_disable_symlinks) { DBUG_PRINT("info", ("Symlinks disabled")); /* Create only the file, not the link and file */ create_link= 0; if (linkname) filename= linkname; } else { if (linkname) my_realpath(abs_linkname, linkname, MYF(0)); create_link= (linkname && strcmp(abs_linkname,filename)); } if (!(MyFlags & MY_DELETE_OLD)) { if (!access(filename,F_OK)) { my_errno= errno= EEXIST; my_error(EE_CANTCREATEFILE, MYF(0), filename, EEXIST); DBUG_RETURN(-1); } if (create_link && !access(linkname,F_OK)) { my_errno= errno= EEXIST; my_error(EE_CANTCREATEFILE, MYF(0), linkname, EEXIST); DBUG_RETURN(-1); } } if ((file=my_create(filename, createflags, access_flags, MyFlags)) >= 0) { if (create_link) { /* Delete old link/file */ if (MyFlags & MY_DELETE_OLD) my_delete(linkname, MYF(0)); /* Create link */ if (my_symlink(filename, linkname, MyFlags)) { /* Fail, remove everything we have done */ tmp_errno=my_errno; my_close(file,MYF(0)); my_delete(filename, MYF(0)); file= -1; my_errno=tmp_errno; } } } DBUG_RETURN(file); }
File create_temp_file(char *to, const char *dir, const char *prefix, int mode __attribute__((unused)), myf MyFlags __attribute__((unused))) { File file= -1; #ifdef __WIN__ TCHAR path_buf[MAX_PATH-14]; #endif DBUG_ENTER("create_temp_file"); DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix)); #if defined (__WIN__) /* Use GetTempPath to determine path for temporary files. This is because the documentation for GetTempFileName has the following to say about this parameter: "If this parameter is NULL, the function fails." */ if (!dir) { if (GetTempPath(sizeof(path_buf), path_buf) > 0) dir = path_buf; } /* Use GetTempFileName to generate a unique filename, create the file and release it's handle - uses up to the first three letters from prefix */ if (GetTempFileName(dir, prefix, 0, to) == 0) DBUG_RETURN(-1); DBUG_PRINT("info", ("name: %s", to)); /* Open the file without the "open only if file doesn't already exist" since the file has already been created by GetTempFileName */ if ((file= my_open(to, (mode & ~O_EXCL), MyFlags)) < 0) { /* Open failed, remove the file created by GetTempFileName */ int tmp= my_errno; (void) my_delete(to, MYF(0)); my_errno= tmp; } #elif defined(HAVE_MKSTEMP) { char prefix_buff[30]; uint pfx_len; File org_file; pfx_len= (uint) (strmov(strnmov(prefix_buff, prefix ? prefix : "tmp.", sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff); if (!dir && ! (dir =getenv("TMPDIR"))) dir=P_tmpdir; if (strlen(dir)+ pfx_len > FN_REFLEN-2) { errno=my_errno= ENAMETOOLONG; DBUG_RETURN(file); } strmov(convert_dirname(to,dir,NullS),prefix_buff); org_file=mkstemp(to); if (mode & O_TEMPORARY) (void) my_delete(to, MYF(MY_WME | ME_NOINPUT)); file=my_register_filename(org_file, to, FILE_BY_MKSTEMP, EE_CANTCREATEFILE, MyFlags); /* If we didn't manage to register the name, remove the temp file */ if (org_file >= 0 && file < 0) { int tmp=my_errno; close(org_file); (void) my_delete(to, MYF(MY_WME | ME_NOINPUT)); my_errno=tmp; } } #elif defined(HAVE_TEMPNAM) { extern char **environ; char *res,**old_env,*temp_env[1]; if (dir && !dir[0]) { /* Change empty string to current dir */ to[0]= FN_CURLIB; to[1]= 0; dir=to; } old_env= (char**) environ; if (dir) { /* Don't use TMPDIR if dir is given */ environ=(const char**) temp_env; temp_env[0]=0; } if ((res=tempnam((char*) dir, (char*) prefix))) { strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to,0, (int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW | O_TEMPORARY | O_SHORT_LIVED), MYF(MY_WME)); } else { DBUG_PRINT("error",("Got error: %d from tempnam",errno)); } environ=(const char**) old_env; } #else #error No implementation found for create_temp_file #endif if (file >= 0) thread_safe_increment(my_tmp_file_created,&THR_LOCK_open); DBUG_RETURN(file); }
int my_copy(const char *from, const char *to, myf MyFlags) { size_t Count; my_bool new_file_stat= 0; /* 1 if we could stat "to" */ int create_flag; File from_file,to_file; uchar buff[IO_SIZE]; MY_STAT stat_buff,new_stat_buff; gid_t gid; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); from_file=to_file= -1; DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */ if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */ new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0))); if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0) { if (!my_stat(from, &stat_buff, MyFlags)) { my_errno=errno; goto err; } if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat) stat_buff=new_stat_buff; create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC; if ((to_file= my_create(to,(int) stat_buff.st_mode, O_WRONLY | create_flag | O_BINARY | O_SHARE, MyFlags)) < 0) goto err; while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0) { if (Count == (uint) -1 || my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; } /* sync the destination file */ if (MyFlags & MY_SYNC) { if (my_sync(to_file, MyFlags)) goto err; } if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ /* Copy modes if possible */ if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat) DBUG_RETURN(0); /* File copyed but not stat */ #if !defined(__WIN__) && !defined(__NETWARE__) /* Refresh the new_stat_buff */ if (!my_stat((char*) to, &new_stat_buff, MYF(0))) { my_errno= errno; goto err; } /* Copy modes */ if ((stat_buff.st_mode & 07777) != (new_stat_buff.st_mode & 07777) && chmod(to, stat_buff.st_mode & 07777)) { my_errno= errno; if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from, errno); goto err; } /* Copy ownership */ if (stat_buff.st_gid == new_stat_buff.st_gid) gid= -1; else gid= stat_buff.st_gid; if ((gid != (gid_t) -1 || stat_buff.st_uid != new_stat_buff.st_uid) && chown(to, stat_buff.st_uid, gid)) { my_errno= errno; if (MyFlags & (MY_FAE+MY_WME)) my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from, errno); goto err; } #endif #if !defined(VMS) && !defined(__ZTC__) if (MyFlags & MY_COPYTIME) { struct utimbuf timep; timep.actime = stat_buff.st_atime; timep.modtime = stat_buff.st_mtime; VOID(utime((char*) to, &timep)); /* last accessed and modified times */ } #endif DBUG_RETURN(0); } err: if (from_file >= 0) VOID(my_close(from_file,MyFlags)); if (to_file >= 0) { VOID(my_close(to_file, MyFlags)); /* attempt to delete the to-file we've partially written */ VOID(my_delete(to, MyFlags)); } DBUG_RETURN(-1); } /* my_copy */
int my_copy(const char *from, const char *to, myf MyFlags) { uint Count; int new_file_stat; File from_file,to_file; char buff[IO_SIZE]; struct stat stat_buff,new_stat_buff; DBUG_ENTER("my_copy"); DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags)); from_file=to_file= -1; new_file_stat=0; if (MyFlags & MY_HOLD_ORIGINAL_MODES) /* Copy stat if possible */ new_file_stat=stat((char*) to, &new_stat_buff); if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0) { if (stat(from,&stat_buff)) { my_errno=errno; goto err; } if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat) stat_buff=new_stat_buff; if ((to_file= my_create(to,(int) stat_buff.st_mode, O_WRONLY | O_TRUNC | O_BINARY | O_SHARE, MyFlags)) < 0) goto err; while ((Count=my_read(from_file,buff,IO_SIZE,MyFlags)) != 0) if (Count == (uint) -1 || my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP))) goto err; if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags)) DBUG_RETURN(-1); /* Error on close */ /* Copy modes if possible */ if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat) DBUG_RETURN(0); /* File copyed but not stat */ VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */ #if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) VOID(chown(to, stat_buff.st_uid,stat_buff.st_gid)); /* Copy ownership */ #endif #if !defined(VMS) && !defined(__ZTC__) if (MyFlags & MY_COPYTIME) { struct utimbuf timep; timep.actime = stat_buff.st_atime; timep.modtime = stat_buff.st_mtime; VOID(utime((char*) to, &timep)); /* last accessed and modified times */ } #endif DBUG_RETURN(0); } err: if (from_file >= 0) VOID(my_close(from_file,MyFlags)); if (to_file >= 0) VOID(my_close(to_file,MyFlags)); DBUG_RETURN(-1); } /* my_copy */
File create_temp_file(char *to, const char *dir, const char *prefix, int mode __attribute__((unused)), myf MyFlags __attribute__((unused))) { File file= -1; DBUG_ENTER("create_temp_file"); #if defined(_MSC_VER) { char temp[FN_REFLEN],*end,*res,**old_env,*temp_env[1]; old_env=environ; if (dir) { end=strend(dir)-1; if (!dir[0]) { /* Change empty string to current dir */ to[0]= FN_CURLIB; to[1]= 0; dir=to; } else if (*end == FN_DEVCHAR) { /* Get current dir for drive */ _fullpath(temp,dir,FN_REFLEN); dir=to; } else if (*end == FN_LIBCHAR && dir < end && end[-1] != FN_DEVCHAR) { strmake(to,dir,(uint) (end-dir)); /* Copy and remove last '\' */ dir=to; } environ=temp_env; /* Force use of dir (dir not checked) */ temp_env[0]=0; } if ((res=tempnam((char*) dir,(char *) prefix))) { strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to,0, mode, MyFlags); } environ=old_env; } #elif defined(_ZTC__) if (!dir) dir=getenv("TMPDIR"); if ((res=tempnam((char*) dir,(char *) prefix))) { strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to, 0, mode, MyFlags); } #elif defined(HAVE_MKSTEMP) { char prefix_buff[30]; uint pfx_len; File org_file; pfx_len=(strmov(strnmov(prefix_buff, prefix ? prefix : "tmp.", sizeof(prefix_buff)-7),"XXXXXX") - prefix_buff); if (!dir && ! (dir =getenv("TMPDIR"))) dir=P_tmpdir; if (strlen(dir)+ pfx_len > FN_REFLEN-2) { errno=my_errno= ENAMETOOLONG; return 1; } strmov(to,dir); strmov(convert_dirname(to),prefix_buff); org_file=mkstemp(to); file=my_register_filename(org_file, to, FILE_BY_MKSTEMP, EE_CANTCREATEFILE, MyFlags); /* If we didn't manage to register the name, remove the temp file */ if (org_file >= 0 && file < 0) { int tmp=my_errno; (void) my_delete(to, MYF(MY_WME | ME_NOINPUT)); my_errno=tmp; } } #elif defined(HAVE_TEMPNAM) { char *res,**old_env,*temp_env[1]; if (dir && !dir[0]) { /* Change empty string to current dir */ to[0]= FN_CURLIB; to[1]= 0; dir=to; } #ifdef OS2 // changing environ variable doesn't work with VACPP char buffer[256]; sprintf( buffer, "TMP=%s", dir); // remove ending backslash if (buffer[strlen(buffer)-1] == '\\') buffer[strlen(buffer)-1] = '\0'; putenv( buffer); #else old_env= (char**) environ; if (dir) { /* Don't use TMPDIR if dir is given */ environ=(const char**) temp_env; temp_env[0]=0; } #endif if ((res=tempnam((char*) dir, (char*) prefix))) { strmake(to,res,FN_REFLEN-1); (*free)(res); file=my_create(to,0, (int) (O_RDWR | O_BINARY | O_TRUNC | O_TEMPORARY | O_SHORT_LIVED), MYF(MY_WME)); } else { DBUG_PRINT("error",("Got error: %d from tempnam",errno)); } #ifndef OS2 environ=(const char**) old_env; #endif } #else { register long uniq; register int length; my_string pos,end_pos; /* Make an unique number */ pthread_mutex_lock(&THR_LOCK_open); uniq= ((long) getpid() << 20) + (long) _my_tempnam_used++ ; pthread_mutex_unlock(&THR_LOCK_open); if (!dir && !(dir=getenv("TMPDIR"))) /* Use this if possibly */ dir=P_tmpdir; /* Use system default */ length=strlen(dir)+strlen(pfx)+1; DBUG_PRINT("test",("mallocing %d byte",length+8+sizeof(TMP_EXT)+1)); if (length+8+sizeof(TMP_EXT)+1 > FN_REFLENGTH) errno=my_errno= ENAMETOOLONG; else { end_pos=strmov(to,dir); if (end_pos != to && end_pos[-1] != FN_LIBCHAR) *end_pos++=FN_LIBCHAR; end_pos=strmov(end_pos,pfx); for (length=0 ; length < 8 && uniq ; length++) { *end_pos++= _dig_vec[(int) (uniq & 31)]; uniq >>= 5; } (void) strmov(end_pos,TMP_EXT); file=my_create(to,0, (int) (O_RDWR | O_BINARY | O_TRUNC | O_TEMPORARY | O_SHORT_LIVED), MYF(MY_WME)); } } #endif if (file >= 0) thread_safe_increment(my_tmp_file_created,&THR_LOCK_open); DBUG_RETURN(file); }
int main(int argc, char **argv) { gcry_error_t gcry_error; File filein = 0; File fileout = 0; MY_INIT(argv[0]); if (get_options(&argc, &argv)) { goto err; } /* Acording to gcrypt docs (and my testing), setting up the threading callbacks must be done first, so, lets give it a shot */ gcry_error = gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); if (gcry_error) { msg("%s: unable to set libgcrypt thread cbs - " "%s : %s\n", my_progname, gcry_strsource(gcry_error), gcry_strerror(gcry_error)); return 1; } /* Version check should be the very first call because it makes sure that important subsystems are intialized. */ if (!gcry_control(GCRYCTL_ANY_INITIALIZATION_P)) { const char *gcrypt_version; gcrypt_version = gcry_check_version(NULL); /* No other library has already initialized libgcrypt. */ if (!gcrypt_version) { msg("%s: failed to initialize libgcrypt\n", my_progname); return 1; } else if (opt_verbose) { msg("%s: using gcrypt %s\n", my_progname, gcrypt_version); } } gcry_control(GCRYCTL_DISABLE_SECMEM, 0); gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0); /* Determine the algorithm */ encrypt_algo = encrypt_algos[opt_encrypt_algo]; /* Set up the iv length */ encrypt_iv_len = gcry_cipher_get_algo_blklen(encrypt_algo); /* Now set up the key */ if (opt_encrypt_key == NULL && opt_encrypt_key_file == NULL) { msg("%s: no encryption key or key file specified.\n", my_progname); return 1; } else if (opt_encrypt_key && opt_encrypt_key_file) { msg("%s: both encryption key and key file specified.\n", my_progname); return 1; } else if (opt_encrypt_key_file) { if (!xb_crypt_read_key_file(opt_encrypt_key_file, &opt_encrypt_key, &encrypt_key_len)) { msg("%s: unable to read encryption key file \"%s\".\n", opt_encrypt_key_file, my_progname); return 1; } } else { encrypt_key_len = strlen(opt_encrypt_key); } if (opt_input_file) { MY_STAT mystat; if (opt_verbose) msg("%s: input file \"%s\".\n", my_progname, opt_input_file); if (my_stat(opt_input_file, &mystat, MYF(MY_WME)) == NULL) { goto err; } if (!MY_S_ISREG(mystat.st_mode)) { msg("%s: \"%s\" is not a regular file, exiting.\n", my_progname, opt_input_file); goto err; } if ((filein = my_open(opt_input_file, O_RDONLY, MYF(MY_WME))) < 0) { msg("%s: failed to open \"%s\".\n", my_progname, opt_input_file); goto err; } } else { if (opt_verbose) msg("%s: input from standard input.\n", my_progname); filein = fileno(stdin); } if (opt_output_file) { if (opt_verbose) msg("%s: output file \"%s\".\n", my_progname, opt_output_file); if ((fileout = my_create(opt_output_file, 0, O_WRONLY|O_BINARY|O_EXCL|O_NOFOLLOW, MYF(MY_WME))) < 0) { msg("%s: failed to create output file \"%s\".\n", my_progname, opt_output_file); goto err; } } else { if (opt_verbose) msg("%s: output to standard output.\n", my_progname); fileout = fileno(stdout); } if (opt_run_mode == RUN_MODE_DECRYPT && mode_decrypt(filein, fileout)) { goto err; } else if (opt_run_mode == RUN_MODE_ENCRYPT && mode_encrypt(filein, fileout)) { goto err; } if (opt_input_file && filein) { my_close(filein, MYF(MY_WME)); } if (opt_output_file && fileout) { my_close(fileout, MYF(MY_WME)); } my_cleanup_options(my_long_options); my_end(0); return EXIT_SUCCESS; err: if (opt_input_file && filein) { my_close(filein, MYF(MY_WME)); } if (opt_output_file && fileout) { my_close(fileout, MYF(MY_WME)); } my_cleanup_options(my_long_options); my_end(0); exit(EXIT_FAILURE); }
int nisam_create(const char *name,uint keys,N_KEYDEF *keyinfo, N_RECINFO *recinfo, ulong records,ulong reloc, uint flags,uint old_options, ulong data_file_length) { register uint i,j; File dfile,file; int errpos,save_errno; uint fields,length,max_key_length,packed,pointer,reclength,min_pack_length, key_length,info_length,key_segs,options,min_key_length_skipp,max_block, base_pos; char buff[max(FN_REFLEN,512)]; ulong tot_length,pack_reclength; enum en_fieldtype type; ISAM_SHARE share; N_KEYDEF *keydef; N_KEYSEG *keyseg; N_RECINFO *rec; DBUG_ENTER("nisam_create"); LINT_INIT(dfile); pthread_mutex_lock(&THR_LOCK_isam); errpos=0; options=0; base_pos=512; /* Enough for N_STATE_INFO */ bzero((byte*) &share,sizeof(share)); if ((file = my_create(fn_format(buff,name,"",N_NAME_IEXT,4),0, O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) goto err; errpos=1; VOID(fn_format(buff,name,"",N_NAME_DEXT,2+4)); if (!(flags & HA_DONT_TOUCH_DATA)) { if ((dfile = my_create(buff,0,O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) goto err; errpos=2; } else if (!(old_options & HA_OPTION_TEMP_COMPRESS_RECORD)) options=old_options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA | HA_OPTION_PACK_RECORD); if (reloc > records) reloc=records; /* Check if wrong parameter */ /* Start by checking fields and field-types used */ reclength=0; for (rec=recinfo, fields=packed=min_pack_length=0, pack_reclength=0L; rec->base.type != (int) FIELD_LAST; rec++,fields++) { reclength+=rec->base.length; if ((type=(enum en_fieldtype) rec->base.type)) { packed++; if (type == FIELD_BLOB) { share.base.blobs++; rec->base.length-= sizeof(char*); /* Don't calc pointer */ if (pack_reclength != NI_POS_ERROR) { if (rec->base.length == 4) pack_reclength= (ulong) NI_POS_ERROR; else pack_reclength+=sizeof(char*)+(1 << (rec->base.length*8)); } } else if (type == FIELD_SKIP_PRESPACE || type == FIELD_SKIP_ENDSPACE) { if (pack_reclength != NI_POS_ERROR) pack_reclength+= rec->base.length > 255 ? 2 : 1; min_pack_length++; } else if (type == FIELD_ZERO) packed--; else if (type != FIELD_SKIP_ZERO) { min_pack_length+=rec->base.length; packed--; /* Not a pack record type */ } } else min_pack_length+=rec->base.length; } if ((packed & 7) == 1) { /* Bad packing, try to remove a zero-field */ while (rec != recinfo) { rec--; if (rec->base.type == (int) FIELD_SKIP_ZERO && rec->base.length == 1) { rec->base.type=(int) FIELD_NORMAL; packed--; min_pack_length++; break; } } } if (packed && !(options & HA_OPTION_COMPRESS_RECORD)) options|=HA_OPTION_PACK_RECORD; /* Must use packed records */ packed=(packed+7)/8; if (pack_reclength != NI_POS_ERROR) pack_reclength+= reclength+packed; min_pack_length+=packed; if (options & HA_OPTION_COMPRESS_RECORD) { if (data_file_length >= (1L << 24)) pointer=4; else if (data_file_length >= (1L << 16)) pointer=3; else pointer=2; } else if (((records == 0L && pack_reclength < 255) || options & HA_OPTION_PACK_RECORD) || records >= (ulong) 16000000L || pack_reclength == (ulong) NI_POS_ERROR || ((options & HA_OPTION_PACK_RECORD) && pack_reclength+4 >= (ulong) 14000000L/records)) pointer=4; else if (records == 0L || records >= (ulong) 65000L || ((options & HA_OPTION_PACK_RECORD) && pack_reclength+4 >= (ulong) 60000L/records)) pointer=3; else pointer=2; max_block=max_key_length=0; tot_length=key_segs=0; for (i=0, keydef=keyinfo ; i < keys ; i++ , keydef++) { share.state.key_root[i]= share.state.key_del[i]= NI_POS_ERROR; share.base.rec_per_key[i]= (keydef->base.flag & HA_NOSAME) ? 1L : 0L; min_key_length_skipp=length=0; key_length=pointer; if (keydef->base.flag & HA_PACK_KEY && keydef->seg[0].base.length > 127) keydef->base.flag&= ~HA_PACK_KEY; /* Can't pack long keys */ if (keydef->base.flag & HA_PACK_KEY) { if ((keydef->seg[0].base.flag & HA_SPACE_PACK) && keydef->seg[0].base.type == (int) HA_KEYTYPE_NUM) keydef->seg[0].base.flag&= ~HA_SPACE_PACK; if (!(keydef->seg[0].base.flag & HA_SPACE_PACK)) length++; keydef->seg[0].base.flag|=HA_PACK_KEY; /* for easyer intern test */ options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ if (!(keydef->seg[0].base.flag & HA_SPACE_PACK)) min_key_length_skipp+=keydef->seg[0].base.length; } keydef->base.keysegs=0; for (keyseg=keydef->seg ; keyseg->base.type ; keyseg++) { keydef->base.keysegs++; if (keyseg->base.length > 127) keyseg->base.flag&= ~(HA_SPACE_PACK | HA_PACK_KEY); if (keyseg->base.flag & HA_SPACE_PACK) { keydef->base.flag |= HA_SPACE_PACK_USED; options|=HA_OPTION_PACK_KEYS; /* Using packed keys */ length++; min_key_length_skipp+=keyseg->base.length; } key_length+= keyseg->base.length; } bzero((gptr) keyseg,sizeof(keyseg[0])); keyseg->base.length=(uint16) pointer; /* Last key part is pointer */ key_segs+=keydef->base.keysegs; length+=key_length; keydef->base.block_length=nisam_block_size; keydef->base.keylength= (uint16) key_length; keydef->base.minlength= (uint16) (length-min_key_length_skipp); keydef->base.maxlength= (uint16) length; if ((uint) keydef->base.block_length > max_block) max_block=(uint) keydef->base.block_length; if (length > max_key_length) max_key_length= length; tot_length+= (records/(ulong) (((uint) keydef->base.block_length-5)/ (length*2)))* (ulong) keydef->base.block_length; } info_length=(uint) (base_pos+sizeof(N_BASE_INFO)+keys*sizeof(N_SAVE_KEYDEF)+ (keys+key_segs)*sizeof(N_SAVE_KEYSEG)+ fields*sizeof(N_SAVE_RECINFO)); bmove(share.state.header.file_version,(byte*) nisam_file_magic,4); old_options=options| (old_options & HA_OPTION_TEMP_COMPRESS_RECORD ? HA_OPTION_COMPRESS_RECORD | HA_OPTION_TEMP_COMPRESS_RECORD: 0); int2store(share.state.header.options,old_options); int2store(share.state.header.header_length,info_length); int2store(share.state.header.state_info_length,sizeof(N_STATE_INFO)); int2store(share.state.header.base_info_length,sizeof(N_BASE_INFO)); int2store(share.state.header.base_pos,base_pos); share.state.dellink = NI_POS_ERROR; share.state.process= (ulong) getpid(); share.state.uniq= (ulong) file; share.state.loop= 0; share.state.version= (ulong) time((time_t*) 0); share.base.options=options; share.base.rec_reflength=pointer; share.base.key_reflength=((!tot_length || tot_length > 30000000L) ? 3 : tot_length > 120000L ? 2 : 1); share.base.keys= share.state.keys = keys; share.base.keystart = share.state.key_file_length=MY_ALIGN(info_length, nisam_block_size); share.base.max_block=max_block; share.base.max_key_length=(uint) ALIGN_SIZE(max_key_length+4); share.base.records=records; share.base.reloc=reloc; share.base.reclength=reclength; share.base.pack_reclength= (uint) (reclength+packed-share.base.blobs*sizeof(char*)); share.base.max_pack_length=pack_reclength; share.base.min_pack_length=min_pack_length; share.base.pack_bits=packed; share.base.fields=fields; share.base.pack_fields=packed; share.base.sortkey= (ushort) ~0; share.base.max_data_file_length= (pointer == 4) ? (ulong) ~0L : (options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? (ulong) (1L << (pointer*8)) : (pointer == 3 && reclength >= 256L) ? (ulong) NI_POS_ERROR : ((ulong) reclength * (1L << (pointer*8))); share.base.max_key_file_length= (share.base.key_reflength == 3 ? NI_POS_ERROR : (ulong) (1L << (share.base.key_reflength*8))*512); share.base.min_block_length= (share.base.pack_reclength+3 < N_EXTEND_BLOCK_LENGTH && ! share.base.blobs) ? max(share.base.pack_reclength,N_MIN_BLOCK_LENGTH) : N_EXTEND_BLOCK_LENGTH; if (! (flags & HA_DONT_TOUCH_DATA)) share.base.create_time= (long) time((time_t*) 0); bzero(buff,base_pos); if (my_write(file,(char*) &share.state,sizeof(N_STATE_INFO),MYF(MY_NABP)) || my_write(file,buff,base_pos-sizeof(N_STATE_INFO),MYF(MY_NABP)) || my_write(file,(char*) &share.base,sizeof(N_BASE_INFO),MYF(MY_NABP))) goto err; for (i=0 ; i < share.base.keys ; i++) { if (my_write(file,(char*) &keyinfo[i].base,sizeof(N_SAVE_KEYDEF), MYF(MY_NABP))) goto err; for (j=0 ; j <= keyinfo[i].base.keysegs ; j++) { if (my_write(file,(char*) &keyinfo[i].seg[j].base,sizeof(N_SAVE_KEYSEG), MYF(MY_NABP))) goto err; } } for (i=0 ; i < share.base.fields ; i++) if (my_write(file,(char*) &recinfo[i].base, (uint) sizeof(N_SAVE_RECINFO), MYF(MY_NABP))) goto err; /* Enlarge files */ if (my_chsize(file, (ulong) share.base.keystart, 0, MYF(0))) goto err; if (! (flags & HA_DONT_TOUCH_DATA)) { #ifdef USE_RELOC if (my_chsize(dfile, share.base.min_pack_length*reloc, 0, MYF(0))) goto err; #endif errpos=1; if (my_close(dfile,MYF(0))) goto err; } errpos=0; pthread_mutex_unlock(&THR_LOCK_isam); if (my_close(file,MYF(0))) goto err; DBUG_RETURN(0); err: pthread_mutex_unlock(&THR_LOCK_isam); save_errno=my_errno; switch (errpos) { case 2: VOID(my_close(dfile,MYF(0))); /* fall through */ case 1: VOID(my_close(file,MYF(0))); } my_errno=save_errno; /* R{tt felkod tillbaka */ DBUG_RETURN(-1); } /* nisam_create */