/* Copyright (C) 1992, 1993, 1996, 1998 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gp_dosfs.c,v 1.2.6.3.2.1 2003/01/17 00:49:02 giles Exp $ */ /* Common routines for MS-DOS (any compiler) and DesqView/X, */ /* which has a MS-DOS-like file system. */ #include "dos_.h" #include "gx.h" #include "gp.h" /* ------ Printer accessing ------ */ /* Put a printer file (which might be stdout) into binary or text mode. */ /* This is not a standard gp procedure, */ /* but all MS-DOS configurations need it. */ void gp_set_file_binary(int prnfno, bool binary) { union REGS regs; regs.h.ah = 0x44; /* ioctl */ regs.h.al = 0; /* get device info */ regs.rshort.bx = prnfno; intdos(®s, ®s); if (regs.rshort.cflag != 0 || !(regs.h.dl & 0x80)) return; /* error, or not a device */ if (binary) regs.h.dl |= 0x20; /* binary (no ^Z intervention) */ else regs.h.dl &= ~0x20; /* text */ regs.h.dh = 0; regs.h.ah = 0x44; /* ioctl */ regs.h.al = 1; /* set device info */ intdos(®s, ®s); } /* ------ File accessing ------ */ /* Set a file into binary or text mode. */ int gp_setmode_binary(FILE * pfile, bool binary) { gp_set_file_binary(fileno(pfile), binary); return 0; /* Fake out dos return status */ } /* ------ File names ------ */ /* Define the character used for separating file names in a list. */ const char gp_file_name_list_separator = ';'; /* Define the string to be concatenated with the file mode */ /* for opening files without end-of-line conversion. */ const char gp_fmode_binary_suffix[] = "b"; /* Define the file modes for binary reading or writing. */ const char gp_fmode_rb[] = "rb"; const char gp_fmode_wb[] = "wb"; /* Answer whether a path_string can meaningfully have a prefix applied */ bool gp_pathstring_not_bare(const char *fname, unsigned len) { /* A file name is not bare if it contains a drive specifications */ /* (second character is a :) or if it starts with a '.', '/' or '\\'*/ /* or it contains '/../' (parent reference) */ if ((len > 0) && ((*fname == '/') || (*fname == '\\') || (*fname == '.') || ((len > 2) && (fname[1] == ':')))) return true; while (len-- > 3) { int c = *fname++; if (((c == '/') || (c == '\\')) && ((len >= 3) && (bytes_compare(fname, 2, "..", 2) == 0) && ((fname[2] == '/') || (fname[2] == '\\')))) return true; } return false; } /* Answer whether the file_name references the directory */ /* containing the specified path (parent). */ bool gp_file_name_references_parent(const char *fname, unsigned len) { int i = 0, last_sep_pos = -1; /* A file name references its parent directory if it starts */ /* with ../ or ..\ or if one of these strings follows / or \ */ while (i < len) { if (fname[i] == '/' || fname[i] == '\\') { last_sep_pos = i++; continue; } if (fname[i++] != '.') continue; if (i > last_sep_pos + 2 || (i < len && fname[i] != '.')) continue; i++; /* have separator followed by .. */ if (i < len && (fname[i] == '/' || fname[i++] == '\\')) return true; } return false; } /* Answer the string to be used for combining a directory/device prefix */ /* with a base file name. The prefix directory/device is examined to */ /* determine if a separator is needed and may return an empty string */ const char * gp_file_name_concat_string(const char *prefix, unsigned plen) { if (plen > 0) switch (prefix[plen - 1]) { case ':': case '/': case '\\': return ""; }; return "/"; }