📄 port.c
字号:
cmp byte ptr [bx], 92 jne do_chmod }slash: ASSEMBLE { cmp bx, dx /* make sure it's not the only char. */ je do_chmod cmp byte ptr [bx-1], ':' /* test for the drive specifier */ je do_chmod mov [bx], al /* chop off the trailing slash */ }do_chmod: ASSEMBLE { mov ax, 0x4300 /* function: get file attributes */ int 0x21 /* DOS interrupt */ pop ds jnc no_error /* save the error code from get attr */ xor cx, cx /* if error, then zero out cx - attrs */ jmp SHORT get_out /* lets get out */ }no_error: ASSEMBLE { xor ax, ax /* if no carry, no error */ }get_out: ASSEMBLE { mov WORD PTR rc, ax /* ax contains error number on error */ mov WORD PTR attr, cx /* cx contains file attributes */ } *fattr = attr; if (ceh.flag == ERROR) rc = ERROR; return( rc );}/* * Name: set_fattr * Purpose: To set dos file attributes * Date: December 26, 1991 * Passed: fname: ASCIIZ file name. Null terminated file name * fattr: file attributes * Returns: 0 if successfull, non zero if not * Notes: Uses the DOS function to get file attributes. * Return codes: * 0 = No error * 1 = AL not 0 or 1 * 2 = file is invalid or does not exist * 3 = path is invalid or does not exist * 5 = Access denied */int set_fattr( char *fname, fattr_t fattr ){int rc; /* return code */ ASSEMBLE { push ds lds dx, fname /* get SEGMENT & OFFSET of filename */ mov cx, WORD PTR fattr /* cx contains file attributes */ mov ax, 0x4301 /* function: get file attributes */ int 0x21 /* DOS interrupt */ pop ds jc get_out /* save the error code from get attr */ xor ax, ax /* if no carry, no error */ }get_out: ASSEMBLE { mov WORD PTR rc, ax /* ax contains error number on error */ } if (ceh.flag == ERROR) rc = ERROR; return( rc );}/* * Name: get_current_directory * Purpose: get current directory * Date: February 13, 1992 * Passed: path: pointer to buffer to store path * Notes: use simple DOS interrupt * path is expected to be at least PATH_MAX long * In the interests of uniform behaviour, convert backslashes to * slashes (ie. '\' to '/') and use lower-case. Append the * directory with a final slash. * * jmh 980503: store the drive specifier as well. */int get_current_directory( char *path ){int rc; ASSEMBLE { push si /* save register vars if any */ push ds /* save ds */ lds si, DWORD PTR path /* get SEGMENT & OFFSET of path */ mov ah, 0x19 /* get default drive, 0 = a,... */ int 0x21 add al, 'a' /* make it a lowercase letter */ mov BYTE PTR [si], al /* store the drive specification */ inc si mov WORD PTR [si], ':' or ('/' shl 8) inc si inc si mov ah, 0x47 /* function 0x47 == get current dir */ mov dl, 0 /* default drive */ int 0x21 /* standard DOS interrupt */ mov ax, 0 /* return 0 if no error */ sbb ax, ax /* if carry set, then an error */ pop ds /* get back ds */ pop si /* get back si */ mov WORD PTR rc, ax /* save return code */ } if (ceh.flag == ERROR) rc = ERROR; else { unixify( path ); path += strlen( path ); if (path[-1] != '/') { *path = '/'; path[1] = '\0'; } } return( rc );}/* * Name: set_current_directory * Purpose: set current directory * Date: February 13, 1992 * Passed: new_path: directory path, which may include drive letter * Notes: use simple DOS interrupt * * jmh 021021: change drive, too; * handle the trailing (back)slash (the other OS's can handle it). */int set_current_directory( char *new_path ){int rc;char chopped = FALSE; ASSEMBLE { push ds /* save ds */ lds bx, new_path /* get SEGMENT & OFFSET of new_path */ mov dx, bx /* strip any trailing slash */ sub al, al /* NUL character */ dec bx /* prime for loop */ }find_nul: ASSEMBLE { inc bx cmp [bx], al jnz find_nul dec bx cmp BYTE PTR [bx], '/' je slash cmp BYTE PTR [bx], 92 jne ch_dir }slash: ASSEMBLE { cmp bx, dx /* make sure it's not the only char. */ je ch_dir cmp BYTE PTR [bx-1], ':' /* test for the drive specifier */ je ch_dir mov [bx], al /* chop off the trailing slash */ mov chopped, TRUE /* indicate we did so */ }ch_dir: ASSEMBLE { mov ah, 0x3b /* function 0x3b == set current dir */ int 0x21 /* standard DOS interrupt */ pushf cmp chopped, FALSE je no_slash mov BYTE PTR [bx], '/' /* too bad if it was a backslash */ }no_slash: ASSEMBLE { popf mov ax, ERROR jc get_out /* if carry set, then an error */ sub ax, ax /* no error if no drive */ mov bx, dx cmp BYTE PTR [bx+1], ':' /* drive as well? */ jne get_out mov dl, [bx] /* the drive letter */ or dl, 0x20 /* normalise to lower-case */ sub dl, 'a' /* letter to number */ mov ah, 0x0e /* function 0x0e == set default drive */ int 0x21 mov ax, 0 sbb ax, ax }get_out: ASSEMBLE { pop ds /* get back ds */ mov WORD PTR rc, ax /* save return code */ } if (ceh.flag == ERROR) rc = ERROR; return( rc );}/* * Name: get_full_path * Purpose: retrieve the fully-qualified path name for a file * Date: May 3, 1998 * Passed: in_path: path to be canonicalized * out_path: canonicalized path * Notes: out_path is assumed to be PATH_MAX characters. * out_path is converted to lower-case and backslashes to slashes. * 980511: wrote an assembly version. * 051017: remove and restore trailing slash. */void get_full_path( char *in_path, char *out_path ){int len;int slash; len = strlen( in_path ); slash = (in_path[len-1] == '/' || in_path[len-1] == '\\'); if (slash && len > 1 && in_path[len-2] != ':') in_path[len-1] = '\0'; ASSEMBLE { push ds push si push di lds si, DWORD PTR in_path /* ds:si = in_path */ les di, DWORD PTR out_path /* es:di = out_path */ mov ah, 0x60 /* function 0x60 == truename */ int 0x21 jnc get_out /* no error */ } chloop: ASSEMBLE { lodsb /* strcpy( out_path, in_path ) */ stosb test al, al jnz chloop }get_out: ASSEMBLE { pop di pop si pop ds } unixify( out_path ); if (slash) { if (in_path[len-1] == '\0') in_path[len-1] = '/'; len = strlen( out_path ); if (out_path[len-1] != '/') { out_path[len] = '/'; out_path[len+1] = '\0'; } }}/* * Name: get_ftime * Purpose: get the file's timestamp * Author: Jason Hood * Date: March 20, 2003 * Passed: fname: pointer to file's name * ftime: pointer to store the timestamp * Returns: OK if successful, ERROR if not (ftime unchanged). */int get_ftime( char *fname, ftime_t *ftime ){int rc = ERROR; ASSEMBLE { push ds lds dx, fname mov ax, 0x3d00 /* open file, read-only */ int 0x21 jc err mov bx, ax mov ax, 0x5700 /* get timestamp */ int 0x21 pushf mov ah, 0x3e /* close file */ int 0x21 popf jc err lds bx, ftime mov [bx], cx /* time */ mov [bx+2], dx /* date */ sub ax, ax mov rc, ax }err: ASSEMBLE { pop ds } return( rc );}/* * Name: set_ftime * Purpose: set the file's timestamp * Author: Jason Hood * Date: March 20, 2003 * Passed: fname: pointer to file's name * ftime: pointer to the timestamp * Returns: OK if successful, ERROR if not. */int set_ftime( char *fname, ftime_t *ftime ){int rc = ERROR; ASSEMBLE { push ds lds dx, fname mov ax, 0x3d00 /* open file, read-only */ int 0x21 jc err lds bx, ftime mov cx, [bx] /* time */ mov dx, [bx+2] /* date */ mov bx, ax mov ax, 0x5701 /* set timestamp */ int 0x21 pushf mov ah, 0x3e /* close file */ int 0x21 popf jc err sub ax, ax mov rc, ax }err: ASSEMBLE { pop ds } return( rc );}/* * Name: ftime_to_tm * Purpose: convert the file time to the tm structure * Author: Jason Hood * Date: March 20, 2003 * Passed: ftime: the file time to convert * Returns: pointer to the tm structure * Notes: only the date and time fields are set. */struct tm *ftime_to_tm( const ftime_t *ftime ){static struct tm t;unsigned int ft; ft = (unsigned int)(*ftime >> 16); t.tm_year = (ft >> 9) + 80; /* tm is from 1900, ft is from 1980 */ t.tm_mon = ((ft >> 5) & 0x0f) - 1; /* tm is from 0, ft is from 1 */ t.tm_mday = ft & 0x1f; ft = (unsigned int)(*ftime); t.tm_hour = ft >> 11; t.tm_min = (ft >> 5) & 0x3f; t.tm_sec = (ft & 0x1f) << 1; /* file time halves the seconds */ return( &t );}/* * Name: unixify * Purpose: convert a DOS path into a UNIX-like path * Author: Jason Hood * Date: June 4, 2001 * Passed: path: path to convert * Notes: backslashes are converted to slashes and letters are lowercased. */void unixify( char *path ){ ASSEMBLE { les si, path /* SI is automatically preserved */ jmp short start }uloop: ASSEMBLE { cmp al, 92 /* '\\' doesn't work & '\' stuffs up the shl */ jne is_letter mov al, '/' jmp short store }is_letter: ASSEMBLE { push ax call FAR PTR bj_tolower add sp, 2 mov es, WORD PTR path+2 }store: ASSEMBLE { mov es:[si], al inc si }start: ASSEMBLE { mov al, es:[si] test al, al jnz uloop }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -