1 #include "libxlu_internal.h"
2 #include "libxlu_disk_l.h"
3 #include "libxlu_disk_i.h"
4 #include "libxlu_cfg_i.h"
5 
xlu__disk_err(DiskParseContext * dpc,const char * erroneous,const char * message)6 void xlu__disk_err(DiskParseContext *dpc, const char *erroneous,
7                    const char *message) {
8     fprintf(dpc->cfg->report,
9             "%s: config parsing error in disk specification: %s"
10             "%s%s%s"
11             " in `%s'\n",
12             dpc->cfg->config_source, message,
13             erroneous?": near `":"", erroneous?erroneous:"", erroneous?"'":"",
14             dpc->spec);
15     if (!dpc->err) dpc->err= EINVAL;
16 }
17 
dpc_prep(DiskParseContext * dpc,const char * spec)18 static int dpc_prep(DiskParseContext *dpc, const char *spec) {
19     int e;
20 
21     dpc->spec = spec;
22 
23     e = xlu__disk_yylex_init_extra(dpc, &dpc->scanner);
24     if (e) goto fail;
25 
26     dpc->buf = xlu__disk_yy_scan_bytes(spec, strlen(spec), dpc->scanner);
27     if (!dpc->buf) { e = ENOMEM; goto fail; }
28 
29     return 0;
30 
31  fail:
32     fprintf(dpc->cfg->report, "cannot init disk scanner: %s\n",
33             strerror(errno));
34     return e;
35 }
36 
dpc_dispose(DiskParseContext * dpc)37 static void dpc_dispose(DiskParseContext *dpc) {
38     if (dpc->buf) {
39         xlu__disk_yy_delete_buffer(dpc->buf, dpc->scanner);
40         dpc->buf = 0;
41     }
42     if (dpc->scanner) {
43         xlu__disk_yylex_destroy(dpc->scanner);
44         dpc->scanner = 0;
45     }
46 }
47 
xlu_disk_parse(XLU_Config * cfg,int nspecs,const char * const * specs,libxl_device_disk * disk)48 int xlu_disk_parse(XLU_Config *cfg,
49                    int nspecs, const char *const *specs,
50                    libxl_device_disk *disk) {
51     DiskParseContext dpc;
52     int i, e;
53 
54     memset(&dpc,0,sizeof(dpc));
55     dpc.cfg = cfg;
56     dpc.scanner = 0;
57     dpc.disk = disk;
58 
59     disk->readwrite = 1;
60 
61     for (i=0; i<nspecs; i++) {
62         e = dpc_prep(&dpc, specs[i]);
63         if (e) { dpc.err = e; goto x_err; }
64 
65         xlu__disk_yylex(dpc.scanner);
66         assert(!e);
67         if (dpc.err) goto x_err;
68 
69         dpc_dispose(&dpc);
70     }
71 
72     if (disk->format == LIBXL_DISK_FORMAT_UNKNOWN) {
73         disk->format = LIBXL_DISK_FORMAT_RAW;
74     }
75     if (disk->is_cdrom) {
76         disk->removable = 1;
77         disk->readwrite = 0;
78         if (!disk->pdev_path || !strcmp(disk->pdev_path, ""))
79             disk->format = LIBXL_DISK_FORMAT_EMPTY;
80     }
81 
82     if (!disk->vdev) {
83         xlu__disk_err(&dpc,0, "no vdev specified");
84         goto x_err;
85     }
86     if (!disk->pdev_path && !disk->removable) {
87         xlu__disk_err(&dpc,0,"no target specified (and device not removable)");
88         goto x_err;
89     }
90 
91  x_err:
92     dpc_dispose(&dpc);
93     return dpc.err;
94 }
95 
96 /*
97  * Local variables:
98  * mode: C
99  * c-basic-offset: 4
100  * indent-tabs-mode: nil
101  * End:
102  */
103