1
1
package GNUpod::FooBar;
2
# Copyright (C) 2002-2003 Adrian Ulrich <pab at blinkenlights.ch>
2
# Copyright (C) 2002-2005 Adrian Ulrich <pab at blinkenlights.ch>
3
3
# Part of the gnupod-tools collection
5
5
# URL: http://www.gnu.org/software/gnupod/
39
38
if(-d $opth->{mount}) {
40
39
$rr->{mountpoint} = $opth->{mount};
41
40
$rr->{etc} = $opth->{mount}."/iPod_Control/.gnupod";
42
42
$rr->{xml} = $opth->{mount}."/iPod_Control/.gnupod/GNUtunesDB";
43
#It can also be called GNUtunesDB.xml
44
$rr->{xml} = $rr->{xml}.".xml" if !(-e $rr->{xml});
43
45
$rr->{itunesdb} = $opth->{mount}."/iPod_Control/iTunes/iTunesDB";
46
$rr->{itunessd} = $opth->{mount}."/iPod_Control/iTunes/iTunesSD";
44
47
$rr->{playcounts} = "$rr->{mountpoint}/iPod_Control/iTunes/Play Counts";
45
48
$rr->{itunesdb_md5} = "$rr->{etc}/.itunesdb_md5";
46
$rr->{playcounts_md5} = "$rr->{etc}/.playcounts_md5";
49
$rr->{onthego_invalid} = "$rr->{etc}/.onthego_invalid";
47
50
$rr->{onthego} = "$rr->{mountpoint}/iPod_Control/iTunes/OTGPlaylistInfo";
48
51
$rr->{status} = undef;
53
_check_casesensitive($rr->{mountpoint}); #Check if somebody mounted the iPod caseSensitive
50
55
#Do an iTunesDB Sync if not disabled and needed
51
56
do_itbsync($rr) if(!$opth->{_no_it_sync} && !$opth->{_no_sync} && _itb_needs_sync($rr));
63
68
#######################################################################
69
# Check if someone mounted the iPod CaseSensitive
70
sub _check_casesensitive {
73
if(open(CSTEST,">$target/csTeSt")) {
74
my $inode_a = (stat("$target/csTeSt"))[1]; #Get inode of just-creaded file
75
my $inode_b = (stat("$target/CStEsT"))[1]; #Get inode of another file..
76
unlink("$target/csTeSt"); #Boom!
78
if($inode_a != $inode_b) { #Whops, different inodes? -> case sensitive fs
80
warn "warning: $target seems to be mounted *CASE SENSITIVE*\n";
81
warn " Mounting VFAT/HFS+ like this is a VERY BAD(tm) idea,\n";
82
warn " strange things may happen... GNUpod may not work correctly!\n";
83
warn " Please mount the Filesystem CASE *IN*SENSITIVE\n";
84
warn " (use 'mount ... -o check=r' for VFAT)\n";
85
warn " [Ignore this message if $target isn't a\n";
86
warn " VFAT or HFS+ Filesystem ;) ]\n";
91
warn "warning: Could not write to $target, iPod mounted read-only? ($!)\n";
95
#######################################################################
68
100
my $XBIN = "$con->{bindir}/tunes2pod.pl";
71
my $OLDENV = $ENV{IPOD_MOUNTPOINT};
72
$ENV{IPOD_MOUNTPOINT} = $con->{mountpoint};
104
local $ENV{IPOD_MOUNTPOINT} = $con->{mountpoint};
73
105
print "> GNUtunesDB sync needed...\n";
74
106
if(system("$XBIN > /dev/null")) {
75
107
die "Unexpected die of $XBIN\n
76
108
You can disable auto-sync (=autorun of $XBIN)
77
109
by removing '$con->{etc}/.itunesdb_md5'\n";
80
$ENV{IPOD_MOUNTPOINT} = $OLDENV;
81
112
print "> GNUtunesDB synced\n";
95
126
my $XBIN = "$con->{bindir}/gnupod_otgsync.pl";
98
my $OLDENV = $ENV{IPOD_MOUNTPOINT};
99
$ENV{IPOD_MOUNTPOINT} = $con->{mountpoint};
130
local $ENV{IPOD_MOUNTPOINT} = $con->{mountpoint};
100
131
print "> On-The-Go data sync needed...\n";
101
132
if(system("$XBIN --top4secret")) {
102
133
warn "** UUUPS **: $XBIN died! On-The-Go list lost, sorry!\n";
143
174
# Returns '1' if we MAY have to sync..
144
175
sub _itb_needs_sync {
146
warn "debug: _itb_needs_sync called($$)\n";
147
178
if(-r $rr->{itunesdb_md5} && -r $rr->{itunesdb}) {
148
179
my $itmd = getmd5($rr->{itunesdb});
149
180
my $otmd = getmd5line($rr->{itunesdb_md5});
157
188
# Checks if we need to do an OTG-Sync
158
189
sub _otg_needs_sync {
160
warn "debug: otgsync need? (request from $$)\n";
191
#warn "debug: otgsync need? (request from $$)\n";
162
return 1 if(GNUpod::iTunesDB::readOTG($rr->{onthego}));
193
return 1 if( (-e $rr->{onthego}) && (-s $rr->{onthego}) > 0 );
164
195
if(-e $rr->{playcounts}) { #PlayCounts file exists..
165
if(-r "$rr->{playcounts_md5}") { #We got a md5 hash
166
my $plmd = getmd5line("$rr->{playcounts_md5}");
168
return 0 if $plmd eq getmd5($rr->{playcounts});
170
#Playcounts file, but no md5, parse it..
179
204
######################################################################
205
# Check for broken onTheGo data (= GNUtunesDB <-> iTunesDB out of sync)
206
sub _otgdata_broken {
208
return (-e $rr->{onthego_invalid});
211
######################################################################
212
# Set otgdata synched
213
sub setvalid_otgdata {
215
return undef unless -e $rr->{onthego_invalid};
216
unlink($rr->{onthego_invalid});
218
######################################################################
219
# Set otgdata synched
220
sub setINvalid_otgdata {
222
open(OTGINVALID, ">$rr->{onthego_invalid}") or die "Can't write $rr->{onthego_invalid}\n";
223
print OTGINVALID undef;
229
######################################################################
194
244
setsync_itunesdb($rr);
195
245
setsync_playcounts($rr);
247
setvalid_otgdata($rr);
250
######################################################################
251
# SetSync for onthego
256
if( !(-e $rr->{onthego}) || unlink($rr->{onthego})) {
260
warn "Could not setsync for onthego\n";
198
264
######################################################################
199
265
# Set only playcounts in sync
200
266
sub setsync_playcounts {
202
warn "**** playcounts setsync call $$\n";
203
#We also create an MD5 sum of the playcounts file
204
if(-r $rr->{playcounts}) { #Test this, because getmd5 would die
205
open(MDX,">$rr->{playcounts_md5}") or die "Can't write pc-md5-sum, $!\n";
206
print MDX getmd5($rr->{playcounts});
269
if( !(-e $rr->{playcounts}) || unlink($rr->{playcounts})) {
210
273
warn "Can't set sync for playcounts to true: file not found\n";
307
########################################################################
308
# Parse configuration
310
my($getopts, $doset, $name) = @_;
312
my($topic,$val,$optarget);
314
foreach my $filerc ( ("$ENV{HOME}/.gnupodrc", "$getopts->{mount}/iPod_Control/.gnupod/gnupodrc") ) {
315
open(RCFILE, $filerc) or next;
316
while (my $line = <RCFILE>) {
318
next if !$line or $line =~ /^#/;
320
#Ok, line is not a comment and has some content, read it..
321
unless(($topic,$val) = $line =~ /^(\S+)\s*=\s*(.+)$/) {
322
warn "warning: Invalid line '$line' found in $filerc\n";
326
#We matched and got $topic + $val, check it $topic has a
327
#specific target (like 'mktunes.volume')
328
if($topic =~ /^([^.]+)\.(.+)/) {
332
else { #No target found
336
# warn "### PARSE($line): *$topic* -> *$val*\n";
337
# warn "### $topic with target $optarget\n";
339
if ($optarget&&$name&&$name ne $optarget) { next}
340
elsif ($getopts->{$topic}) { next } #this is a dup
341
elsif ($doset->{$topic} eq "s") { $getopts->{$topic} = $val }
342
elsif ($doset->{$topic} eq "i") { $getopts->{$topic} = int($val) }
343
elsif ($doset->{$topic} eq "b") { $getopts->{$topic} = 1 if($val && $val ne "no") }
346
# warn "** Parser finished $filerc\n";
349
# foreach(keys(%$getopts)) {
350
# warn "CONF: $_ - $getopts->{$_}\n";