"Fossies" - the Fresh Open Source Software Archive

Member "syslinux-6.03/libinstaller/advio.c" (6 Oct 2014, 3829 Bytes) of package /linux/misc/syslinux-6.03.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* ----------------------------------------------------------------------- *
    2  *
    3  *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
    4  *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
    5  *
    6  *   This program is free software; you can redistribute it and/or modify
    7  *   it under the terms of the GNU General Public License as published by
    8  *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
    9  *   Boston MA 02111-1307, USA; either version 2 of the License, or
   10  *   (at your option) any later version; incorporated herein by reference.
   11  *
   12  * ----------------------------------------------------------------------- */
   13 
   14 /*
   15  * advio.c
   16  *
   17  * Linux ADV I/O
   18  *
   19  * Return 0 on success, -1 on error, and set errno.
   20  *
   21  */
   22 #define  _GNU_SOURCE
   23 
   24 #include <stdio.h>
   25 #include <stdlib.h>
   26 #include <stddef.h>
   27 #include <stdint.h>
   28 #include <string.h>
   29 #include <unistd.h>
   30 #include <errno.h>
   31 #include <fcntl.h>
   32 #include <sys/stat.h>
   33 #include <sys/types.h>
   34 #include "syslxint.h"
   35 #include "syslxcom.h"
   36 
   37 /*
   38  * Read the ADV from an existing instance, or initialize if invalid.
   39  * Returns -1 on fatal errors, 0 if ADV is okay, 1 if the ADV is
   40  * invalid, and 2 if the file does not exist.
   41  */
   42 int read_adv(const char *path, const char *cfg)
   43 {
   44     char *file;
   45     int fd = -1;
   46     struct stat st;
   47     int err = 0;
   48     int rv;
   49 
   50     rv = asprintf(&file, "%s%s%s", path,
   51           path[0] && path[strlen(path) - 1] == '/' ? "" : "/", cfg);
   52 
   53     if (rv < 0 || !file) {
   54     perror(program);
   55     return -1;
   56     }
   57 
   58     fd = open(file, O_RDONLY);
   59     if (fd < 0) {
   60     if (errno != ENOENT) {
   61         err = -1;
   62     } else {
   63         syslinux_reset_adv(syslinux_adv);
   64         err = 2;        /* Nonexistence is not a fatal error */
   65     }
   66     } else if (fstat(fd, &st)) {
   67     err = -1;
   68     } else if (st.st_size < 2 * ADV_SIZE) {
   69     /* Too small to be useful */
   70     syslinux_reset_adv(syslinux_adv);
   71     err = 0;        /* Nothing to read... */
   72     } else if (xpread(fd, syslinux_adv, 2 * ADV_SIZE,
   73               st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
   74     err = -1;
   75     } else {
   76     /* We got it... maybe? */
   77     err = syslinux_validate_adv(syslinux_adv) ? 1 : 0;
   78     }
   79 
   80     if (err < 0)
   81     perror(file);
   82 
   83     if (fd >= 0)
   84     close(fd);
   85 
   86     free(file);
   87 
   88     return err;
   89 }
   90 
   91 /*
   92  * Update the ADV in an existing installation.
   93  */
   94 int write_adv(const char *path, const char *cfg)
   95 {
   96     unsigned char advtmp[2 * ADV_SIZE];
   97     char *file;
   98     int fd = -1;
   99     struct stat st, xst;
  100     int err = 0;
  101     int rv;
  102 
  103     rv = asprintf(&file, "%s%s%s", path,
  104           path[0] && path[strlen(path) - 1] == '/' ? "" : "/", cfg);
  105 
  106     if (rv < 0 || !file) {
  107     perror(program);
  108     return -1;
  109     }
  110 
  111     fd = open(file, O_RDONLY);
  112     if (fd < 0) {
  113     err = -1;
  114     } else if (fstat(fd, &st)) {
  115     err = -1;
  116     } else if (st.st_size < 2 * ADV_SIZE) {
  117     /* Too small to be useful */
  118     err = -2;
  119     } else if (xpread(fd, advtmp, 2 * ADV_SIZE,
  120               st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
  121     err = -1;
  122     } else {
  123     /* We got it... maybe? */
  124     err = syslinux_validate_adv(advtmp) ? -2 : 0;
  125     if (!err) {
  126         /* Got a good one, write our own ADV here */
  127         clear_attributes(fd);
  128 
  129         /* Need to re-open read-write */
  130         close(fd);
  131         fd = open(file, O_RDWR | O_SYNC);
  132         if (fd < 0) {
  133         err = -1;
  134         } else if (fstat(fd, &xst) || xst.st_ino != st.st_ino ||
  135                xst.st_dev != st.st_dev || xst.st_size != st.st_size) {
  136         fprintf(stderr, "%s: race condition on write\n", file);
  137         err = -2;
  138         }
  139         /* Write our own version ... */
  140         if (xpwrite(fd, syslinux_adv, 2 * ADV_SIZE,
  141             st.st_size - 2 * ADV_SIZE) != 2 * ADV_SIZE) {
  142         err = -1;
  143         }
  144 
  145         sync();
  146         set_attributes(fd);
  147     }
  148     }
  149 
  150     if (err == -2)
  151     fprintf(stderr, "%s: cannot write auxilliary data (need --update)?\n",
  152         file);
  153     else if (err == -1)
  154     perror(file);
  155 
  156     if (fd >= 0)
  157     close(fd);
  158     if (file)
  159     free(file);
  160 
  161     return err;
  162 }