1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006-2007 Dave Chapman
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
27 #include <sys/types.h>
29 #include <sys/ioctl.h>
34 #if defined(linux) || defined (__linux)
35 #include <sys/mount.h>
36 #include <linux/hdreg.h>
37 #define IPOD_SECTORSIZE_IOCTL BLKSSZGET
39 static void get_geometry(struct ipod_t
* ipod
)
41 struct hd_geometry geometry
;
43 if (!ioctl(ipod
->dh
, HDIO_GETGEO
, &geometry
)) {
44 /* never use geometry.cylinders - it is truncated */
45 ipod
->num_heads
= geometry
.heads
;
46 ipod
->sectors_per_track
= geometry
.sectors
;
49 ipod
->sectors_per_track
= 0;
53 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
54 || defined(__bsdi__) || defined(__DragonFly__)
56 #define IPOD_SECTORSIZE_IOCTL DIOCGSECTORSIZE
58 /* TODO: Implement this function for BSD */
59 static void get_geometry(struct ipod_t
* ipod
)
61 /* Are these universal for all ipods? */
62 ipod
->num_heads
= 255;
63 ipod
->sectors_per_track
= 63;
66 #elif defined(__APPLE__) && defined(__MACH__)
68 #define IPOD_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE
70 /* TODO: Implement this function for Mac OS X */
71 static void get_geometry(struct ipod_t
* ipod
)
73 /* Are these universal for all ipods? */
74 ipod
->num_heads
= 255;
75 ipod
->sectors_per_track
= 63;
79 #error No sector-size detection implemented for this platform
82 #if defined(__APPLE__) && defined(__MACH__)
83 static int ipod_unmount(struct ipod_t
* ipod
)
88 sprintf(cmd
, "/usr/sbin/diskutil unmount \"%ss2\"",ipod
->diskname
);
89 fprintf(stderr
,"[INFO] ");
95 perror("Unmount failed");
101 void print_error(char* msg
)
106 int ipod_open(struct ipod_t
* ipod
, int silent
)
108 ipod
->dh
=open(ipod
->diskname
,O_RDONLY
);
110 if (!silent
) perror(ipod
->diskname
);
111 if(errno
== EACCES
) return -2;
115 /* Read information about the disk */
117 if(ioctl(ipod
->dh
,IPOD_SECTORSIZE_IOCTL
,&ipod
->sector_size
) < 0) {
118 ipod
->sector_size
=512;
120 fprintf(stderr
,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n"
131 int ipod_reopen_rw(struct ipod_t
* ipod
)
133 #if defined(__APPLE__) && defined(__MACH__)
134 if (ipod_unmount(ipod
) < 0)
139 ipod
->dh
=open(ipod
->diskname
,O_RDWR
);
141 perror(ipod
->diskname
);
147 int ipod_close(struct ipod_t
* ipod
)
153 int ipod_alloc_buffer(unsigned char** sectorbuf
, int bufsize
)
155 *sectorbuf
=malloc(bufsize
);
156 if (*sectorbuf
== NULL
) {
162 int ipod_seek(struct ipod_t
* ipod
, unsigned long pos
)
166 res
= lseek(ipod
->dh
, pos
, SEEK_SET
);
174 ssize_t
ipod_read(struct ipod_t
* ipod
, unsigned char* buf
, int nbytes
)
176 return read(ipod
->dh
, buf
, nbytes
);
179 ssize_t
ipod_write(struct ipod_t
* ipod
, unsigned char* buf
, int nbytes
)
181 return write(ipod
->dh
, buf
, nbytes
);