summaryrefslogtreecommitdiffstats
path: root/rbutil/sansapatcher/sansaio-posix.c
blob: d173fbc300b01e8634f133c6d22f84e89f53f3a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2006-2007 Dave Chapman
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

#if !defined(_WIN32) /* all non-Windows platforms supported are POSIX. */
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <errno.h>

#if defined(linux) || defined (__linux)
#include <sys/mount.h>
#define SANSA_SECTORSIZE_IOCTL BLKSSZGET
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
      || defined(__bsdi__) || defined(__DragonFly__)
#include <sys/disk.h>
#define SANSA_SECTORSIZE_IOCTL DIOCGSECTORSIZE
#elif defined(__APPLE__) && defined(__MACH__)
#include <sys/disk.h>
#define SANSA_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE
#else
    #error No sector-size detection implemented for this platform
#endif

#include "sansaio.h"

#if defined(__APPLE__) && defined(__MACH__)
static int sansa_unmount(struct sansa_t* sansa)
{
    char cmd[4096];
    int res;

    sprintf(cmd, "/usr/sbin/diskutil unmount \"%ss1\"",sansa->diskname);
    fprintf(stderr,"[INFO] ");
    res = system(cmd);

    if (res==0) {
        return 0;
    } else {
        perror("Unmount failed");
        return -1;
    }
}
#endif


void sansa_print_error(char* msg)
{
    perror(msg);
}

int sansa_open(struct sansa_t* sansa, int silent)
{
    sansa->dh=open(sansa->diskname,O_RDONLY);
    if (sansa->dh < 0) {
        if (!silent) perror(sansa->diskname);
        if(errno == EACCES) return -2;
        else return -1;
    }

    if(ioctl(sansa->dh,SANSA_SECTORSIZE_IOCTL,&sansa->sector_size) < 0) {
        sansa->sector_size=512;
        if (!silent) {
            fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n"
                   ,sansa->sector_size);
        }
    }
    return 0;
}


int sansa_reopen_rw(struct sansa_t* sansa)
{
#if defined(__APPLE__) && defined(__MACH__)
    if (sansa_unmount(sansa) < 0)
        return -1;
#endif

    close(sansa->dh);
    sansa->dh=open(sansa->diskname,O_RDWR);
    if (sansa->dh < 0) {
        perror(sansa->diskname);
        return -1;
    }
    return 0;
}

int sansa_close(struct sansa_t* sansa)
{
    close(sansa->dh);
    return 0;
}

int sansa_alloc_buffer(struct sansa_t *sansa, int bufsize)
{
    sansa->sectorbuf=malloc(bufsize);
    if (sansa->sectorbuf == NULL) {
        return -1;
    }
    return 0;
}

int sansa_seek(struct sansa_t* sansa, loff_t pos)
{
    off_t res;

    res = lseek64(sansa->dh, pos, SEEK_SET);

    if (res == -1) {
       return -1;
    }
    return 0;
}

int sansa_read(struct sansa_t* sansa, unsigned char* buf, int nbytes)
{
    return read(sansa->dh, buf, nbytes);
}

int sansa_write(struct sansa_t* sansa, int nbytes)
{
    return write(sansa->dh, sansa->sectorbuf, nbytes);
}
#endif