1/*
2 * cvt_pt.c
3 *
4 *	Convert partition type.
5 *
6 *	Copyright (c)  1999, Eryk Vershen
7 *
8 * History:
9 * Log: cvt_pt.c,v
10 * Revision 1.2  2000/05/16 13:56:11  eryk
11 * Minor fixes
12 *
13 * Revision 1.1  2000/02/13 22:04:08  eryk
14 * Initial revision
15 *
16 */
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <stdarg.h>
22#include <errno.h>
23#include <ctype.h>
24
25#include "partition_map.h"
26#include "errors.h"
27
28
29/*
30 * Defines / Constants
31 */
32#define CFLAG_DEFAULT	0
33#define DFLAG_DEFAULT	0
34#define HFLAG_DEFAULT	0
35#define INTERACT_DEFAULT	0
36#define RFLAG_DEFAULT	0
37
38
39/*
40 * Structs / Types
41 */
42
43
44/*
45 * Global variables
46 */
47int hflag = HFLAG_DEFAULT;	/* show help */
48int dflag = DFLAG_DEFAULT;	/* turn on debugging commands and printout */
49int rflag = RFLAG_DEFAULT;	/* open device read Only */
50int interactive = INTERACT_DEFAULT;
51int cflag = CFLAG_DEFAULT;	/* compute device size */
52
53
54/*
55 * Forward declarations
56 */
57void process(char *filename);
58
59
60/*
61 * Start here ...
62 */
63int
64main(int argc, char **argv)
65{
66    register int i;
67#ifdef notdef
68    register int c;
69    extern char *optarg;	/* pointer to argument */
70    extern int optind;		/* next argv index */
71    extern int opterr;		/* who does error messages */
72    extern int optopt;		/* char that caused the error */
73    int getopt_error;		/* getopt choked */
74    char option_error[100];	/* buffer for error message */
75    char *arg_option = 0;
76    int bool_option = 0;
77#else
78    int optind = 1;
79#endif
80
81    init_program_name(argv);
82
83#ifdef notdef
84    opterr = 0;	/* tell getopt to be quiet */
85
86    /*
87     * Changes to getopt's last argument should
88     * be reflected in the string printed by the
89     * usage() function.
90     */
91    while ((c = getopt(argc, argv, "a:b")) != EOF) {
92	if (c == '?') {
93	    getopt_error = 1;
94	    c = optopt;
95	} else {
96	    getopt_error = 0;
97	}
98
99	switch (c) {
100	case 'a':
101	    if (getopt_error) {
102		usage("missing argument");
103	    } else {
104		arg_option = optarg;
105	    }
106	    break;
107	case 'b':
108	    bool_option = 1;
109	    break;
110	default:
111	    snprintf(option_error, sizeof(option_error),
112	        "no such option as -%c", c);
113	    usage(option_error);
114	}
115    }
116#endif
117
118    if (optind >= argc) {
119	usage("no file argument");
120    }
121    for (i = optind ; i < argc; i++) {
122	process(argv[i]);
123    }
124    return 0;
125}
126
127
128int
129trim_num(char *s)
130{
131    char *t;
132    int n;
133
134    for (t = s; *t; t++) {
135    }
136
137    for (t--; t >= s; t--) {
138        if (!isdigit((unsigned char)*t)) {
139            t++;
140            if (*t) {
141                n = atoi(t);
142                *t = 0;
143            } else {
144                n = -1;
145            }
146            return n;
147        }
148    }
149
150    return -1;
151}
152
153/*
154 * The operation to apply to each file ...
155 */
156void
157process(char *filename)
158{
159    char *s;
160    int index;
161    partition_map_header *map;
162    int valid_file;
163    partition_map * entry;
164
165    //printf("Processing %s\n", filename);
166
167    // 1)       strip off number from end of filename
168    s = strdup(filename);
169    index = trim_num(s);
170
171    if (index < 0) {
172        fatal(-1, "%s does not end in a number", filename);
173    }
174
175    // 2)       open prefix of filename as partition map
176    map = open_partition_map(s, &valid_file, 0);
177    if (!valid_file) {
178        fatal(-1, "%s does not have a partition map", s);
179        return;
180    }
181
182    // 3)       verify the type for the partition;
183
184    if (map->writable == 0) {
185	fatal(-1, "The map is not writable");
186        return;
187    }
188
189    // 4) find partition and change it
190    entry = find_entry_by_disk_address(index, map);
191    if (entry == NULL) {
192	fatal(-1, "No such partition");
193    } else if (strcmp(entry->data->dpme_type, kHFSType) != 0) {
194	fatal(-1, "Can't convert a partition with type %s",
195		entry->data->dpme_type);
196    } else {
197	// 4a)       modify the type
198	strncpy(entry->data->dpme_type, kUnixType, DPISTRLEN);
199
200	// 5)       and write back.
201	write_partition_map(map);
202    }
203}
204