📄 os2.c
字号:
free(odp); }}static char *getdirent(__GPRO__ ZCONST char *dir){ int done; /* moved to os2data.h so it can be global */ /* static int lower; */ if (dir != NULL) { /* get first entry */ G.os2.hdir = HDIR_SYSTEM; G.os2.count = 1; done = DosFindFirst((PSZ) dir, &G.os2.hdir, attributes, &G.os2.find, sizeof(G.os2.find), &G.os2.count); G.os2.lower = IsFileSystemFAT(__G__ dir); } else /* get next entry */ done = DosFindNext(G.os2.hdir, &G.os2.find, sizeof(G.os2.find), &G.os2.count); if (done == 0) { if ( G.os2.lower ) StringLower(G.os2.find.achName); return G.os2.find.achName; } else { DosFindClose(G.os2.hdir); return NULL; }}int IsFileSystemFAT(__GPRO__ ZCONST char *dir) /* FAT / HPFS detection */{ /* moved to os2data.h so they can be global */ /* static USHORT nLastDrive=(USHORT)(-1), nResult; */ ULONG lMap; BYTE bData[64]; char bName[3];#ifdef __32BIT__ ULONG nDrive, cbData; PFSQBUFFER2 pData = (PFSQBUFFER2) bData;#else USHORT nDrive, cbData; PFSQBUFFER pData = (PFSQBUFFER) bData;#endif /* We separate FAT and HPFS+other file systems here. at the moment I consider other systems to be similar to HPFS, i.e. support long file names and case sensitive */ if ( isalpha(dir[0]) && (dir[1] == ':') ) nDrive = toupper(dir[0]) - '@'; else DosQueryCurrentDisk(&nDrive, &lMap); if ( nDrive == G.os2.nLastDrive ) return G.os2.nResult; bName[0] = (char) (nDrive + '@'); bName[1] = ':'; bName[2] = 0; G.os2.nLastDrive = nDrive; cbData = sizeof(bData); if ( !DosQueryFSAttach(bName, 0, FSAIL_QUERYNAME, (PVOID) pData, &cbData) ) G.os2.nResult = !strcmp((char *) (pData -> szFSDName) + pData -> cbName, "FAT"); else G.os2.nResult = FALSE; /* End of this ugly code */ return G.os2.nResult;} /* end function IsFileSystemFAT() *//************************//* Function do_wild() *//************************/char *do_wild(__G__ wildspec) __GDEF char *wildspec; /* only used first time on a given dir */{ /* moved to os2data.h so they can be global */#if 0 static DIR *dir = NULL; static char *dirname, *wildname, matchname[FILNAMSIZ]; static int firstcall=TRUE, have_dirname, dirnamelen;#endif char *fnamestart; struct direct *file; /* Even when we're just returning wildspec, we *always* do so in * matchname[]--calling routine is allowed to append four characters * to the returned string, and wildspec may be a pointer to argv[]. */ if (G.os2.firstcall) { /* first call: must initialize everything */ G.os2.firstcall = FALSE; if (!iswild(wildspec)) { strcpy(G.os2.matchname, wildspec); G.os2.have_dirname = FALSE; G.os2.dir = NULL; return G.os2.matchname; } /* break the wildspec into a directory part and a wildcard filename */ if ((G.os2.wildname = strrchr(wildspec, '/')) == NULL && (G.os2.wildname = strrchr(wildspec, ':')) == NULL) { G.os2.dirname = "."; G.os2.dirnamelen = 1; G.os2.have_dirname = FALSE; G.os2.wildname = wildspec; } else { ++G.os2.wildname; /* point at character after '/' or ':' */ G.os2.dirnamelen = G.os2.wildname - wildspec; if ((G.os2.dirname = (char *)malloc(G.os2.dirnamelen+1)) == NULL) { Info(slide, 1, ((char *)slide, LoadFarString(CantAllocateWildcard))); strcpy(G.os2.matchname, wildspec); return G.os2.matchname; /* but maybe filespec was not a wildcard */ } strncpy(G.os2.dirname, wildspec, G.os2.dirnamelen); G.os2.dirname[G.os2.dirnamelen] = '\0'; /* terminate for strcpy below */ G.os2.have_dirname = TRUE; } Trace((stderr, "do_wild: dirname = [%s]\n", G.os2.dirname)); if ((G.os2.dir = opendir(__G__ G.os2.dirname)) != NULL) { if (G.os2.have_dirname) { strcpy(G.os2.matchname, G.os2.dirname); fnamestart = G.os2.matchname + G.os2.dirnamelen; } else fnamestart = G.os2.matchname; while ((file = readdir(__G__ G.os2.dir)) != NULL) { Trace((stderr, "do_wild: readdir returns %s\n", file->d_name)); strcpy(fnamestart, file->d_name); if (strrchr(fnamestart, '.') == (char *)NULL) strcat(fnamestart, "."); if (match(fnamestart, G.os2.wildname, 1) && /* 1 == ignore case */ /* skip "." and ".." directory entries */ strcmp(fnamestart, ".") && strcmp(fnamestart, "..")) { Trace((stderr, "do_wild: match() succeeds\n")); /* remove trailing dot */ fnamestart += strlen(fnamestart) - 1; if (*fnamestart == '.') *fnamestart = '\0'; return G.os2.matchname; } } /* if we get to here directory is exhausted, so close it */ closedir(G.os2.dir); G.os2.dir = NULL; }#ifdef DEBUG else { Trace((stderr, "do_wild: opendir(%s) returns NULL\n", G.os2.dirname)); }#endif /* DEBUG */ /* return the raw wildspec in case that works (e.g., directory not * searchable, but filespec was not wild and file is readable) */ strcpy(G.os2.matchname, wildspec); return G.os2.matchname; } /* last time through, might have failed opendir but returned raw wildspec */ if (G.os2.dir == NULL) { G.os2.firstcall = TRUE; /* nothing left to try--reset for new wildspec */ if (G.os2.have_dirname) free(G.os2.dirname); return (char *)NULL; } /* If we've gotten this far, we've read and matched at least one entry * successfully (in a previous call), so dirname has been copied into * matchname already. */ if (G.os2.have_dirname) { /* strcpy(G.os2.matchname, G.os2.dirname); */ fnamestart = G.os2.matchname + G.os2.dirnamelen; } else fnamestart = G.os2.matchname; while ((file = readdir(__G__ G.os2.dir)) != NULL) { Trace((stderr, "do_wild: readdir returns %s\n", file->d_name)); strcpy(fnamestart, file->d_name); if (strrchr(fnamestart, '.') == (char *)NULL) strcat(fnamestart, "."); if (match(fnamestart, G.os2.wildname, 1)) { /* 1 == ignore case */ Trace((stderr, "do_wild: match() succeeds\n")); /* remove trailing dot */ fnamestart += strlen(fnamestart) - 1; if (*fnamestart == '.') *fnamestart = '\0'; return G.os2.matchname; } } closedir(G.os2.dir); /* have read at least one dir entry; nothing left */ G.os2.dir = NULL; G.os2.firstcall = TRUE; /* reset for new wildspec */ if (G.os2.have_dirname) free(G.os2.dirname); return (char *)NULL;} /* end function do_wild() */#endif /* !SFX *//* scan extra fields for something we happen to know */static int EvalExtraFields(__GPRO__ const char *path, void *extra_field, unsigned ef_len){ char *ef_ptr = extra_field; PEFHEADER pEFblock; int rc = PK_OK; while (ef_len >= sizeof(EFHEADER)) { pEFblock = (PEFHEADER) ef_ptr; if (pEFblock -> nSize > (ef_len - EB_HEADSIZE)) return PK_ERR; /* claimed EFblock length exceeds EF size! */ switch (pEFblock -> nID) { case EF_OS2: rc = SetEAs(__G__ path, ef_ptr); break; case EF_ACL: rc = (uO.X_flag) ? SetACL(__G__ path, ef_ptr) : PK_OK; break;#if 0 case EF_IZUNIX: case EF_PKUNIX: /* handled elsewhere */ break;#endif default: TTrace((stderr,"EvalExtraFields: unknown extra field block, ID=%d\n", pEFblock -> nID)); break; } ef_ptr += (pEFblock -> nSize + EB_HEADSIZE); ef_len -= (pEFblock -> nSize + EB_HEADSIZE); if (rc != PK_OK) break; } return rc;}/************************//* Function mapattr() *//************************/int mapattr(__G) __GDEF{ /* set archive bit (file is not backed up): */ G.pInfo->file_attr = (unsigned)(G.crec.external_file_attributes | 32) & 0xff; return 0;}/************************//* Function mapname() *//************************//* * There are presently two possibilities in OS/2: the output filesystem is * FAT, or it is HPFS. If the former, we need to map to FAT, obviously, but * we *also* must map to HPFS and store that version of the name in extended * attributes. Either way, we need to map to HPFS, so the main mapname * routine does that. In the case that the output file system is FAT, an * extra filename-mapping routine is called in checkdir(). While it should * be possible to determine the filesystem immediately upon entry to mapname(), * it is conceivable that the DOS APPEND utility could be added to OS/2 some- * day, allowing a FAT directory to be APPENDed to an HPFS drive/path. There- * fore we simply check the filesystem at each path component. * * Note that when alternative IFSes become available/popular, everything will * become immensely more complicated. For example, a Minix filesystem would * have limited filename lengths like FAT but no extended attributes in which * to store the longer versions of the names. A BSD Unix filesystem would * support paths of length 1024 bytes or more, but it is not clear that FAT * EAs would allow such long .LONGNAME fields or that OS/2 would properly * restore such fields when moving files from FAT to the new filesystem. * * GRR: some or all of the following chars should be checked in either * mapname (HPFS) or map2fat (FAT), depending: ,=^+'"[]<>|\t& */ /* return 0 if no error, 1 if caution (filename */int mapname(__G__ renamed) /* truncated), 2 if warning (skip file because */ __GDEF /* dir doesn't exist), 3 if error (skip file), */ int renamed; /* or 10 if out of memory (skip file) */{ /* [also IZ_VOL_LABEL, IZ_CREATED_DIR] */ char pathcomp[FILNAMSIZ]; /* path-component buffer */ char *pp, *cp=(char *)NULL; /* character pointers */ char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */ int quote = FALSE; /* flag: next char is literal */ int error = 0; register unsigned workch; /* hold the character being tested *//*--------------------------------------------------------------------------- Initialize various pointers and counters and stuff. ---------------------------------------------------------------------------*/ /* can create path as long as not just freshening, or if user told us */ G.create_dirs = (!uO.fflag || renamed); G.os2.created_dir = FALSE; /* not yet */ G.os2.renamed_fullpath = FALSE; G.os2.fnlen = strlen(G.filename);/* GRR: for VMS, convert to internal format now or later? or never? */ if (renamed) { cp = G.filename - 1; /* point to beginning of renamed name... */ while (*++cp) if (*cp == '\\') /* convert backslashes to forward */ *cp = '/'; cp = G.filename; /* use temporary rootpath if user gave full pathname */ if (G.filename[0] == '/') { G.os2.renamed_fullpath = TRUE; pathcomp[0] = '/'; /* copy the '/' and terminate */ pathcomp[1] = '\0'; ++cp; } else if (isalpha(G.filename[0]) && G.filename[1] == ':') { G.os2.renamed_fullpath = TRUE; pp = pathcomp; *pp++ = *cp++; /* copy the "d:" (+ '/', possibly) */ *pp++ = *cp++; if (*cp == '/') *pp++ = *cp++; /* otherwise add "./"? */ *pp = '\0'; } } /* pathcomp is ignored unless renamed_fullpath is TRUE: */ if ((error = checkdir(__G__ pathcomp, INIT)) != 0) /* init path buffer */ return error; /* ...unless no mem or vol label on hard disk */ *pathcomp = '\0'; /* initialize translation buffer */ pp = pathcomp; /* point to translation buffer */ if (!renamed) { /* cp already set if renamed */ if (uO.jflag) /* junking directories *//* GRR: watch out for VMS version... */ cp = (char *)strrchr(G.filename, '/'); if (cp == (char *)NULL) /* no '/' or not junking dirs */ cp = G.filename; /* point to internal zipfile-member pathname */ else ++cp; /* point to start of last component of path */ }/*--------------------------------------------------------------------------- Begin main loop through characters in filename. ---------------------------------------------------------------------------*/ while ((workch = (uch)*cp++) != 0) { if (quote) { /* if character quoted, */ *pp++ = (char)workch; /* include it literally */ quote = FALSE; } else switch (workch) { case '/': /* can assume -j flag not given */ *pp = '\0'; if ((error = checkdir(__G__ pathcomp, APPEND_DIR)) > 1) return error; pp = pathcomp; /* reset conversion buffer for next piece */ lastsemi = (char *)NULL; /* leave directory semi-colons alone */ break; case ':': *pp++ = '_'; /* drive names not stored in zipfile, */ break; /* so no colons allowed */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -