1From ee3a60829edc9d3344dc872fb0158e7b006f02be Mon Sep 17 00:00:00 2001
2From: Robert Yang <liezhi.yang@windriver.com>
3Date: Wed, 31 Dec 2014 16:47:52 +0800
4Subject: [PATCH] linux/syslinux: implement handle_adv_on_ext()
5
6It reads adv if found on the device, or resets syslinux_adv, or update
7the adv if update adv only.
8
9Upstream-Status: Submitted
10
11Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
12Tested-by: Du Dolpher <dolpher.du@intel.com>
13---
14 linux/syslinux.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
15 1 file changed, 97 insertions(+)
16
17diff --git a/linux/syslinux.c b/linux/syslinux.c
18index c7c1994..90b8edd 100755
19--- a/linux/syslinux.c
20+++ b/linux/syslinux.c
21@@ -422,6 +422,103 @@ int install_bootblock(int fd, const char *device)
22
23 static int handle_adv_on_ext(void)
24 {
25+    int                 i, retval, found_file;
26+    int                 need_close = 2; /* 2 means no need extra close */
27+    char                *filenames[2] = {"ldlinux.sys", "extlinux.sys"};
28+    char                *filename;
29+    ext2_ino_t          newino;
30+    ext2_file_t         e2_file;
31+    struct ext2_inode   inode;
32+
33+    for (i = 0; i < 2; i++) {
34+        filename = filenames[i];
35+        found_file = 0;
36+        retval = ext2fs_namei(e2fs, root, cwd, filename, &newino);
37+        if (retval == 0) {
38+            found_file = 1;
39+        } else
40+            continue;
41+
42+        need_close = i;
43+
44+        retval = ext2fs_file_open(e2fs, newino, EXT2_FLAG_RW, &e2_file);
45+        if (retval) {
46+            fprintf(stderr, "%s: failed to open %s\n",
47+                program, filename);
48+            goto fail;
49+        }
50+
51+        retval = ext2fs_read_inode(e2fs, newino, &inode);
52+        if (retval) {
53+            fprintf(stderr, "%s: error while reading inode: %u, file: %s\n",
54+                program, newino, filename);
55+            goto fail;
56+        }
57+
58+        /* Check the size to see if too small to read */
59+        if (inode.i_size < 2 * ADV_SIZE) {
60+            if (opt.update_only == -1) {
61+                fprintf(stderr, "%s: failed to write auxilliary data\n\
62+                        the size of %s is too small (need --update)?\n",
63+                        program, filename);
64+                retval = -1;
65+                goto fail;
66+            }
67+            syslinux_reset_adv(syslinux_adv);
68+            found_file = 0;
69+            break;
70+        }
71+
72+        /* Read the adv */
73+        retval = ext_file_read(e2_file, syslinux_adv, 2 * ADV_SIZE,
74+                        inode.i_size - 2 * ADV_SIZE, "ADV");
75+        if (retval == -1)
76+                goto fail;
77+        if (retval == 2 * ADV_SIZE) {
78+            retval = syslinux_validate_adv(syslinux_adv);
79+            /* Read the adv successfully */
80+            if (retval == 0)
81+                break;
82+        }
83+
84+        /* Close the file if reaches here, otherwise we leave the file
85+         * open in case we need write it */
86+        need_close = 2;
87+        retval = ext2fs_file_close(e2_file);
88+        if (retval) {
89+            fprintf(stderr, "%s: error while closing %s\n",
90+                program, filename);
91+            return retval;
92+        }
93+    }
94+
95+    if (!found_file) {
96+        if (opt.update_only == -1) {
97+            fprintf(stderr, "%s: no ldlinux.sys or extlinux.sys found on the device\n",
98+                program);
99+            return -1;
100+        }
101+        syslinux_reset_adv(syslinux_adv);
102+    }
103+
104+    /* The modify_adv will reset the adv if opt.reset_adv */
105+    if (modify_adv() < 0) {
106+        fprintf(stderr, "%s: error while modifying adv\n", program);
107+        retval = -1;
108+        goto fail;
109+    }
110+
111+    /* Write adv if update_only == -1 and found file */
112+    if (opt.update_only == -1 && found_file) {
113+        if (ext_file_write(e2_file, syslinux_adv, 2 * ADV_SIZE ,
114+                        inode.i_size - 2 * ADV_SIZE) == -1)
115+                goto fail;
116+    }
117+
118+fail:
119+    if (need_close != 2)
120+        (void) ext2fs_file_close(e2_file);
121+    return retval;
122 }
123
124 /* Write files, adv, boot sector */
125