1 /*
2  * pathname.c -
3  *
4  * Written by Eryk Vershen
5  */
6 
7 /*
8  * Copyright 1997,1998 by Apple Computer, Inc.
9  *              All Rights Reserved
10  *
11  * Permission to use, copy, modify, and distribute this software and
12  * its documentation for any purpose and without fee is hereby granted,
13  * provided that the above copyright notice appears in all copies and
14  * that both the copyright notice and this permission notice appear in
15  * supporting documentation.
16  *
17  * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
18  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE.
20  *
21  * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
22  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
23  * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
24  * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
25  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26  */
27 
28 
29 // for strncmp()
30 #include <string.h>
31 #include <stdint.h>
32 
33 #include "pathname.h"
34 #include "file_media.h"
35 
36 #if !defined(__linux__) && !defined(__unix__)
37 #include "SCSI_media.h"
38 #include "ATA_media.h"
39 #endif
40 
41 
42 /*
43  * Defines
44  */
45 
46 
47 /*
48  * Types
49  */
50 
51 
52 /*
53  * Global Constants
54  */
55 
56 
57 /*
58  * Global Variables
59  */
60 
61 
62 /*
63  * Forward declarations
64  */
65 
66 
67 /*
68  * Routines
69  */
70 
71 /*
72  * Note that open_pathname_as_media() and get_linux_name() have almost
73  * identical structures.  If one changes the other must also!
74  */
75 MEDIA
open_pathname_as_media(char * path,int oflag)76 open_pathname_as_media(char *path, int oflag)
77 {
78     MEDIA m = 0;
79 #if !defined(__linux__) && !defined(__unix__)
80     long  id;
81     long  bus;
82 
83     if (strncmp("/dev/", path, 5) == 0) {
84           if (strncmp("/dev/scsi", path, 9) == 0) {
85               if (path[9] >= '0' && path[9] <= '7' && path[10] == 0) {
86                     // scsi[0-7]
87                     id = path[9] - '0';
88                     m = open_old_scsi_as_media(id);
89               } else if (path[9] >= '0' && path[9] <= '7' && path[10] == '.'
90                         && path[11] >= '0' && path[11] <= '7' && path[12] == 0) {
91                     // scsi[0-7].[0-7]
92                     id = path[11] - '0';
93                     bus = path[9] - '0';
94                     m = open_scsi_as_media(bus, id);
95               }
96           } else if (strncmp("/dev/ata", path, 8) == 0
97                     || strncmp("/dev/ide", path, 8) == 0) {
98               if (path[8] >= '0' && path[8] <= '7' && path[9] == 0) {
99                     // ata[0-7], ide[0-7]
100                     bus = path[8] - '0';
101                     m = open_ata_as_media(bus, 0);
102               } else if (path[8] >= '0' && path[8] <= '7' && path[9] == '.'
103                         && path[10] >= '0' && path[10] <= '1' && path[11] == 0) {
104                     // ata[0-7].[0-1], ide[0-7].[0-1]
105                     id = path[10] - '0';
106                     bus = path[8] - '0';
107                     m = open_ata_as_media(bus, id);
108               }
109           } else if (strncmp("/dev/sd", path, 7) == 0) {
110               if (path[7] >= 'a' && path[7] <= 'z' && path[8] == 0) {
111                     // sd[a-z]
112                     id = path[7] - 'a';
113                     m = open_linux_scsi_as_media(id, 0);
114               } else if (path[7] >= 'a' && path[7] <= 'z' && path[8] == '.'
115                         && path[9] >= 'a' && path[9] <= 'z' && path[10] == 0) {
116                     // sd[a-z][a-z]
117                     bus = path[7] - 'a';
118                     id = path[9] - 'a';
119                     id += bus * 26;
120                     m = open_linux_scsi_as_media(id, 0);
121               }
122           } else if (strncmp("/dev/scd", path, 8) == 0) {
123               if (path[8] >= '0' && path[8] <= '9' && path[9] == 0) {
124                     // scd[0-9]
125                     id = path[8] - '0';
126                     m = open_linux_scsi_as_media(id, 1);
127               }
128           } else if (strncmp("/dev/hd", path, 7) == 0) {
129               if (path[7] >= 'a' && path[7] <= 'z' && path[8] == 0) {
130                     // hd[a-z]
131                     id = path[7] - 'a';
132                     m = open_linux_ata_as_media(id);
133               }
134           }
135     } else
136 #endif
137 
138     {
139           m = open_file_as_media(path, oflag);
140     }
141     return m;
142 }
143 
144 
145 char *
get_linux_name(char * path)146 get_linux_name(char *path)
147 {
148     char  *result = 0;
149 #if !defined(__linux__) && !defined(__unix__)
150     long  id;
151     long  bus;
152 
153     if (strncmp("/dev/", path, 5) == 0) {
154           if (strncmp("/dev/scsi", path, 9) == 0) {
155               if (path[9] >= '0' && path[9] <= '7' && path[10] == 0) {
156                     /* old scsi */
157                     // scsi[0-7]
158                     id = path[9] - '0';
159                     result = linux_old_scsi_name(id);
160               } else if (path[9] >= '0' && path[9] <= '7' && path[10] == '.'
161                         && path[11] >= '0' && path[11] <= '7' && path[12] == 0) {
162                     /* new scsi */
163                     // scsi[0-7].[0-7]
164                     id = path[11] - '0';
165                     bus = path[9] - '0';
166                     result = linux_scsi_name(bus, id);
167               }
168           } else if (strncmp("/dev/ata", path, 8) == 0
169                     || strncmp("/dev/ide", path, 8) == 0) {
170               if (path[8] >= '0' && path[8] <= '7' && path[9] == 0) {
171                     /* ata/ide - master device */
172                     // ata[0-7], ide[0-7]
173                     bus = path[8] - '0';
174                     result = linux_ata_name(bus, 0);
175               } else if (path[8] >= '0' && path[8] <= '7' && path[9] == '.'
176                         && path[10] >= '0' && path[10] <= '1' && path[11] == 0) {
177                     /* ata/ide */
178                     // ata[0-7].[0-1], ide[0-7].[0-1]
179                     id = path[10] - '0';
180                     bus = path[8] - '0';
181                     result = linux_ata_name(bus, id);
182               }
183           }
184     }
185 #endif
186 
187     return result;
188 }
189 
190 
191 MEDIA_ITERATOR
first_media_kind(long * state)192 first_media_kind(long *state)
193 {
194     *state = 0;
195     return next_media_kind(state);
196 }
197 
198 
199 MEDIA_ITERATOR
next_media_kind(long * state)200 next_media_kind(long *state)
201 {
202     MEDIA_ITERATOR result;
203     long ix;
204 
205     result = 0;
206     ix = *state;
207 
208     switch (ix) {
209     case 0:
210 #if defined(__linux__) || defined(__unix__)
211           result = create_file_iterator();
212 #endif
213           ix = 1;
214           if (result != 0) {
215                     break;
216           }
217           /* fall through to next interface */
218 
219     case 1:
220 #if !defined(__linux__) && !defined(__unix__)
221           result = create_ata_iterator();
222 #endif
223           ix = 2;
224           if (result != 0) {
225                     break;
226           }
227           /* fall through to next interface */
228 
229     case 2:
230 #if !defined(__linux__) && !defined(__unix__)
231           result = create_scsi_iterator();
232 #endif
233           ix = 3;
234           if (result != 0) {
235                     break;
236           }
237           /* fall through to next interface */
238 
239     case 3:
240     default:
241           break;
242     }
243 
244     *state = ix;
245     return result;
246 }
247 
248 
249