As a owner of an iPod, I had a problem when I moved to Linux on my desktop, as Apple does not provide iTunes for Linux. After some digging around I found gtkPod, which is a linux iPod tool.
My iPod is originally an Mac iPod, but I converted it almost immidiatly after I got, so that I could use ephPod. This is due to this fact that if you have an Mac iPod you might find that some of the information here can be a little bit incorrect (See Updates).
With this tutorial, I will try to give you the steps to build the gtkpod, as an RPM package for Fedora.
"gtkpod is a platform independent GUI for Apple's iPod using GTK2. It allows you to upload songs and playlists to your iPod. It supports ID3 tag editing, multiple charsets for ID3 tags, detects duplicate songs, allows offline modification of the database with later synchronisation, and more."
[casper@localhost casper]$ cd rpmbuild/SPECS [casper@localhost SPECS]$
[casper@localhost SPECS]$ rpmbuild -ba gtkpod.spec Executing(%prep): /bin/sh -e /home/casper/rpmbuild/TMP/rpm-tmp.41992 + umask 022 + cd /home/casper/rpmbuild//BUILD + LANG=C + export LANG + unset DISPLAY + cd /home/casper/rpmbuild/BUILD + rm -rf gtkpod-0.72-2 + /usr/bin/gzip -dc /home/casper/rpmbuild/SOURCES/gtkpod-0.72-2.tar.gz + tar -xf - + STATUS=0 + '[' 0 -ne 0 ']' + cd gtkpod-0.72-2 ++ /usr/bin/id -u + '[' 1002 = 0 ']' ++ /usr/bin/id -u + '[' 1002 = 0 ']' + /bin/chmod -Rf a+rX,g-w,o-w . + exit 0 Executing(%build): /bin/sh -e /home/casper/rpmbuild/TMP/rpm-tmp.41992 + umask 022 + cd /home/casper/rpmbuild//BUILD + cd gtkpod-0.72-2 + LANG=C + export LANG + unset DISPLAY + CFLAGS=-O2 -g -pipe -march=i386 -mcpu=i686 + export CFLAGS + CXXFLAGS=-O2 -g -pipe -march=i386 -mcpu=i686 + export CXXFLAGS + FFLAGS=-O2 -g -pipe -march=i386 -mcpu=i686 + export FFLAGS ++ find . -name config.guess -o -name config.sub ++ basename ./config.guess + '[' -f /usr/lib/rpm/redhat/config.guess ']' + /bin/rm -f ./config.guess ++ basename ./config.guess + /bin/cp -fv /usr/lib/rpm/redhat/config.guess ./config.guess `/usr/lib/rpm/redhat/config.guess' -> `./config.guess' ++ basename ./config.sub + '[' -f /usr/lib/rpm/redhat/config.sub ']' + /bin/rm -f ./config.sub ++ basename ./config.sub + /bin/cp -fv /usr/lib/rpm/redhat/config.sub ./config.sub `/usr/lib/rpm/redhat/config.sub' -> `./config.sub' + ./configure --host=i686-pc-linux-gnu --build=i686-pc-linux-gnu --target=i386-redhat-linux-gnu --program-prefix= --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include --libdir=/usr/lib --libexecdir=/usr/libexec --localstatedir=/var --sharedstatedir=/usr/com --mandir=/usr/share/man --infodir=/usr/share/info checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for gawk... gawk checking whether make sets $(MAKE)... yes checking whether to enable maintainer-specific portions of Makefiles... no checking build system type... i686-pc-linux-gnu checking host system type... i686-pc-linux-gnu checking for style of include used by make... GNU checking for i686-pc-linux-gnu-gcc... no checking for gcc... gcc checking for C compiler default output file name... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ANSI C... none needed checking dependency style of gcc... gcc3 checking for strerror in -lcposix... no checking for i686-pc-linux-gnu-gcc... gcc checking whether we are using the GNU C compiler... (cached) yes checking whether gcc accepts -g... (cached) yes checking for gcc option to accept ANSI C... (cached) none needed checking dependency style of gcc... (cached) gcc3 checking for gcc option to accept ANSI C... none needed checking for pkg-config... /usr/bin/pkg-config checking for gtk+-2.0 >= 2.0.0 gthread-2.0 >= 0.14.0 glib-2.0 > 2.0.0... yes checking PACKAGE_CFLAGS... -pthread -I/usr/include/gtk-2.0 -I/usr/lib/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/pango-1.0 -I/usr/X11R6/include -I/usr/include/freetype2 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include checking PACKAGE_LIBS... -Wl,--export-dynamic -pthread -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangoxft-1.0 -lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -ldl -lgthread-2.0 -lglib-2.0 checking for flex... flex checking for yywrap in -lfl... yes checking lex output file root... lex.yy checking whether yytext is a pointer... yes checking how to run the C preprocessor... gcc -E checking for egrep... grep -E checking for ANSI C header files... yes checking for sys/types.h... yes checking for sys/stat.h... yes checking for stdlib.h... yes checking for string.h... yes checking for memory.h... yes checking for strings.h... yes checking for inttypes.h... yes ..... Requires(interp): /bin/sh /bin/sh Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Requires(post): /bin/sh Requires(postun): /bin/sh Requires: gettext id3lib libatk-1.0.so.0 libc.so.6 libc.so.6(GLIBC_2.0) libc.so.6(GLIBC_2.1) libc.so.6(GLIBC_2.2) libc.so.6(GLIBC_2.3) libdl.so.2 libgdk-x11-2.0.so.0 libgdk_pixbuf-2.0.so.0 libglib-2.0.so.0 libgmodule-2.0.so.0 libgobject-2.0.so.0 libgthread-2.0.so.0 libgtk-x11-2.0.so.0 libid3tag libid3tag.so.0 libm.so.6 libpango-1.0.so.0 libpangox-1.0.so.0 libpangoxft-1.0.so.0 libpthread.so.0 libpthread.so.0(GLIBC_2.0) Processing files: gtkpod-debuginfo-0.72-2.1.fdr Requires(rpmlib): rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/casper/rpmbuild/TMP/gtkpod-0.72-root Wrote: /home/casper/rpmbuild/SRPMS/gtkpod-0.72-2.1.fdr.src.rpm Wrote: /home/casper/rpmbuild/RPMS/i386/gtkpod-0.72-2.1.fdr.i386.rpm Wrote: /home/casper/rpmbuild/RPMS/i386/gtkpod-debuginfo-0.72-2.1.fdr.i386.rpm Executing(%clean): /bin/sh -e /home/casper/rpmbuild/TMP/rpm-tmp.44467 + umask 022 + cd /home/casper/rpmbuild//BUILD + cd gtkpod-0.72-2 + rm -rf /home/casper/rpmbuild/TMP/gtkpod-0.72-root + exit 0 [casper@localhost SPECS]$
[casper@localhost SPECS]$ su -c "rpm -ivh ../RPMS/i386/gtkpod-0.72-2.1.fdr.i386.rpm" Password: Preparing... ########################################### [100%] 1:gtkpod ########################################### [100%] [casper@localhost SPECS]$
[casper@localhost casper]$ lsmod | grep sbp2 sbp2 20780 0 (unused) ieee1394 208164 0 [sbp2 ohci1394] scsi_mod 113640 5 [sbp2 sg usb-storage ata_piix libata sd_mod] [casper@tuxdsk casper]$
[casper@localhost casper]$ su -c "/sbin/fdisk -l" Password: Disk /dev/hda: 61.4 GB, 61492838400 bytes 16 heads, 63 sectors/track, 119150 cylinders Units = cylinders of 1008 * 512 = 516096 bytes Device Boot Start End Blocks Id System /dev/hda1 * x xxx xxxxxx+ 83 Linux /dev/hda2 xxx xxxxx xxxxxxxx 83 Linux /dev/hda3 xxxxx xxxxx xxxxxxx 82 Linux swap /dev/hda4 xxxxx xxxxxx xxxxxxxx f Win95 Ext'd (LBA) /dev/hda5 xxxxx xxxxxx xxxxxxxx+ 83 Linux [casper@localhost casper]$Stop!! It's not there, and this is because SCSI did not update the devices. To fix this download rescan-scsi-bus.sh and run it:
[casper@localhost casper]$ su -c "rescan-scsi-bus.sh" Password: Host adapter 0 (ata_piix) found. Host adapter 1 (ata_piix) found. Host adapter 3 (sbp2_1) found. Host adapter 2 (usb-storage-0) found. Scanning hosts 0 1 3 2 channels 0 for SCSI target IDs 0 1 2 3 4 5 6 7 , LUNs 0 Scanning for device 3 0 0 0 ... NEW: Host: scsi3 Channel: 00 Id: 00 Lun: 00 Vendor: Apple Model: iPod Rev: 1.30 Type: Direct-Access ANSI SCSI revision: 02 Scanning for device 2 0 0 0 ... 1 new device(s) found. 0 device(s) removed. [casper@localhost casper]$Now you should have a SCSI disk:
[casper@tuxdsk casper]$ su -c "/sbin/fdisk -l" Password: Disk /dev/sda: 10.0 GB, 10000005120 bytes 255 heads, 63 sectors/track, 1215 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Device Boot Start End Blocks Id System /dev/sda1 * 1 5 40131 0 Empty /dev/sda2 * 6 1215 9719325 b Win95 FAT32 ..... [casper@localhost casper]$I know from earlier experience that something bad will happen if I mount sdb1, therefor do not mount sdb1!!
[casper@localhost casper]$ su -c "mkdir -p /mnt/ipod"
[casper@localhost casper]$ su -c "mount -t vfat /dev/sda2 /mnt/ipod" Password: [casper@localhost casper]$
[casper@localhost casper]$ ls /mnt/ipod autorun.inf Calendars Contacts iPod_Control [casper@localhost casper]$
[casper@localhost casper]$ su -c "umount /mnt/ipod" Password: [casper@localhost casper]$Then modify /etc/fstab, and add the following
/dev/sda2 /mnt/ipod vfat user,noauto,umask=0 0 0Which enable you to mount it as an unpriviledged user (root), and you will have write access to it.
[casper@localhost casper]$ mount /mnt/ipod [casper@localhost casper]$ ls -l /mnt/ipod [casper@localhost casper]$ ls -l /mnt/ipod total 20 -rwxrwxrwx 1 casper users 24 Mar 29 2003 autorun.inf drwxrwxrwx 2 casper users 4096 Jan 1 1980 Calendars drwxrwxrwx 2 casper users 4096 Jan 1 1980 Contacts drwxrwxrwx 5 casper users 4096 Sep 7 2002 iPod_Control [casper@localhost casper]$Cool!!
[casper@localhost casper]$ su -c "/sbin/rmmod sbp2" Password: [casper@localhost casper]$This is what I do, if someone have an better way to do it, please let me know, and I will add the information here.
Legal notice
iTunes and iPod are trademarks of Apple.
UPDATED 2004-06-14
I got an email from Jorg Schuler, who pointed me to to ars technica which has an interesting discussion about auto-mouting.
I have not looked at but, I'll update this as soon as it happens.
UPDATED 2004-03-21
I've updated the .spec file, BuildRequires was missing '-devel' on the package names. New version is 0.72-2.2. There is no need to rebuild the package if you already did it.
I've got some suggestions on how to eject the iPod.