kernel: Use hashdestroy() to free hash tables allocated with hashinit().
[dragonfly.git] / usr.bin / doscmd / dos.h
1 /*
2  * Copyright (c) 1992, 1993, 1996
3  *      Berkeley Software Design, Inc.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Berkeley Software
16  *      Design, Inc.
17  *
18  * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *      BSDI dos.h,v 2.2 1996/04/08 19:32:28 bostic Exp
31  *
32  * $FreeBSD: src/usr.bin/doscmd/dos.h,v 1.2.2.1 2002/04/25 11:04:51 tg Exp $
33  * $DragonFly: src/usr.bin/doscmd/dos.h,v 1.3 2008/10/03 19:56:11 swildner Exp $
34  */
35
36 /*
37  * DOS Error codes
38  */
39 /* MS-DOS version 2 error codes */
40 #define FUNC_NUM_IVALID         0x01
41 #define FILE_NOT_FOUND          0x02
42 #define PATH_NOT_FOUND          0x03
43 #define TOO_MANY_OPEN_FILES     0x04
44 #define ACCESS_DENIED           0x05
45 #define HANDLE_INVALID          0x06
46 #define MEM_CB_DEST             0x07
47 #define INSUF_MEM               0x08
48 #define MEM_BLK_ADDR_IVALID     0x09
49 #define ENV_INVALID             0x0a
50 #define FORMAT_INVALID          0x0b
51 #define ACCESS_CODE_INVALID     0x0c
52 #define DATA_INVALID            0x0d
53 #define UNKNOWN_UNIT            0x0e
54 #define DISK_DRIVE_INVALID      0x0f
55 #define ATT_REM_CUR_DIR         0x10
56 #define NOT_SAME_DEV            0x11
57 #define NO_MORE_FILES           0x12
58 /* mappings to critical-error codes */
59 #define WRITE_PROT_DISK         0x13
60 #define UNKNOWN_UNIT_CERR       0x14
61 #define DRIVE_NOT_READY         0x15
62 #define UNKNOWN_COMMAND         0x16
63 #define DATA_ERROR_CRC          0x17
64 #define BAD_REQ_STRUCT_LEN      0x18
65 #define SEEK_ERROR              0x19
66 #define UNKNOWN_MEDIA_TYPE      0x1a
67 #define SECTOR_NOT_FOUND        0x1b
68 #define PRINTER_OUT_OF_PAPER    0x1c
69 #define WRITE_FAULT             0x1d
70 #define READ_FAULT              0x1e
71 #define GENERAL_FAILURE         0x1f
72
73 /* MS-DOS version 3 and later extended error codes */
74 #define SHARING_VIOLATION       0x20
75 #define FILE_LOCK_VIOLATION     0x21
76 #define DISK_CHANGE_INVALID     0x22
77 #define FCB_UNAVAILABLE         0x23
78 #define SHARING_BUF_EXCEEDED    0x24
79
80 #define NETWORK_NAME_NOT_FOUND  0x35
81
82 #define FILE_ALREADY_EXISTS     0x50
83
84 #define DUPLICATE_REDIR         0x55
85
86 /*
87  * dos attribute byte flags
88  */
89 #define REGULAR_FILE    0x00    
90 #define READ_ONLY_FILE  0x01    
91 #define HIDDEN_FILE     0x02    
92 #define SYSTEM_FILE     0x04    
93 #define VOLUME_LABEL    0x08    
94 #define DIRECTORY       0x10    
95 #define ARCHIVE_NEEDED  0x20    
96
97 /*
98  * Internal structure used for get_space()
99  */
100 typedef struct {
101     long        bytes_sector;
102     long        sectors_cluster;
103     long        total_clusters;
104     long        avail_clusters;
105 } fsstat_t;
106
107 /*
108  * Several DOS structures used by the file redirector
109  */
110
111 typedef struct {
112     DIR         *dp;
113     u_char      *searchend;
114     u_char      searchdir[1024];
115 } search_t;
116
117 /*
118  * This is really the format of the DTA.  The file redirector will only
119  * use the first 21 bytes.
120  */
121 typedef struct {
122     u_char      drive;
123     u_char      pattern[11];
124     u_char      flag;
125     u_char      reserved1[4];
126     search_t    *searchptr;
127     u_char      attr;
128     u_short     time;
129     u_short     date;
130     u_long      size;
131     u_char      name[13];
132 } __packed find_block_t;
133
134 /*
135  * DOS directory entry structure
136  */
137 typedef struct {
138     u_char      name[8];
139     u_char      ext[3];
140     u_char      attr;
141     u_char      reserved[10];
142     u_short     time;
143     u_short     date;
144     u_short     start;
145     u_long      size;
146 } __packed dosdir_t;
147
148 /*
149  * The Current Drive Structure
150  */
151 typedef struct {
152         u_char  path[0x43];
153         u_short flag;
154         u_short dpb_off;
155         u_short dpb_seg;
156         u_short redirector_off;
157         u_short redirector_seg;
158         u_char  paramter_int21[2];
159         u_short offset;
160         u_char  dummy;
161         u_char  ifs_driver[4];
162         u_char  dummy2[2];
163 } __packed CDS;
164
165 #define CDS_remote      0x8000
166 #define CDS_ready       0x4000
167 #define CDS_joined      0x2000
168 #define CDS_substed     0x1000
169
170 #define CDS_notnet      0x0080
171
172 /* 
173  * The List of Lists (used to get the CDS and a few other numbers)
174  */
175 typedef struct {
176         u_char  dummy1[0x16];
177         u_short cds_offset;
178         u_short cds_seg;
179         u_char  dummy2[6];
180         u_char  numberbdev;
181         u_char  lastdrive;
182 } __packed LOL;
183
184 /*
185  * The System File Table
186  */
187 typedef struct {
188 /*00*/  u_short nfiles;         /* Number file handles referring to this file */
189 /*02*/  u_short open_mode;      /* Open mode (bit 15 -> by FCB) */
190 /*04*/  u_char  attribute;
191 /*05*/  u_short info;           /* 15 -> remote, 14 ->  dont set date */
192 /*07*/  u_char  ddr_dpb[4];     /* Device Driver Header/Drive Paramter Block */
193 /*0b*/  u_short fd;
194 /*0d*/  u_short time;
195 /*0f*/  u_short date;
196 /*11*/  u_long  size;
197 /*15*/  u_long  offset;
198 /*19*/  u_short rel_cluster;
199 /*1b*/  u_short abs_cluster;
200 /*1d*/  u_char  dir_sector[2];
201 /*1f*/  u_char  dir_entry;
202 /*20*/  u_char  name[8];
203 /*28*/  u_char  ext[3];
204 /*2b*/  u_char  sharesft[4];
205 /*2f*/  u_char  sharenet[2];
206 /*31*/  u_short psp;
207 /*33*/  u_char  share_off[2];
208 /*35*/  u_char  local_end[2];
209 /*37*/  u_char  ifd_driver[4]; 
210 } __packed SFT;
211
212 /*
213  * Format of PCDOS 4.01 swappable data area
214  * (Sorry, but you need a wide screen to make this look nice)
215  */
216 typedef struct {
217     u_char      err_crit;       /*   00h    BYTE    critical error flag */
218     u_char      InDOS;          /*   01h    BYTE    InDOS flag (count of active INT 21 calls) */
219     u_char      err_drive;      /*   02h    BYTE    ??? drive number or FFh */
220     u_char      err_locus;      /*   03h    BYTE    locus of last error */
221     u_short     err_code;       /*   04h    WORD    extended error code of last error */
222     u_char      err_suggest;    /*   06h    BYTE    suggested action for last error */
223     u_char      err_class;      /*   07h    BYTE    class of last error */
224     u_short     err_di;
225     u_short     err_es;         /*   08h    DWORD   ES:DI pointer for last error */
226     u_short     dta_off;
227     u_short     dta_seg;        /*   0Ch    DWORD   current DTA */
228     u_short     psp;            /*   10h    WORD    current PSP */
229     u_short     int_23_sp;      /*   12h    WORD    stores SP across an INT 23 */
230     u_short     wait_status;    /*   14h    WORD    return code from last process termination (zerod after reading with AH=4Dh) */
231     u_char      current_drive;  /*   16h    BYTE    current drive */
232     u_char      break_flag;     /*   17h    BYTE    extended break flag */
233     u_char      unknown1[2];    /*   18h  2 BYTEs   ??? */
234     u_short     int_21_ax;      /*   1Ah    WORD    value of AX on call to INT 21 */
235     u_short     net_psp;        /*   1Ch    WORD    PSP segment for sharing/network */
236     u_short     net_number;     /*   1Eh    WORD    network machine number for sharing/network (0000h = us) */
237     u_short     first_mem;      /*   20h    WORD    first usable memory block found when allocating memory */
238     u_short     best_mem;       /*   22h    WORD    best usable memory block found when allocating memory */
239     u_short     last_mem;       /*   24h    WORD    last usable memory block found when allocating memory */
240     u_char      unknown[10];    /*   26h  2 BYTEs   ??? (don't seem to be referenced) */
241     u_char      monthday;       /*   30h    BYTE    day of month */
242     u_char      month;          /*   31h    BYTE    month */
243     u_short     year;           /*   32h    WORD    year - 1980 */
244     u_short     days;           /*   34h    WORD    number of days since 1-1-1980 */
245     u_char      weekday;        /*   36h    BYTE    day of week (0 = Sunday) */
246     u_char      unknown2[3];    /*   37h    BYTE    ??? */
247     u_char      ddr_head[30];   /*   38h 30 BYTEs   device driver request header */
248     u_short     ddre_ip;
249     u_short     ddre_cs;        /*   58h    DWORD   pointer to device driver entry point (used in calling driver) */
250     u_char      ddr_head2[22];  /*   5Ch 22 BYTEs   device driver request header */
251     u_char      ddr_head3[30];  /*   72h 30 BYTEs   device driver request header */
252     u_char      unknown3[6];    /*   90h  6 BYTEs   ??? */
253     u_char      clock_xfer[6];  /*   96h  6 BYTEs   CLOCK$ transfer record (see AH=52h) */
254     u_char      unknown4[2];    /*   9Ch  2 BYTEs   ??? */
255     u_char      filename1[128]; /*   9Eh 128 BYTEs  buffer for filename */
256     u_char      filename2[128]; /*  11Eh 128 BYTEs  buffer for filename */
257     u_char      findfirst[21];  /*  19Eh 21 BYTEs   findfirst/findnext search data block (see AH=4Eh) */
258     u_char      foundentry[32]; /*  1B3h 32 BYTEs   directory entry for found file */
259     u_char      cds[88];        /*  1D3h 88 BYTEs   copy of current directory structure for drive being accessed */
260     u_char      fcbname[11];    /*  22Bh 11 BYTEs   ??? FCB-format filename */
261     u_char      unknown5;       /*  236h    BYTE    ??? */
262     u_char      wildcard[11];   /*  237h 11 BYTEs   wildcard destination specification for rename (FCB format) */
263     u_char      unknown6[11];   /*  242h  2 BYTEs   ??? */
264     u_char      attrmask;       /*  24Dh    BYTE    attribute mask for directory search??? */
265     u_char      open_mode;      /*  24Eh    BYTE    open mode */
266     u_char      unknown7[3];    /*  24fh    BYTE    ??? */
267     u_char      virtual_dos;    /*  252h    BYTE    flag indicating how DOS function was invoked (00h = direct INT 20/INT 21, FFh = server call AX=5D00h) */
268     u_char      unknown8[9];    /*  253h    BYTE    ??? */
269     u_char      term_type;      /*  25Ch    BYTE    type of process termination (00h-03h) */
270     u_char      unknown9[3];    /*  25Dh    BYTE    ??? */
271     u_short     dpb_off;
272     u_short     dpb_seg;        /*  260h    DWORD   pointer to Drive Parameter Block for critical error invocation */
273     u_short     int21_sf_off;
274     u_short     int21_sf_seg;   /*  264h    DWORD   pointer to stack frame containing user registers on INT 21 */
275     u_short     store_sp;       /*  268h    WORD    stores SP??? */
276     u_short     dosdpb_off;
277     u_short     dosdpb_seg;     /*  26Ah    DWORD   pointer to DOS Drive Parameter Block for ??? */
278     u_short     disk_buf_seg;   /*  26Eh    WORD    segment of disk buffer */
279     u_short     unknown10[4];   /*  270h    WORD    ??? */
280     u_char      media_id;       /*  278h    BYTE    Media ID byte returned by AH=1Bh,1Ch */
281     u_char      unknown11;      /*  279h    BYTE    ??? (doesn't seem to be referenced) */
282     u_short     unknown12[2];   /*  27Ah    DWORD   pointer to ??? */
283     u_short     sft_off;
284     u_short     sft_seg;        /*  27Eh    DWORD   pointer to current SFT */
285     u_short     cds_off;
286     u_short     cds_seg;        /*  282h    DWORD   pointer to current directory structure for drive being accessed */
287     u_short     fcb_off;
288     u_short     fcb_seg;        /*  286h    DWORD   pointer to caller's FCB */
289     u_short     unknown13[2];   /*  28Ah    WORD    ??? */
290     u_short     jft_off;
291     u_short     jft_seg;        /*  28Eh    DWORD   pointer to a JFT entry in process handle table (see AH=26h) */
292     u_short     filename1_off;  /*  292h    WORD    offset in DOS CS of first filename argument */
293     u_short     filename2_off;  /*  294h    WORD    offset in DOS CS of second filename argument */
294     u_short     unknown14[12];  /*  296h    WORD    ??? */
295     u_short     file_offset_lo;
296     u_short     file_offset_hi; /*  2AEh    DWORD   offset in file??? */
297     u_short     unknown15;      /*  2B2h    WORD    ??? */
298     u_short     partial_bytes;  /*  2B4h    WORD    bytes in partial sector */
299     u_short     number_sectors; /*  2B6h    WORD    number of sectors */
300     u_short     unknown16[3];   /*  2B8h    WORD    ??? */
301     u_short     nbytes_lo;
302     u_short     nbytes_hi;      /*  2BEh    DWORD   number of bytes appended to file */
303     u_short     qpdb_off;
304     u_short     qpdb_seg;       /*  2C2h    DWORD   pointer to ??? disk buffer */
305     u_short     asft_off;
306     u_short     asft_seg;       /*  2C6h    DWORD   pointer to ??? SFT */
307     u_short     int21_bx;       /*  2CAh    WORD    used by INT 21 dispatcher to store caller's BX */
308     u_short     int21_ds;       /*  2CCh    WORD    used by INT 21 dispatcher to store caller's DS */
309     u_short     temporary;      /*  2CEh    WORD    temporary storage while saving/restoring caller's registers */
310     u_short     prevcall_off;
311     u_short     prevcall_seg;   /*  2D0h    DWORD   pointer to prev call frame (offset 264h) if INT 21 reentered also switched to for duration of INT 24 */
312     u_char      unknown17[9];   /*  2D4h    WORD    ??? */
313     u_short     ext_action;     /*  2DDh    WORD    multipurpose open action */
314     u_short     ext_attr;       /*  2DFh    WORD    multipurpose attribute */
315     u_short     ext_mode;       /*  2E1h    WORD    multipurpose mode */
316     u_char      unknown17a[9];
317     u_short     lol_ds;         /*  2ECh    WORD    stores DS during call to [List-of-Lists + 37h] */
318     u_char      unknown18[5];   /*  2EEh    WORD    ??? */
319     u_char      usernameptr[4]; /*  2F3h    DWORD   pointer to user-supplied filename */
320     u_char      unknown19[4];   /*  2F7h    DWORD   pointer to ??? */
321     u_char      lol_ss[2];      /*  2FBh    WORD    stores SS during call to [List-of-Lists + 37h] */
322     u_char      lol_sp[2];      /*  2FDh    WORD    stores SP during call to [List-of-Lists + 37h] */
323     u_char      lol_flag;       /*  2FFh    BYTE    flag, nonzero if stack switched in calling [List-of-Lists+37h] */
324     u_char      searchdata[21]; /*  300h 21 BYTEs   FindFirst search data for source file(s) of a rename operation (see AH=4Eh) */
325     u_char      renameentry[32];/*  315h 32 BYTEs   directory entry for file being renamed */
326     u_char      errstack[331];  /*  335h 331 BYTEs  critical error stack */
327     u_char      diskstack[384]; /*  480h 384 BYTEs  disk stack (functions greater than 0Ch, INT 25, INT 26) */
328     u_char      iostack[384];   /*  600h 384 BYTEs  character I/O stack (functions 01h through 0Ch) */
329     u_char      int_21_08_flag; /*  780h    BYTE    flag affecting AH=08h (see AH=64h) */
330     u_char      unknown20[11];  /*  781h    BYTE    ??? looks like a drive number */
331 } __packed SDA;
332
333 struct exehdr {
334         u_short magic;
335         u_short bytes_on_last_page;
336         u_short size; /* 512 byte blocks */
337         u_short nreloc;
338         u_short hdr_size; /* paragraphs */
339         u_short min_memory; /* paragraphs */
340         u_short max_memory; /* pargraphs */
341         u_short init_ss;
342         u_short init_sp;
343         u_short checksum;
344         u_short init_ip;
345         u_short init_cs;
346         u_short reloc_offset;
347         u_short overlay_num;
348 };
349
350 struct reloc_entry {
351         u_short off;
352         u_short seg;
353 };
354
355
356 /*
357 ** DOS-related shrapnel
358 */
359
360 static inline int
361 from_dos_attr(int attr)
362 {
363     return((attr & READ_ONLY_FILE) ? 0444 : 0666);
364 }
365
366 static inline int
367 to_dos_attr(int mode)
368 {
369     int         attr;
370
371     attr = (mode & 0200) ? 0:READ_ONLY_FILE;
372     attr |= S_ISDIR(mode) ? DIRECTORY:0;
373     return(attr);
374 }
375
376 /* prototypes */
377
378 extern const char       *dos_return[];  /* names of DOS return codes */
379 extern const int        dos_ret_size;   /* length of above */
380 extern char             *InDOS;
381 extern int              diskdrive;      /* current drive */
382 unsigned long           disk_transfer_addr;
383
384 extern void             encode_dos_file_time (time_t, u_short *, u_short *);
385 extern time_t           decode_dos_file_time(u_short dosdate, u_short dostime);
386 extern int              translate_filename(u_char *dname, u_char *uname, int *drivep);
387 extern int              parse_filename(int flag, char *str, char *fcb, int *nb);
388 extern void             dos_init(void);
389
390 /* from exe.c */
391 extern int      pspseg;                 /* segment # of PSP */
392 extern int      curpsp;
393
394 extern void     exec_command(regcontext_t *REGS, int run, int fd, char *cmdname, u_short *param);
395 extern void     load_overlay(int fd, int start_segment, int reloc_segment);
396 extern void     load_command(regcontext_t *REGS, int run, int fd, char *cmdname, 
397                              u_short *param, char **argv, char **envs);
398 extern void     exec_return(regcontext_t *REGS, int code);
399 extern int      get_env(void);