1*d5c9a868SElliott Hughes /* Copyright 1999-2003,2006,2008,2009 Alain Knaff.
2*d5c9a868SElliott Hughes * This file is part of mtools.
3*d5c9a868SElliott Hughes *
4*d5c9a868SElliott Hughes * Mtools is free software: you can redistribute it and/or modify
5*d5c9a868SElliott Hughes * it under the terms of the GNU General Public License as published by
6*d5c9a868SElliott Hughes * the Free Software Foundation, either version 3 of the License, or
7*d5c9a868SElliott Hughes * (at your option) any later version.
8*d5c9a868SElliott Hughes *
9*d5c9a868SElliott Hughes * Mtools is distributed in the hope that it will be useful,
10*d5c9a868SElliott Hughes * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*d5c9a868SElliott Hughes * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12*d5c9a868SElliott Hughes * GNU General Public License for more details.
13*d5c9a868SElliott Hughes *
14*d5c9a868SElliott Hughes * You should have received a copy of the GNU General Public License
15*d5c9a868SElliott Hughes * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
16*d5c9a868SElliott Hughes */
17*d5c9a868SElliott Hughes
18*d5c9a868SElliott Hughes #include "sysincludes.h"
19*d5c9a868SElliott Hughes #include "stream.h"
20*d5c9a868SElliott Hughes #include "llong.h"
21*d5c9a868SElliott Hughes #include "mtools.h"
22*d5c9a868SElliott Hughes
23*d5c9a868SElliott Hughes #if 1
24*d5c9a868SElliott Hughes const mt_off_t max_off_t_31 = MAX_OFF_T_B(31); /* Floppyd */
25*d5c9a868SElliott Hughes static const mt_off_t max_off_t_32 = MAX_OFF_T_B(32); /* Directory */
26*d5c9a868SElliott Hughes const mt_off_t max_off_t_41 = MAX_OFF_T_B(41); /* SCSI */
27*d5c9a868SElliott Hughes const mt_off_t max_off_t_seek = MAX_OFF_T_B(SEEK_BITS); /* SCSI */
28*d5c9a868SElliott Hughes #else
29*d5c9a868SElliott Hughes const mt_off_t max_off_t_31 = MAX_OFF_T_B(10); /* Floppyd */
30*d5c9a868SElliott Hughes const mt_off_t max_off_t_41 = MAX_OFF_T_B(10); /* SCSI */
31*d5c9a868SElliott Hughes const mt_off_t max_off_t_seek = MAX_OFF_T_B(10); /* SCSI */
32*d5c9a868SElliott Hughes #endif
33*d5c9a868SElliott Hughes
fileTooBig(mt_off_t off)34*d5c9a868SElliott Hughes int fileTooBig(mt_off_t off) {
35*d5c9a868SElliott Hughes return (off & ~max_off_t_32) != 0;
36*d5c9a868SElliott Hughes }
37*d5c9a868SElliott Hughes
38*d5c9a868SElliott Hughes /* truncMtOffToOff */
truncBytes32(mt_off_t off)39*d5c9a868SElliott Hughes off_t truncBytes32(mt_off_t off)
40*d5c9a868SElliott Hughes {
41*d5c9a868SElliott Hughes if (fileTooBig(off)) {
42*d5c9a868SElliott Hughes fprintf(stderr, "Internal error, offset too big\n");
43*d5c9a868SElliott Hughes exit(1);
44*d5c9a868SElliott Hughes }
45*d5c9a868SElliott Hughes return (off_t) off;
46*d5c9a868SElliott Hughes }
47*d5c9a868SElliott Hughes
truncMtOffTo32u(mt_off_t off)48*d5c9a868SElliott Hughes uint32_t truncMtOffTo32u(mt_off_t off)
49*d5c9a868SElliott Hughes {
50*d5c9a868SElliott Hughes if (fileTooBig(off)) {
51*d5c9a868SElliott Hughes fprintf(stderr, "Internal error, offset too big\n");
52*d5c9a868SElliott Hughes exit(1);
53*d5c9a868SElliott Hughes }
54*d5c9a868SElliott Hughes return (uint32_t) off;
55*d5c9a868SElliott Hughes }
56*d5c9a868SElliott Hughes
truncSizeTo32u(size_t siz)57*d5c9a868SElliott Hughes uint32_t truncSizeTo32u(size_t siz)
58*d5c9a868SElliott Hughes {
59*d5c9a868SElliott Hughes if (siz > UINT32_MAX) {
60*d5c9a868SElliott Hughes fprintf(stderr, "Internal error, size too big\n");
61*d5c9a868SElliott Hughes exit(1);
62*d5c9a868SElliott Hughes }
63*d5c9a868SElliott Hughes return (uint32_t) siz;
64*d5c9a868SElliott Hughes }
65*d5c9a868SElliott Hughes
66*d5c9a868SElliott Hughes #if SIZEOF_MT_OFF_T == 4
to_mt_off_t(uint32_t off)67*d5c9a868SElliott Hughes mt_off_t to_mt_off_t(uint32_t off)
68*d5c9a868SElliott Hughes {
69*d5c9a868SElliott Hughes if(off > UINT32_MAX >> 1) {
70*d5c9a868SElliott Hughes fprintf(stderr, "File size/pos %d too big for this platform\n",
71*d5c9a868SElliott Hughes off);
72*d5c9a868SElliott Hughes exit(1);
73*d5c9a868SElliott Hughes }
74*d5c9a868SElliott Hughes return (mt_off_t) off;
75*d5c9a868SElliott Hughes }
76*d5c9a868SElliott Hughes #endif
77*d5c9a868SElliott Hughes
78*d5c9a868SElliott Hughes
79*d5c9a868SElliott Hughes #if defined HAVE_LLSEEK
80*d5c9a868SElliott Hughes # ifndef HAVE_LLSEEK_PROTOTYPE
81*d5c9a868SElliott Hughes extern long long llseek (int fd, long long offset, int origin);
82*d5c9a868SElliott Hughes # endif
83*d5c9a868SElliott Hughes #endif
84*d5c9a868SElliott Hughes
85*d5c9a868SElliott Hughes #if defined HAVE_LSEEK64
86*d5c9a868SElliott Hughes # ifndef HAVE_LSEEK64_PROTOTYPE
87*d5c9a868SElliott Hughes extern long long lseek64 (int fd, long long offset, int origin);
88*d5c9a868SElliott Hughes # endif
89*d5c9a868SElliott Hughes #endif
90*d5c9a868SElliott Hughes
mt_lseek(int fd,mt_off_t where,int whence)91*d5c9a868SElliott Hughes int mt_lseek(int fd, mt_off_t where, int whence)
92*d5c9a868SElliott Hughes {
93*d5c9a868SElliott Hughes #if defined HAVE_LSEEK64
94*d5c9a868SElliott Hughes if(lseek64(fd, where, whence) >= 0)
95*d5c9a868SElliott Hughes return 0;
96*d5c9a868SElliott Hughes else
97*d5c9a868SElliott Hughes return -1;
98*d5c9a868SElliott Hughes #elif defined HAVE_LLSEEK
99*d5c9a868SElliott Hughes if(llseek(fd, where, whence) >= 0)
100*d5c9a868SElliott Hughes return 0;
101*d5c9a868SElliott Hughes else
102*d5c9a868SElliott Hughes return -1;
103*d5c9a868SElliott Hughes #else
104*d5c9a868SElliott Hughes if (lseek(fd, (off_t) where, whence) >= 0)
105*d5c9a868SElliott Hughes return 0;
106*d5c9a868SElliott Hughes else
107*d5c9a868SElliott Hughes return 1;
108*d5c9a868SElliott Hughes #endif
109*d5c9a868SElliott Hughes }
110*d5c9a868SElliott Hughes
log_2(unsigned int size)111*d5c9a868SElliott Hughes unsigned int log_2(unsigned int size)
112*d5c9a868SElliott Hughes {
113*d5c9a868SElliott Hughes unsigned int i;
114*d5c9a868SElliott Hughes
115*d5c9a868SElliott Hughes for(i=0; i<24; i++) {
116*d5c9a868SElliott Hughes if(1u << i == size)
117*d5c9a868SElliott Hughes return i;
118*d5c9a868SElliott Hughes }
119*d5c9a868SElliott Hughes return 24;
120*d5c9a868SElliott Hughes }
121