Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / install / libcaptive-install / proc_partitions.c
1 /* $Id$
2  * /proc/partitions file reader for installers of captive
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #undef FALSE
23 #undef TRUE
24 #include <ntfs/types.h> /* for 'FALSE'/'TRUE' libntfs definition */
25 #define FALSE FALSE
26 #define TRUE TRUE
27
28 #include "proc_partitions.h"    /* self */
29 #include <glib/gmessages.h>
30 #include <popt.h>
31 #include <locale.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <mntent.h>
35 #include <glib/ghash.h>
36 #include <glib/gstrfuncs.h>
37 #include <sys/stat.h>
38 #include <errno.h>
39 #include <unistd.h>
40
41 #include <captive/macros.h>
42
43 #include <ntfs/volume.h>
44
45
46 /* Config: */
47 #define FILENAME_PROC_PARTITIONS  "/proc/partitions"
48
49
50 static void proc_partitions_ntfs_hash_key_destroy_func(gchar *device)
51 {
52         g_return_if_fail(device!=NULL);
53
54         g_free(device);
55 }
56
57 static void proc_partitions_ntfs_hash_value_destroy_func(gchar *vol_name)
58 {
59         g_return_if_fail(vol_name!=NULL);
60
61         g_free(vol_name);
62 }
63
64
65 GHashTable *proc_partitions_ntfs_hash_get(gboolean msg_verbose)
66 {
67 FILE *fpartitions;
68 gchar line[LINE_MAX];
69 gint lineno;
70 /* map: (gchar *)device -> (gchar *)vol_name */
71 GHashTable *proc_partitions_ntfs_hash;
72
73         proc_partitions_ntfs_hash=g_hash_table_new_full(g_str_hash,g_str_equal,
74                         (GDestroyNotify)proc_partitions_ntfs_hash_key_destroy_func,
75                         (GDestroyNotify)proc_partitions_ntfs_hash_value_destroy_func);
76
77         if (!(fpartitions=fopen(FILENAME_PROC_PARTITIONS,"r")))
78                 g_error(_("Cannot open \"%s\": %m"),FILENAME_PROC_PARTITIONS);
79         lineno=0;
80         while (fgets(line,sizeof(line),fpartitions)) {
81 unsigned major,minor;
82 unsigned long long blocks;
83 char device[strlen("/dev/")+100];
84 ntfs_volume *volume;
85
86                 lineno++;
87                 if (lineno<=2)
88                         continue;
89                 if (!*line || *line=='\n') {
90                         /* At least RedHat Linux kernel 2.4.18-18.8.0 sometimes appends
91                          * bogus empty line at the end of file.
92                          */
93                         continue;
94                         }
95                 if (4!=sscanf(line,"%u%u%llu%100s",&major,&minor,&blocks,device+strlen("/dev/"))) {
96                         g_warning(_("Error parsing line of \"%s\" (Linux kernel bug): %s"),FILENAME_PROC_PARTITIONS,line);
97                         continue;
98                         }
99                 memcpy(device,"/dev/",strlen("/dev/"));
100                 if (!(volume=ntfs_mount(device,MS_RDONLY))) {
101                         if (msg_verbose)
102                                 g_message(_("not ntfs: %s"),device);
103                         continue;
104                         }
105                 if (msg_verbose)
106                         g_message(_("FOUND ntfs: %s\t%s"),device,volume->vol_name);
107                 g_hash_table_insert(proc_partitions_ntfs_hash,g_strdup(device),g_strdup(volume->vol_name));
108                 if (ntfs_umount(volume,
109                                 TRUE))  /* force; close even if it would mean data loss */
110                         g_warning(_("Error unmounting volume: %s"),device);
111                 }
112         if (fclose(fpartitions))
113                 g_warning(_("Cannot close \"%s\": %m"),FILENAME_PROC_PARTITIONS);
114         return proc_partitions_ntfs_hash;
115 }