[BACK]Return to backup.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sbin / gpt

Annotation of src/sbin/gpt/backup.c, Revision 1.1.6.2

1.1       jnemeth     1: /*-
                      2:  * Copyright (c) 2002 Marcel Moolenaar
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  *
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     17:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     18:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     19:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     20:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     21:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     22:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     23:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     24:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
1.1.6.1   snj        27: #if HAVE_NBTOOL_CONFIG_H
                     28: #include "nbtool_config.h"
                     29: #endif
                     30:
1.1       jnemeth    31: #include <sys/cdefs.h>
                     32: #ifdef __FBSDID
                     33: __FBSDID("$FreeBSD: src/sbin/gpt/show.c,v 1.14 2006/06/22 22:22:32 marcel Exp $");
                     34: #endif
                     35: #ifdef __RCSID
1.1.6.2 ! martin     36: __RCSID("$NetBSD: backup.c,v 1.18 2017/09/07 10:23:33 christos Exp $");
1.1       jnemeth    37: #endif
                     38:
                     39: #include <sys/bootblock.h>
                     40: #include <sys/types.h>
                     41:
                     42: #include <err.h>
                     43: #include <stddef.h>
                     44: #include <stdio.h>
                     45: #include <stdlib.h>
                     46: #include <string.h>
                     47: #include <unistd.h>
                     48: #include <prop/proplib.h>
                     49:
                     50: #include "map.h"
                     51: #include "gpt.h"
1.1.6.2 ! martin     52: #include "gpt_private.h"
1.1       jnemeth    53:
1.1.6.2 ! martin     54: static const char *backuphelp[] = {
        !            55:        "[-o outfile]",
        !            56: };
1.1       jnemeth    57:
1.1.6.2 ! martin     58: static int cmd_backup(gpt_t, int, char *[]);
1.1       jnemeth    59:
1.1.6.2 ! martin     60: struct gpt_cmd c_backup = {
        !            61:        "backup",
        !            62:        cmd_backup,
        !            63:        backuphelp, __arraycount(backuphelp),
        !            64:        GPT_READONLY,
        !            65: };
        !            66:
        !            67: #define usage() gpt_usage(NULL, &c_backup)
        !            68:
        !            69: #define PROP_ERR(x)    if (!(x)) goto cleanup
        !            70:
        !            71: #define prop_uint(a) prop_number_create_unsigned_integer(a)
        !            72:
        !            73: static int
        !            74: store_mbr(gpt_t gpt, unsigned int i, const struct mbr *mbr,
        !            75:     prop_array_t *mbr_array)
1.1       jnemeth    76: {
1.1.6.2 ! martin     77:        prop_dictionary_t mbr_dict;
        !            78:        prop_number_t propnum;
        !            79:        const struct mbr_part *par = &mbr->mbr_part[i];
        !            80:        bool rc;
1.1       jnemeth    81:
1.1.6.2 ! martin     82:        if (mbr->mbr_part[i].part_typ == MBR_PTYPE_UNUSED)
        !            83:                return 0;
        !            84:
        !            85:        mbr_dict = prop_dictionary_create();
        !            86:        PROP_ERR(mbr_dict);
        !            87:        propnum = prop_number_create_integer(i);
        !            88:        PROP_ERR(propnum);
        !            89:        rc = prop_dictionary_set(mbr_dict, "index", propnum);
        !            90:        PROP_ERR(rc);
        !            91:        propnum = prop_uint(par->part_flag);
        !            92:        PROP_ERR(propnum);
        !            93:        rc = prop_dictionary_set(mbr_dict, "flag", propnum);
        !            94:        PROP_ERR(rc);
        !            95:        propnum = prop_uint(par->part_shd);
        !            96:        PROP_ERR(propnum);
        !            97:        rc = prop_dictionary_set(mbr_dict, "start_head", propnum);
        !            98:        PROP_ERR(rc);
        !            99:        propnum = prop_uint(par->part_ssect);
        !           100:        PROP_ERR(propnum);
        !           101:        rc = prop_dictionary_set(mbr_dict, "start_sector", propnum);
        !           102:        PROP_ERR(rc);
        !           103:        propnum = prop_uint(par->part_scyl);
        !           104:        PROP_ERR(propnum);
        !           105:        rc = prop_dictionary_set(mbr_dict, "start_cylinder", propnum);
        !           106:        PROP_ERR(rc);
        !           107:        propnum = prop_uint(par->part_typ);
        !           108:        PROP_ERR(propnum);
        !           109:        rc = prop_dictionary_set(mbr_dict, "type", propnum);
        !           110:        PROP_ERR(rc);
        !           111:        propnum = prop_uint(par->part_ehd);
        !           112:        PROP_ERR(propnum);
        !           113:        rc = prop_dictionary_set(mbr_dict, "end_head", propnum);
        !           114:        PROP_ERR(rc);
        !           115:        propnum = prop_uint(par->part_esect);
        !           116:        PROP_ERR(propnum);
        !           117:        rc = prop_dictionary_set(mbr_dict, "end_sector", propnum);
        !           118:        PROP_ERR(rc);
        !           119:        propnum = prop_uint(par->part_ecyl);
        !           120:        PROP_ERR(propnum);
        !           121:        rc = prop_dictionary_set(mbr_dict, "end_cylinder", propnum);
        !           122:        PROP_ERR(rc);
        !           123:        propnum = prop_uint(le16toh(par->part_start_lo));
        !           124:        PROP_ERR(propnum);
        !           125:        rc = prop_dictionary_set(mbr_dict, "lba_start_low", propnum);
        !           126:        PROP_ERR(rc);
        !           127:        propnum = prop_uint(le16toh(par->part_start_hi));
        !           128:        PROP_ERR(propnum);
        !           129:        rc = prop_dictionary_set(mbr_dict, "lba_start_high", propnum);
        !           130:        PROP_ERR(rc);
        !           131:        propnum = prop_uint(le16toh(par->part_size_lo));
        !           132:        PROP_ERR(propnum);
        !           133:        rc = prop_dictionary_set(mbr_dict, "lba_size_low", propnum);
        !           134:        PROP_ERR(rc);
        !           135:        propnum = prop_uint(le16toh(par->part_size_hi));
        !           136:        PROP_ERR(propnum);
        !           137:        rc = prop_dictionary_set(mbr_dict, "lba_size_high", propnum);
        !           138:        if (*mbr_array == NULL) {
        !           139:                *mbr_array = prop_array_create();
        !           140:                PROP_ERR(*mbr_array);
        !           141:        }
        !           142:        rc = prop_array_add(*mbr_array, mbr_dict);
        !           143:        PROP_ERR(rc);
        !           144:        return 0;
        !           145: cleanup:
        !           146:        if (mbr_dict)
        !           147:                prop_object_release(mbr_dict);
        !           148:        gpt_warnx(gpt, "proplib failure");
        !           149:        return -1;
1.1       jnemeth   150: }
                    151:
1.1.6.2 ! martin    152: static int
        !           153: store_gpt(gpt_t gpt, const struct gpt_hdr *hdr, prop_dictionary_t *type_dict)
        !           154: {
        !           155:        prop_number_t propnum;
        !           156:        prop_string_t propstr;
        !           157:        char buf[128];
        !           158:        bool rc;
        !           159:
        !           160:        *type_dict = prop_dictionary_create();
        !           161:        PROP_ERR(type_dict);
        !           162:        propnum = prop_uint(le32toh(hdr->hdr_revision));
        !           163:        PROP_ERR(propnum);
        !           164:        rc = prop_dictionary_set(*type_dict, "revision", propnum);
        !           165:        PROP_ERR(rc);
        !           166:        gpt_uuid_snprintf(buf, sizeof(buf), "%d", hdr->hdr_guid);
        !           167:        propstr = prop_string_create_cstring(buf);
        !           168:        PROP_ERR(propstr);
        !           169:        rc = prop_dictionary_set(*type_dict, "guid", propstr);
        !           170:        PROP_ERR(rc);
        !           171:        propnum = prop_number_create_integer(le32toh(hdr->hdr_entries));
        !           172:        PROP_ERR(propnum);
        !           173:        rc = prop_dictionary_set(*type_dict, "entries", propnum);
        !           174:        PROP_ERR(rc);
        !           175:        return 0;
        !           176: cleanup:
        !           177:        if (*type_dict)
        !           178:                prop_object_release(*type_dict);
        !           179:        return -1;
        !           180: }
        !           181:
        !           182: static int
        !           183: store_tbl(gpt_t gpt, const map_t m, prop_dictionary_t *type_dict)
        !           184: {
        !           185:        const struct gpt_ent *ent;
        !           186:        unsigned int i;
        !           187:        prop_dictionary_t gpt_dict;
        !           188:        prop_array_t gpt_array;
        !           189:        prop_number_t propnum;
        !           190:        prop_string_t propstr;
        !           191:        char buf[128];
        !           192:        uint8_t utfbuf[__arraycount(ent->ent_name) * 3 + 1];
        !           193:        bool rc;
        !           194:
        !           195:        *type_dict = NULL;
        !           196:
        !           197:        gpt_array = prop_array_create();
        !           198:        PROP_ERR(gpt_array);
        !           199:
        !           200:        *type_dict = prop_dictionary_create();
        !           201:        PROP_ERR(*type_dict);
        !           202:
        !           203:        ent = m->map_data;
        !           204:        for (i = 1, ent = m->map_data;
        !           205:            (const char *)ent < (const char *)(m->map_data) +
        !           206:            m->map_size * gpt->secsz; i++, ent++) {
        !           207:                gpt_dict = prop_dictionary_create();
        !           208:                PROP_ERR(gpt_dict);
        !           209:                propnum = prop_number_create_integer(i);
        !           210:                PROP_ERR(propnum);
        !           211:                rc = prop_dictionary_set(gpt_dict, "index", propnum);
        !           212:                PROP_ERR(propnum);
        !           213:                gpt_uuid_snprintf(buf, sizeof(buf), "%d", ent->ent_type);
        !           214:                propstr = prop_string_create_cstring(buf);
        !           215:                PROP_ERR(propstr);
        !           216:                rc = prop_dictionary_set(gpt_dict, "type", propstr);
        !           217:                gpt_uuid_snprintf(buf, sizeof(buf), "%d", ent->ent_guid);
        !           218:                propstr = prop_string_create_cstring(buf);
        !           219:                PROP_ERR(propstr);
        !           220:                rc = prop_dictionary_set(gpt_dict, "guid", propstr);
        !           221:                PROP_ERR(propstr);
        !           222:                propnum = prop_uint(le64toh(ent->ent_lba_start));
        !           223:                PROP_ERR(propnum);
        !           224:                rc = prop_dictionary_set(gpt_dict, "start", propnum);
        !           225:                PROP_ERR(rc);
        !           226:                propnum = prop_uint(le64toh(ent->ent_lba_end));
        !           227:                PROP_ERR(rc);
        !           228:                rc = prop_dictionary_set(gpt_dict, "end", propnum);
        !           229:                PROP_ERR(rc);
        !           230:                propnum = prop_uint(le64toh(ent->ent_attr));
        !           231:                PROP_ERR(propnum);
        !           232:                rc = prop_dictionary_set(gpt_dict, "attributes", propnum);
        !           233:                PROP_ERR(rc);
        !           234:                utf16_to_utf8(ent->ent_name, __arraycount(ent->ent_name),
        !           235:                    utfbuf, __arraycount(utfbuf));
        !           236:                if (utfbuf[0] != '\0') {
        !           237:                        propstr = prop_string_create_cstring((char *)utfbuf);
        !           238:                        PROP_ERR(propstr);
        !           239:                        rc = prop_dictionary_set(gpt_dict, "name", propstr);
        !           240:                        PROP_ERR(rc);
        !           241:                }
        !           242:                rc = prop_array_add(gpt_array, gpt_dict);
        !           243:                PROP_ERR(rc);
1.1       jnemeth   244:        }
1.1.6.2 ! martin    245:        rc = prop_dictionary_set(*type_dict, "gpt_array", gpt_array);
        !           246:        PROP_ERR(rc);
        !           247:        prop_object_release(gpt_array);
        !           248:        return 0;
        !           249: cleanup:
        !           250:        if (*type_dict)
        !           251:                prop_object_release(*type_dict);
        !           252:        if (gpt_array)
        !           253:                prop_object_release(gpt_array);
        !           254:        return -1;
        !           255: }
1.1       jnemeth   256:
1.1.6.2 ! martin    257: static int
        !           258: backup(gpt_t gpt, const char *outfile)
1.1       jnemeth   259: {
1.1.6.2 ! martin    260:        map_t m;
1.1       jnemeth   261:        struct mbr *mbr;
                    262:        unsigned int i;
1.1.6.2 ! martin    263:        prop_dictionary_t props, type_dict;
        !           264:        prop_array_t mbr_array;
1.1       jnemeth   265:        prop_data_t propdata;
                    266:        prop_number_t propnum;
1.1.6.2 ! martin    267:        char *propext;
1.1       jnemeth   268:        bool rc;
1.1.6.2 ! martin    269:        FILE *fp;
1.1       jnemeth   270:
                    271:        props = prop_dictionary_create();
                    272:        PROP_ERR(props);
1.1.6.2 ! martin    273:        propnum = prop_number_create_integer(gpt->secsz);
1.1.6.1   snj       274:        PROP_ERR(propnum);
                    275:        rc = prop_dictionary_set(props, "sector_size", propnum);
                    276:        PROP_ERR(rc);
1.1.6.2 ! martin    277:        m = map_first(gpt);
1.1       jnemeth   278:        while (m != NULL) {
                    279:                switch (m->map_type) {
                    280:                case MAP_TYPE_MBR:
                    281:                case MAP_TYPE_PMBR:
                    282:                        type_dict = prop_dictionary_create();
                    283:                        PROP_ERR(type_dict);
                    284:                        mbr = m->map_data;
                    285:                        propdata = prop_data_create_data_nocopy(mbr->mbr_code,
                    286:                            sizeof(mbr->mbr_code));
                    287:                        PROP_ERR(propdata);
                    288:                        rc = prop_dictionary_set(type_dict, "code", propdata);
                    289:                        PROP_ERR(rc);
                    290:                        mbr_array = NULL;
                    291:                        for (i = 0; i < 4; i++) {
1.1.6.2 ! martin    292:                                if (store_mbr(gpt, i, mbr, &mbr_array) == -1)
        !           293:                                        goto cleanup;
1.1       jnemeth   294:                        }
                    295:                        if (mbr_array != NULL) {
                    296:                                rc = prop_dictionary_set(type_dict,
                    297:                                    "mbr_array", mbr_array);
                    298:                                PROP_ERR(rc);
                    299:                                prop_object_release(mbr_array);
                    300:                        }
                    301:                        rc = prop_dictionary_set(props, "MBR", type_dict);
                    302:                        PROP_ERR(rc);
                    303:                        prop_object_release(type_dict);
                    304:                        break;
                    305:                case MAP_TYPE_PRI_GPT_HDR:
1.1.6.2 ! martin    306:                        if (store_gpt(gpt, m->map_data, &type_dict) == -1)
        !           307:                                goto cleanup;
        !           308:
1.1       jnemeth   309:                        rc = prop_dictionary_set(props, "GPT_HDR", type_dict);
                    310:                        PROP_ERR(rc);
                    311:                        prop_object_release(type_dict);
                    312:                        break;
                    313:                case MAP_TYPE_PRI_GPT_TBL:
1.1.6.2 ! martin    314:                        if (store_tbl(gpt, m, &type_dict) == -1)
        !           315:                                goto cleanup;
1.1       jnemeth   316:                        rc = prop_dictionary_set(props, "GPT_TBL", type_dict);
                    317:                        PROP_ERR(rc);
                    318:                        prop_object_release(type_dict);
                    319:                        break;
                    320:                }
                    321:                m = m->map_next;
                    322:        }
                    323:        propext = prop_dictionary_externalize(props);
                    324:        PROP_ERR(propext);
                    325:        prop_object_release(props);
1.1.6.2 ! martin    326:        fp = strcmp(outfile, "-") == 0 ? stdout : fopen(outfile, "w");
        !           327:        if (fp == NULL) {
        !           328:                gpt_warn(gpt, "Can't open `%s'", outfile);
        !           329:                free(propext);
        !           330:                goto cleanup;
        !           331:        }
        !           332:        fputs(propext, fp);
        !           333:        if (fp != stdout)
        !           334:                fclose(fp);
1.1.6.1   snj       335:        free(propext);
1.1.6.2 ! martin    336:        return 0;
        !           337: cleanup:
        !           338:        if (props)
        !           339:                prop_object_release(props);
        !           340:        return -1;
1.1       jnemeth   341: }
                    342:
1.1.6.2 ! martin    343: static int
        !           344: cmd_backup(gpt_t gpt, int argc, char *argv[])
1.1       jnemeth   345: {
1.1.6.2 ! martin    346:        int ch;
        !           347:        const char *outfile = "-";
1.1       jnemeth   348:
1.1.6.2 ! martin    349:        while ((ch = getopt(argc, argv, "o:")) != -1) {
        !           350:                switch(ch) {
        !           351:                case 'o':
        !           352:                        outfile = optarg;
        !           353:                        break;
        !           354:                default:
        !           355:                        return usage();
1.1       jnemeth   356:                }
                    357:        }
1.1.6.2 ! martin    358:        if (argc != optind)
        !           359:                return usage();
1.1       jnemeth   360:
1.1.6.2 ! martin    361:        return backup(gpt, outfile);
1.1       jnemeth   362: }

CVSweb <webmaster@jp.NetBSD.org>