📄 ea_mgr.c
字号:
/* * $Id: ea_mgr.c,v 1.3 2003/06/27 18:58:35 andrew_belov Exp $ * --------------------------------------------------------------------------- * This file provides basic routines for handling extended attributes. * */#include "arj.h"DEBUGHDR(__FILE__) /* Debug information block *//* OS/2 v 1.2 structure declarations for Win32 */#if TARGET==WIN32typedef struct _FEA { BYTE fEA; /* flags */ BYTE cbName; /* name length not including NULL */ WORD cbValue; /* value length */} FEA;typedef FEA FAR *PFEA;/* flags for _FEA.fEA */#define FEA_NEEDEA 0x80 /* need EA bit */typedef struct _FEALIST { DWORD cbList; /* total bytes of structure inc full list */ FEA list[1]; /* variable length FEA structures */} FEALIST;typedef FEALIST FAR * PFEALIST;#endif/* Local variables */#if defined(HAVE_EAS)static char longname_ea[]=".LONGNAME";static char forbidden_chars[]="\\/:?*<>|";#endif/* Aligns any address to DWORD */#if (TARGET==OS2&&defined(__32BIT__))||TARGET==WIN32static char FAR *align_dword(char FAR *p){ unsigned int p_l; p_l=(unsigned int)p; if(p_l%4==0) return(p); else return(p+4-(p_l%4));}#endif/* Returns 1 if the EA is to be included/processed */#if SFX_LEVEL>=ARJ&&defined(HAVE_EAS)static int ea_filter(char FAR *name, int skip_ln){ char tmp_name[CCHMAXPATH]; far_strcpy((char FAR *)tmp_name, name); if(skip_ln&&!stricmp(tmp_name, longname_ea)) return(0); if(include_eas&&!flist_find(&flist_ea, tmp_name)) return(0); if(exclude_eas&&flist_find(&flist_xea, tmp_name)) return(0); return(1);}#endif/* Returns size of extended attributes attached to file */unsigned int get_ea_size(char *name){ #if TARGET==OS2 #ifdef __32BIT__ FILESTATUS4 fs; #else FILESTATUS2 fs; #endif unsigned int rc; #ifdef __32BIT__ DosQueryPathInfo(name, FIL_QUERYEASIZE, (PVOID)&fs, sizeof(fs)); #else DosQPathInfo(name, FIL_QUERYEASIZE, (PVOID)&fs, sizeof(fs), 0L); #endif rc=(fs.cbList>=4)?fs.cbList-4:fs.cbList; #ifdef __32BIT__ rc>>=1; /* BUGBUG? */ #endif return(rc); #elif TARGET==WIN32 struct nt_sid *sid; unsigned long rc; if(!ea_supported||(sid=open_streams(name, 0))==NULL) return(0); rc=seek_stream_id(BACKUP_EA_DATA, sid); close_streams(sid); return((rc>0xFFFF)?0:rc); #else return(0); #endif}/* Returns EA block size */unsigned int get_eablk_size(char FAR *blk){ unsigned int rc; unsigned int i, total, data_len; char FAR *blk_ptr; total=mget_word(blk); rc=2; blk_ptr=blk+2; for(i=0; i<total; i++) { blk_ptr++; data_len=mget_byte(blk_ptr++); data_len+=mget_word(blk_ptr); blk_ptr+=2; rc+=data_len+4; blk_ptr+=data_len; } return(rc);}/* Returns # of EAs in the block to external caller */unsigned int get_num_eas(char FAR *blk){ return(mget_word(blk));}/* EA deletion routine */int discard_ea(char *name){ #if TARGET==OS2 ULONG count; #ifdef __32BIT__ APIRET rc; char FAR *real_pfeal; PFEA2LIST pfeal; EAOP2 eaop; PDENA2 pdena; #else USHORT rc; PFEALIST pfeal; EAOP eaop; PDENA1 pdena; #endif int rcode=0; #ifdef __32BIT__ pdena=(PDENA2)farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); real_pfeal=(char FAR *)farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); pfeal=(PFEA2LIST)align_dword(real_pfeal); #else pdena=(PDENA1)farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); pfeal=(PFEALIST)farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); #endif while(1) { count=1L; #ifdef __32BIT__ if(DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PVOID)name, 1L, (PVOID)pdena, sizeof(*pdena)+CCHMAXPATHCOMP, &count, ENUMEA_LEVEL_NO_VALUE)) #else if(DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PVOID)name, 1L, (PVOID)pdena, sizeof(*pdena)+CCHMAXPATHCOMP, &count, ENUMEA_LEVEL_NO_VALUE, 0L)) #endif break; if(count==0L) break; /* EA (pdena->szName) consumes (pdena->cbValue) bytes */ #ifdef __32BIT__ eaop.fpFEA2List=pfeal; pfeal->list[0].oNextEntryOffset=0; #else eaop.fpFEAList=pfeal; #endif pfeal->list[0].fEA=0; pfeal->list[0].cbName=far_strlen(pdena->szName); pfeal->list[0].cbValue=0; #ifdef __32BIT__ far_strcpy((char FAR *)&(pfeal->list[0])+sizeof(FEA2)-1, pdena->szName); pfeal->cbList=(unsigned long)sizeof(FEA2LIST)+pfeal->list[0].cbName; if((rc=DosSetPathInfo(name, FIL_QUERYEASIZE, (PBYTE)&eaop, sizeof(eaop), 0))!=0) { rcode=-1; break; } #else far_strcpy((char FAR *)&(pfeal->list[0])+sizeof(FEA), pdena->szName); pfeal->cbList=(unsigned long)sizeof(FEALIST)+pfeal->list[0].cbName+1; if((rc=DosSetPathInfo(name, FIL_QUERYEASIZE, (PBYTE)&eaop, sizeof(eaop), 0, 0L))!=0) { rcode=-1; break; } #endif } farfree(pdena); #ifndef TILED farfree(real_pfeal); #endif return(rcode); #elif TARGET==WIN32 /* There seems to be no easy way to not purge EAs using the backup APIs! */ return(0); #else return(-1); #endif}/* Allocates memory for and stores extended attributes */#if SFX_LEVEL>=ARJint query_ea(char FAR **dest, char *name, int skip_ln){ #ifdef HAVE_EAS ULONG count, j; #if TARGET==OS2 #ifdef __32BIT__ EAOP2 eaop; PGEA2LIST pgeal; PFEA2LIST pfeal; APIRET rc; PDENA2 pdena; FILESTATUS4 fs; #else EAOP eaop; PGEALIST pgeal; PFEALIST pfeal; USHORT rc; PDENA1 pdena; FILESTATUS2 fs; #endif #elif TARGET==WIN32 struct nt_sid *sid; unsigned char *streambuf; unsigned long stream_len; PFEALIST pfeal; #endif int rcode=0; char FAR *dptr, FAR *nptr; #if TARGET==OS2 pdena=farmalloc_msg(sizeof(*pdena)+CCHMAXPATHCOMP); #ifdef __32BIT__ pgeal=(PGEA2LIST)farmalloc_msg(sizeof(GEA2LIST)+CCHMAXPATHCOMP); if(DosQueryPathInfo(name, FIL_QUERYEASIZE, (PVOID)&fs, sizeof(fs))) return(-1); #else pgeal=(PGEALIST)farmalloc_msg(sizeof(GEALIST)+CCHMAXPATHCOMP); if(DosQPathInfo(name, FIL_QUERYEASIZE, (PVOID)&fs, sizeof(fs), 0L)) return(-1); #endif if(fs.cbList<4) fs.cbList=4; /* Fix for Ext2FS */ /* Allocate enough space to hold EA block */ #ifdef __32BIT__ *dest=(char FAR *)farmalloc_msg((int)fs.cbList*2); /* SDK does recommend it */ #else *dest=(char FAR *)farmalloc_msg((int)fs.cbList-2); #endif #elif TARGET==WIN32 if((sid=open_streams(name, 0))==NULL) return(-1); stream_len=seek_stream_id(BACKUP_EA_DATA, sid); if(stream_len==0||stream_len>65535) { close_streams(sid); *dest=(char FAR *)farmalloc_msg(2); dptr=*dest; mput_word(0, dptr); return(0); } /* It's a plain FEALIST, so doesn't require much caution */ streambuf=(char FAR *)farmalloc_msg((int)stream_len); *dest=(char FAR *)farmalloc_msg((int)stream_len); if((stream_len=read_stream(streambuf, stream_len, sid))==0) { close_streams(sid); dptr=*dest; mput_word(0, dptr); free(streambuf); return(0); } #endif /* Initialize storage */ dptr=*dest; mput_word(0, dptr); dptr+=2; j=0L; while(1) { #if TARGET==OS2 count=1L; #ifdef __32BIT__ if(DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PVOID)name, ++j, (PVOID)pdena, sizeof(*pdena)+CCHMAXPATHCOMP, &count, ENUMEA_LEVEL_NO_VALUE)) break; #else if(DosEnumAttribute(ENUMEA_REFTYPE_PATH, (PVOID)name, ++j, (PVOID)pdena, sizeof(*pdena)+CCHMAXPATHCOMP, &count, ENUMEA_LEVEL_NO_VALUE, 0L)) break; #endif if(count==0L) break; /* EA (pdena->szName) consumes (pdena->cbValue) bytes */ #ifdef __32BIT__ eaop.fpGEA2List=pgeal; #else eaop.fpGEAList=pgeal; #endif far_strcpy(pgeal->list[0].szName, pdena->szName); pgeal->list[0].cbName=pdena->cbName; #ifdef __32BIT__ pgeal->list[0].oNextEntryOffset=0; pgeal->cbList=sizeof(GEA2LIST)+pdena->cbName; eaop.fpGEA2List=pgeal; pfeal=(PFEA2LIST)farmalloc_msg(sizeof(FEA2LIST)+pdena->cbName+pdena->cbValue+1); pfeal->cbList=sizeof(FEA2LIST)+pdena->cbName+pdena->cbValue+1; eaop.fpFEA2List=pfeal; if((rc=DosQueryPathInfo(name, FIL_QUERYEASFROMLIST, (PBYTE)&eaop, sizeof(eaop)))!=0) { farfree(pfeal); rcode=-1; break; } nptr=(char FAR *)&(pfeal->list[0])+sizeof(FEA2)-1; #else pgeal->cbList=sizeof(GEALIST)+pdena->cbName; eaop.fpGEAList=pgeal; pfeal=(PFEALIST)farmalloc_msg(sizeof(FEALIST)+pdena->cbName+pdena->cbValue+1); pfeal->cbList=sizeof(FEALIST)+pdena->cbName+pdena->cbValue+1; eaop.fpFEAList=pfeal; if((rc=DosQPathInfo(name, FIL_QUERYEASFROMLIST, (PBYTE)&eaop, sizeof(eaop), 0L))!=0) { farfree(pfeal); rcode=-1; break; } nptr=(char FAR *)&(pfeal->list[0])+sizeof(FEA); #endif #elif TARGET==WIN32 /* Win32 provides us with a FEALIST at our disposal. */ pfeal=(PFEALIST)streambuf; nptr=(char FAR *)&(pfeal->list[0])+sizeof(FEA); #endif #if SFX_LEVEL>=ARJ if(ea_filter(nptr, skip_ln)&&((pfeal->list[0].fEA&FEA_NEEDEA)||!crit_eas)) #endif { mput_word(mget_word(*dest)+1, *dest); mput_byte(pfeal->list[0].fEA, dptr++); mput_byte(pfeal->list[0].cbName, dptr++); mput_word(pfeal->list[0].cbValue, dptr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -