/* CIO.C compatible direct access (c) 1996 Oliver Kraus kraus@lrs.e-technik.uni-erlangen.de */ #include #include #include #include "ccommon.h" /*--- ms-dos ---*/ #ifdef C_DOS #include #include #include "dpmicall.h" short c_pathbuf_sel_dir; short c_pathbuf_seg_dir; int c_pathbuf_is_dos_mem = 0; /* returns name of filesystem ("FAT", ...) fills flags: Bit(s) Description (Table 1083) 0 searches are case sensitive 1 preserves case in directory entries 2 uses Unicode characters in file and directory names 3-13 reserved (0) 14 supports DOS long filename functions 15 volume is compressed */ char *c_get_vol_info(const char *root, int *flags) { static char s[64]; rminfo_struct rmi; short sel_root, seg_root; short sel_sys, seg_sys; if ( dpmi_alloc_dos_memory(strlen(root)+1, &sel_root, &seg_root ) == 0 ) return NULL; if ( dpmi_alloc_dos_memory(64, &sel_sys, &seg_sys ) == 0 ) { dpmi_free_dos_memory(sel_root); return NULL; } dpmi_copy_to_dos(sel_root, (void *)root, strlen(root)+1); rmi.eax = 0x071a0L; rmi.ebx = 0UL; rmi.ecx = 64UL; rmi.edx = 0UL; rmi.ds = seg_root; rmi.esi = 0L; rmi.es = seg_sys; rmi.edi = 0L; if ( dpmi_simulate_rmi(0x021, &rmi) != 0 ) { dpmi_free_dos_memory(sel_root); dpmi_free_dos_memory(sel_sys); return NULL; } dpmi_copy_from_dos(sel_sys, s, 64); if ( flags != NULL ) { *flags = (int)rmi.ebx; } dpmi_free_dos_memory(sel_root); dpmi_free_dos_memory(sel_sys); return s; } int c_is_long_filename(void) { static int is_long_filename = 2; if ( is_long_filename >= 2 ) { is_long_filename = 0; /* int flags; if ( c_get_vol_info("C:\\", &flags) == NULL ) { is_long_filename = 0; return is_long_filename; } if ( (flags & (1<<14)) == 0 ) { is_long_filename = 0; return is_long_filename; } is_long_filename = 1; */ } return is_long_filename; } /* 0 == 'A' */ void c_chdrive(int drive) { rminfo_struct rmi; rmi.eax = 0x0e00UL; rmi.ebx = 0UL; rmi.ecx = 0UL; rmi.edx = (unsigned long)drive; if ( dpmi_simulate_rmi(0x021, &rmi) != 0 ) { return; } return; } static int c_chdir_lfn(const char *newdir) { size_t len; rminfo_struct rmi; if ( c_pathbuf_is_dos_mem == 0 ) { if ( dpmi_alloc_dos_memory(C_MAX_PATHNAME, &c_pathbuf_sel_dir, &c_pathbuf_seg_dir ) == 0 ) return ENOMEM; c_pathbuf_is_dos_mem = 1; } len = strlen(newdir); if ( len+1 >= C_MAX_PATHNAME ) return EINVAL; dpmi_copy_to_dos(c_pathbuf_sel_dir, (void *)newdir, len+1); rmi.eax = 0x0713bL; rmi.ebx = 0UL; rmi.ecx = 0UL; rmi.edx = 0UL; rmi.ds = c_pathbuf_seg_dir; rmi.edx = 0L; if ( dpmi_simulate_rmi(0x021, &rmi) != 0 ) { return (int)rmi.eax; } return (int)rmi.eax; } static int c_mkdir_lfn(const char *newdir) { size_t len; rminfo_struct rmi; if ( c_pathbuf_is_dos_mem == 0 ) { if ( dpmi_alloc_dos_memory(C_MAX_PATHNAME, &c_pathbuf_sel_dir, &c_pathbuf_seg_dir ) == 0 ) return ENOMEM; c_pathbuf_is_dos_mem = 1; } len = strlen(newdir); if ( len+1 >= C_MAX_PATHNAME ) return EINVAL; dpmi_copy_to_dos(c_pathbuf_sel_dir, (void *)newdir, len+1); rmi.eax = 0x07139L; rmi.ebx = 0UL; rmi.ecx = 0UL; rmi.edx = 0UL; rmi.ds = c_pathbuf_seg_dir; rmi.edx = 0L; if ( dpmi_simulate_rmi(0x021, &rmi) != 0 ) { return (int)rmi.eax; } return (int)rmi.eax; } static char *c_getcwd_lfn(char *s) { rminfo_struct rmi; if ( c_pathbuf_is_dos_mem == 0 ) { if ( dpmi_alloc_dos_memory(C_MAX_PATHNAME, &c_pathbuf_sel_dir, &c_pathbuf_seg_dir ) == 0 ) return NULL; c_pathbuf_is_dos_mem = 1; } rmi.eax = 0x07147L; rmi.ebx = 0UL; rmi.ecx = 0UL; rmi.edx = 0UL; /* current drive */ rmi.ds = c_pathbuf_seg_dir; rmi.esi = 0L; if ( dpmi_simulate_rmi(0x021, &rmi) != 0 ) { return NULL; } dpmi_copy_from_dos(c_pathbuf_sel_dir, (void *)s, C_MAX_PATHNAME); return s; } int c_chdir(const char *newdir) { if ( c_is_long_filename() != 0 ) return c_chdir_lfn(newdir); return chdir(newdir); } int c_mkdir(const char *newdir) { if ( c_is_long_filename() != 0 ) return c_mkdir_lfn(newdir); return mkdir(newdir); } char *c_getcwd(void) { static char s[C_MAX_PATHNAME]; if ( c_is_long_filename() != 0 ) return c_getcwd_lfn(s); return getcwd(s,C_MAX_PATHNAME); } void c_io_clear(void) { dpmi_free_dos_memory(c_pathbuf_sel_dir); c_pathbuf_is_dos_mem = 0; } #endif /*--- unix ---*/ #ifdef C_UNIX int c_chdir(const char *newdir) { return chdir(newdir); } int c_mkdir(const char *newdir) { return mkdir(newdir); } void c_io_clear(void) { } #endif /*--- common ---*/ char c_common_buf[C_MAX_PATHNAME]; void c_strncpy(char *dest, const char *src, size_t n) { strncpy(dest, src, n); dest[n-1] = '\0'; } /* 0 if successful */ int c_create_path(const char *path) { char *s = c_common_buf; char *t; c_strncpy(s, path, C_MAX_PATHNAME); if ( *s == C_DELIMITER_CHAR ) { c_chdir(C_DELIMITER_STR); s++; } t = strtok(s, C_DELIMITER_STR); for(;;) { if ( t == NULL ) break; if ( *t == '\0' ) break; if ( c_chdir(t) != 0 ) { if ( c_mkdir(t) != 0 ) return -1; } t = strtok(NULL, C_DELIMITER_STR); } return 0; } /* 0 if successful */ int c_set_path(const char *path) { char *s = c_common_buf; char *t; c_strncpy(s, path, C_MAX_PATHNAME); #ifdef C_DOS if ( s[1] == ':' ) { c_chdrive(toupper(s[0])-'A'); s+=2; } #endif if ( *s == C_DELIMITER_CHAR ) { c_chdir(C_DELIMITER_STR); s++; } t = strtok(s, C_DELIMITER_STR); for(;;) { if ( t == NULL ) break; if ( *t == '\0' ) break; if ( c_chdir(t) != 0 ) { return -1; } t = strtok(NULL, C_DELIMITER_STR); } return 0; }