📄 environ.c
字号:
if(name[1]==PATHSEP_DEFAULT||name[1]==PATHSEP_UNIX) name++; /* ".\" relative path */ } if(name[0]==PATHSEP_DEFAULT||name[0]==PATHSEP_UNIX) name++; /* "\" - revert to root */#if SFX_LEVEL>=ARJSFXV } }#endif return(name);}#endif/* Convert the extended finddata record to OS-independent internal storage format */#if SFX_LEVEL>=ARJstatic void finddata_to_properties(struct file_properties *properties, struct new_ffblk *new_ffblk){ #if TARGET==UNIX int u; #endif properties->ftime=new_ffblk->ff_ftime; properties->atime=new_ffblk->ff_atime; properties->ctime=new_ffblk->ff_ctime; properties->fsize=new_ffblk->ff_fsize; properties->attrib=(ATTRIB)new_ffblk->ff_attrib; #if TARGET!=UNIX properties->type=(new_ffblk->ff_attrib&FATTR_DIREC)?ARJT_DIR:ARJT_BINARY; properties->isarchive=(new_ffblk->ff_attrib&FATTR_ARCH)?1:0; #else u=uftype(new_ffblk->ff_attrib); if(u&FATTR_DT_DIR) properties->type=ARJT_DIR; else if(u&FATTR_DT_UXSPECIAL) properties->type=ARJT_UXSPECIAL; else properties->type=ARJT_BINARY; /* Can't check fot non-DT_REG since these may be requested by find_file() */ properties->isarchive=1; /* Hardlink data */ properties->l_search=new_ffblk->l_search; properties->l_search.ref=0; properties->islink=0; #endif}#endif/* Return pointer to the first path delimiter in given string, or NULL if nothing found */#if SFX_LEVEL>=ARJSFXstatic char *find_delimiter(char *path, int datatype){ if(path[0]=='\0') return(NULL); while(path[0]!='\0') { if(path[0]==PATHSEP_DEFAULT||path[0]==PATHSEP_UNIX) return(path); path++; } if(datatype==ARJT_DIR) return(path); else return(NULL);}#endif/* * Secondary-level file management routines. Usually they must either be * redirected to Win95 LFN API, or serviced with the C RTL functions. *//* chmod() - Borland's implementation */#if SFX_LEVEL>=ARJSFX||defined(REARJ)int file_chmod(char *name, int action, int attrs){ #if TARGET==DOS if(lfn_supported!=LFN_NOT_SUPPORTED) return(w95_chmod(name, action, attrs)); else #if COMPILER==BCC return(_chmod(name, action, attrs)); #elif COMPILER==MSC { int rc; if(action) return(_dos_setfileattr(name, attrs)); else { rc=-1; _dos_getfileattr(name, &rc); return(rc); } } #endif #elif TARGET==OS2 #ifdef __32BIT__ FILESTATUS3 fstatus; int rc; rc=DosQueryPathInfo(name, FIL_STANDARD, (PBYTE)&fstatus, sizeof(fstatus)); if(action) { fstatus.attrFile=attrs; return(DosSetPathInfo(name, FIL_STANDARD, (PBYTE)&fstatus, sizeof(fstatus), 0)?-1:0); } else return(rc?-1:fstatus.attrFile); #else USHORT rc; if(action) return(DosSetFileMode(name, attrs, 0L)?-1:0); else return(DosQFileMode(name, &rc, 0L)?-1:rc); #endif #elif TARGET==WIN32 DWORD rc; if(!action) { rc=GetFileAttributes(name); if(rc==0xFFFFFFFF) return(-1); else return((int)rc); } else return(!SetFileAttributes(name, attrs)); #else struct stat st; if(action) { if(!lstat(name, &st)&&S_ISLNK(st.st_mode)) return(0); /* ASR fix 15/06/2003: don't touch symlinks anymore */ else return(chmod(name, attrs)); } else return(lstat(name, &st)?-1:st.st_mode); #endif}#endif/* Manages the access rights for a stream - required to handle the SFX archives properly */#if SFX_LEVEL>=ARJ&&TARGET==UNIXint file_acc(FILE *stream){ struct stat st; return(fstat(fileno(stream), &st)?-1:st.st_mode);}/* Duplicates the "R" access bits into "X" for creating a SFX */void make_executable(FILE *stream){ int stm; stm=file_acc(stream); fchmod(fileno(stream), stm|((stm>>2)&0111));}#endif/* access() */#if SFX_LEVEL>=ARJSFX||defined(REARJ)||defined(REGISTER)static int file_access(char *name, int mode){ #if TARGET==DOS #ifndef REGISTER if(lfn_supported!=LFN_NOT_SUPPORTED) return(w95_access(name, mode)); else #endif return(access(name, mode)); #elif TARGET==OS2||TARGET==WIN32||TARGET==UNIX return(access(name, mode)); #else #error No access() defined #endif}#endif#if TARGET==UNIX&&(SFX_LEVEL>=ARJSFXV||defined(REARJ))/* Locates the first matching dirent, like findnext() but for the first dirent as well (the UNIX-way). May trash the new_ffblk structures without returning success, but who cares? */static int roll_dirent(struct new_ffblk *new_ffblk){ struct dirent *ent; int a, l, m; struct stat st, resolved_st; int attrs; dev_t real_dev; ino_t real_inode; a=ufattr(attrs=new_ffblk->attrs); strcpy(new_ffblk->ff_name, new_ffblk->dir); if(!strcmp(new_ffblk->ff_name, cur_dir_spec)) new_ffblk->ff_name[l=0]='\0'; else { l=strlen(new_ffblk->ff_name); if(l==0||new_ffblk->ff_name[l-1]!=PATHSEP_DEFAULT) new_ffblk->ff_name[l++]=PATHSEP_DEFAULT; } /* Now, check all files until we find the matching one */ while((ent=readdir(new_ffblk->ff_handle))!=NULL) { strcpy(new_ffblk->ff_name+l, ent->d_name); if(a!=0) m=match_unix_attrs(file_chmod(new_ffblk->ff_name, 0, 0), a); else m=1; /* Wildcard matching and attribute check */ if(m&&!fnmatch(new_ffblk->wildcard, ent->d_name, 0)) { if(lstat(new_ffblk->ff_name, &st)) return(-1); real_dev=st.st_dev; real_inode=st.st_ino;#if SFX_LEVEL>=ARJ /* Search in the device pool to see if the user forbids archiving for this device */ if(!is_dev_allowed(real_dev)) continue;#endif /* Redo stat if it's a link and we do not handle links (so need it to be resolved) */ if(!(attrs&FATTR_DT_UXSPECIAL)&&stat(new_ffblk->ff_name, &st)) continue; /* Sockets aren't supported, check for other types as well */#if !defined(S_ISSOCK)#define S_ISSOCK(m) 0#endif if(!S_ISSOCK(st.st_mode)&& (((uftype(attrs)==FATTR_DT_ANY||(uftype(attrs)&FATTR_DT_REG))&&S_ISREG(st.st_mode))|| ((attrs&FATTR_DT_DIR)&&S_ISDIR(st.st_mode))|| (attrs&FATTR_DT_UXSPECIAL))) { /* Reestablish the "unqualified" filename */ strcpy(new_ffblk->ff_name, ent->d_name); /* If it was a link, try to retrieve the mode of file which it points to. Otherwise, chmod() will trash the mode of original file upon restore */ if(S_ISLNK(st.st_mode)&&stat(new_ffblk->ff_name, &resolved_st)!=-1) { new_ffblk->ff_attrib=resolved_st.st_mode&FATTR_UFMASK; real_dev=resolved_st.st_dev; real_inode=resolved_st.st_ino; } else new_ffblk->ff_attrib=st.st_mode&FATTR_UFMASK; /* Convert the remaining structures to new_ffblk and leave the search */ new_ffblk->ff_ftype=st.st_mode; if(S_ISREG(st.st_mode)) new_ffblk->ff_attrib|=FATTR_DT_REG; else if(S_ISDIR(st.st_mode)) new_ffblk->ff_attrib|=FATTR_DT_DIR; else new_ffblk->ff_attrib|=FATTR_DT_UXSPECIAL; new_ffblk->ff_ftime=st.st_mtime; /* Prevent REARJ from complaining about directory size mismatch */ new_ffblk->ff_fsize=(S_ISREG(st.st_mode))?st.st_size:0; new_ffblk->ff_atime=st.st_atime; new_ffblk->ff_ctime=st.st_ctime; /* Special structures for hard links */ new_ffblk->l_search.dev=real_dev; new_ffblk->l_search.inode=real_inode; new_ffblk->l_search.refcount=S_ISDIR(st.st_mode)?1:st.st_nlink; break; } } } return(ent==NULL?-1:0);}#endif#if TARGET==WIN32/* Strip NT timestamps -> DOS timestamps */#if SFX_LEVEL>=ARJSFX||defined(REARJ)static unsigned long dosify_time(FILETIME *pft){ FILETIME lft; WORD dd=0x1111, dt=0x1111; FileTimeToLocalFileTime(pft, &lft); FileTimeToDosDateTime(&lft, &dd, &dt); return(make_ftime(dd, dt));}#endif/* Expand DOS timestamps into NT UTC timestamps */#if SFX_LEVEL>=ARJSFXJR||defined(REARJ)static void ntify_time(FILETIME *pft, unsigned long dft){ FILETIME lft; DosDateTimeToFileTime((WORD)(dft>>16), (WORD)(dft&0xFFFF), &lft); LocalFileTimeToFileTime(&lft, pft);}#endif#endif/* findfirst() - Borland's implementation */#if SFX_LEVEL>=ARJSFXV||defined(REARJ)int lfn_findfirst(char *path, struct new_ffblk *new_ffblk, int attrib){ #if TARGET==DOS /* ASR fix 04/09/2001 for the R11 timestamp format */ new_ffblk->ff_atime=new_ffblk->ff_ctime=0; if(lfn_supported==LFN_SUPPORTED) return(w95_findfirst(path, new_ffblk, attrib)); else #if COMPILER==BCC return(findfirst(path, (struct ffblk *)new_ffblk, attrib)); #elif COMPILER==MSC return(_dos_findfirst(path, attrib, (struct find_t *)new_ffblk)); #endif #elif TARGET==OS2 HDIR handle=HDIR_CREATE; #ifdef __32BIT__ FILEFINDBUF3 findbuf; ULONG fcount=1L; #else FILEFINDBUF findbuf; USHORT fcount=1; #endif #ifdef __32BIT__ if(DosFindFirst(path, &handle, attrib, &findbuf, sizeof(findbuf), &fcount, FIL_STANDARD)) return(-1); #else if(DosFindFirst(path, &handle, attrib, &findbuf, sizeof(findbuf), &fcount, 0L)) return(-1); #endif /* Do the conversion */ new_ffblk->ff_attrib=findbuf.attrFile; new_ffblk->ff_ftime=make_ftime(findbuf.fdateLastWrite, findbuf.ftimeLastWrite); new_ffblk->ff_fsize=findbuf.cbFile; strcpy(new_ffblk->ff_name, findbuf.achName); new_ffblk->ff_atime=make_ftime(findbuf.fdateLastAccess, findbuf.ftimeLastAccess); new_ffblk->ff_ctime=make_ftime(findbuf.fdateCreation, findbuf.ftimeCreation); #if SFX_LEVEL<=ARJSFXV&&!defined(REARJ) DosFindClose(handle); #else new_ffblk->ff_handle=handle; #endif return(0); #elif TARGET==WIN32 WIN32_FIND_DATA wfd; HANDLE hf; if((hf=FindFirstFile(path, &wfd))==INVALID_HANDLE_VALUE) return(-1); if(wfd.nFileSizeHigh>0||(long)wfd.nFileSizeLow<0) return(-1); new_ffblk->ff_attrib=wfd.dwFileAttributes; new_ffblk->ff_ftime=dosify_time(&wfd.ftLastWriteTime); new_ffblk->ff_atime=dosify_time(&wfd.ftLastAccessTime); new_ffblk->ff_ctime=dosify_time(&wfd.ftCreationTime); new_ffblk->ff_fsize=wfd.nFileSizeLow; strcpy(new_ffblk->ff_name, wfd.cFileName); #if SFX_LEVEL<=ARJSFXV&&!defined(REARJ) FindClose(hf); #else new_ffblk->ff_handle=hf; #endif return(0); #elif TARGET==UNIX split_name(path, new_ffblk->dir, new_ffblk->wildcard); if(new_ffblk->wildcard[0]=='\0') strcpy(new_ffblk->wildcard, all_wildcard); if(new_ffblk->dir[0]=='\0') strcpy(new_ffblk->dir, cur_dir_spec); if((new_ffblk->ff_handle=opendir(new_ffblk->dir))==NULL) return(-1); new_ffblk->attrs=attrib; if(roll_dirent(new_ffblk)==-1) { closedir(new_ffblk->ff_handle); new_ffblk->ff_handle=NULL; /* Invalidate the new_ffblk */ return(-1); } #if SFX_LEVEL<=ARJSFXV&&!defined(REARJ) closedir(new_ffblk->ff_handle); #endif return(0); #endif}#endif/* findnext() - Borland's implementation */#if SFX_LEVEL>=ARJ||defined(REARJ)int lfn_findnext(struct new_ffblk *new_ffblk){ #if TARGET==DOS if(lfn_supported==LFN_SUPPORTED) return(w95_findnext(new_ffblk)); else #if COMPILER==BCC return(findnext((struct ffblk *)new_ffblk)); #elif COMPILER==MSC return(_dos_findnext((struct find_t *)new_ffblk)); #endif #elif TARGET==OS2 HDIR handle; #ifdef __32BIT__ FILEFINDBUF3 findbuf; ULONG fcount=1L; #else FILEFINDBUF findbuf; USHORT fcount=1; #endif handle=new_ffblk->ff_handle; if(DosFindNext(handle, &findbuf, sizeof(findbuf), &fcount)) return(-1); /* Do the conversion */ new_ffblk->ff_attrib=findbuf.attrFile; new_ffblk->ff_ftime=make_ftime(findbuf.fdateLastWrite, findbuf.ftimeLastWrite); new_ffblk->ff_fsize=findbuf.cbFile; strcpy(new_ffblk->ff_name, findbuf.achName); new_ffblk->ff_atime=make_ftime(findbuf.fdateLastAccess, findbuf.ftimeLastAccess); new_ffblk->ff_ctime=make_ftime(findbuf.fdateCreation, findbuf.ftimeCreation); return(0); #elif TARGET==WIN32 WIN32_FIND_DATA wfd; if(!FindNextFile(new_ffblk->ff_handle, &wfd)) return(-1); if(wfd.nFileSizeHigh>0||(long)wfd.nFileSizeLow<0) return(-1); new_ffblk->ff_attrib=wfd.dwFileAttributes; new_ffblk->ff_ftime=dosify_time(&wfd.ftLastWriteTime); new_ffblk->ff_atime=dosify_time(&wfd.ftLastAccessTime); new_ffblk->ff_ctime=dosify_time(&wfd.ftCreationTime); new_ffblk->ff_fsize=wfd.nFileSizeLow; strcpy(new_ffblk->ff_name, wfd.cFileName); return(0); #elif TARGET==UNIX if(roll_dirent(new_ffblk)==-1) return(-1); return(0); #endif}#endif/* findclose() */#if SFX_LEVEL>=ARJ||defined(REARJ)void lfn_findclose(struct new_ffblk *new_ffblk){ #if TARGET==DOS if(lfn_supported==LFN_SUPPORTED) w95_findclose(new_ffblk); #elif TARGET==OS2 DosFindClose(new_ffblk->ff_handle); #elif TARGET==WIN32 FindClose(new_ffblk->ff_handle); #elif TARGET==UNIX if(new_ffblk->ff_handle!=NULL) closedir(new_ffblk->ff_handle); new_ffblk->ff_handle=NULL; /* Invalidate it! */ #endif}#endif/* Convert the given symbols to upper case, depending on locale */#if SFX_LEVEL>=ARJSFXV||defined(REARJ)void toupper_loc(unsigned char *ptr, int length){ #if TARGET==DOS&&defined(ASM8086) struct { int co_date; char co_curr[5]; char co_thsep[2]; char co_desep[2]; char co_dtsep[2]; char co_tmsep[2]; char co_currstyle; char co_digits; char co_time; long co_case; char co_dasep[2]; char co_fill[10]; } cty; static int cty_state=0; /* 0 if not queried yet */ static char((FAR *ctycnv)()); /* Case map routine */ union REGS regs; char c; if(cty_state==0) { cty_state=-1; if(_osmajor>=3) { regs.x.dx=(unsigned int)&cty; regs.x.ax=0x3800; intdos(®s, ®s); if(!regs.x.cflag) { cty_state=1; /* Accept any further calls */ ctycnv=(char (FAR *)())cty.co_case; } } } if(cty_state>0) { while(length>0) { if(ptr[0]>='a'&&ptr[0]<='z') ptr[0]-=0x20; /* Convert to upper case */ else if(ptr[0]>=0x80) { c=ptr[0]; asm mov al, c; ctycnv(); asm mov c, al; ptr[0]=c; } ptr++; length--; } } else { while(length>0) { if(ptr[0]>='a'&&ptr[0]<='z')
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -