RHEL4/usr/gen_init_cpio.c
<<
>>
Prefs
   1#include <stdio.h>
   2#include <stdlib.h>
   3#include <sys/types.h>
   4#include <sys/stat.h>
   5#include <string.h>
   6#include <unistd.h>
   7#include <time.h>
   8#include <fcntl.h>
   9
  10static unsigned int offset;
  11static unsigned int ino = 721;
  12
  13static void push_string(const char *name)
  14{
  15        unsigned int name_len = strlen(name) + 1;
  16
  17        fputs(name, stdout);
  18        putchar(0);
  19        offset += name_len;
  20}
  21
  22static void push_pad (void)
  23{
  24        while (offset & 3) {
  25                putchar(0);
  26                offset++;
  27        }
  28}
  29
  30static void push_rest(const char *name)
  31{
  32        unsigned int name_len = strlen(name) + 1;
  33        unsigned int tmp_ofs;
  34
  35        fputs(name, stdout);
  36        putchar(0);
  37        offset += name_len;
  38
  39        tmp_ofs = name_len + 110;
  40        while (tmp_ofs & 3) {
  41                putchar(0);
  42                offset++;
  43                tmp_ofs++;
  44        }
  45}
  46
  47static void push_hdr(const char *s)
  48{
  49        fputs(s, stdout);
  50        offset += 110;
  51}
  52
  53static void cpio_trailer(void)
  54{
  55        char s[256];
  56        const char name[] = "TRAILER!!!";
  57
  58        sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX"
  59               "%08X%08X%08X%08X%08X%08X%08X",
  60                "070701",               /* magic */
  61                0,                      /* ino */
  62                0,                      /* mode */
  63                (long) 0,               /* uid */
  64                (long) 0,               /* gid */
  65                1,                      /* nlink */
  66                (long) 0,               /* mtime */
  67                0,                      /* filesize */
  68                0,                      /* major */
  69                0,                      /* minor */
  70                0,                      /* rmajor */
  71                0,                      /* rminor */
  72                (unsigned)strlen(name) + 1, /* namesize */
  73                0);                     /* chksum */
  74        push_hdr(s);
  75        push_rest(name);
  76
  77        while (offset % 512) {
  78                putchar(0);
  79                offset++;
  80        }
  81}
  82
  83static void cpio_mkdir(const char *name, unsigned int mode,
  84                       uid_t uid, gid_t gid)
  85{
  86        char s[256];
  87        time_t mtime = time(NULL);
  88
  89        sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
  90               "%08X%08X%08X%08X%08X%08X%08X",
  91                "070701",               /* magic */
  92                ino++,                  /* ino */
  93                S_IFDIR | mode,         /* mode */
  94                (long) uid,             /* uid */
  95                (long) gid,             /* gid */
  96                2,                      /* nlink */
  97                (long) mtime,           /* mtime */
  98                0,                      /* filesize */
  99                3,                      /* major */
 100                1,                      /* minor */
 101                0,                      /* rmajor */
 102                0,                      /* rminor */
 103                (unsigned)strlen(name) + 1,/* namesize */
 104                0);                     /* chksum */
 105        push_hdr(s);
 106        push_rest(name);
 107}
 108
 109static void cpio_mknod(const char *name, unsigned int mode,
 110                       uid_t uid, gid_t gid, int dev_type,
 111                       unsigned int maj, unsigned int min)
 112{
 113        char s[256];
 114        time_t mtime = time(NULL);
 115
 116        if (dev_type == 'b')
 117                mode |= S_IFBLK;
 118        else
 119                mode |= S_IFCHR;
 120
 121        sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
 122               "%08X%08X%08X%08X%08X%08X%08X",
 123                "070701",               /* magic */
 124                ino++,                  /* ino */
 125                mode,                   /* mode */
 126                (long) uid,             /* uid */
 127                (long) gid,             /* gid */
 128                1,                      /* nlink */
 129                (long) mtime,           /* mtime */
 130                0,                      /* filesize */
 131                3,                      /* major */
 132                1,                      /* minor */
 133                maj,                    /* rmajor */
 134                min,                    /* rminor */
 135                (unsigned)strlen(name) + 1,/* namesize */
 136                0);                     /* chksum */
 137        push_hdr(s);
 138        push_rest(name);
 139}
 140
 141/* Not marked static to keep the compiler quiet, as no one uses this yet... */
 142void cpio_mkfile(const char *filename, const char *location,
 143                        unsigned int mode, uid_t uid, gid_t gid)
 144{
 145        char s[256];
 146        char *filebuf;
 147        struct stat buf;
 148        int file;
 149        int retval;
 150        int i;
 151
 152        mode |= S_IFREG;
 153
 154        retval = stat (filename, &buf);
 155        if (retval) {
 156                fprintf (stderr, "Filename %s could not be located\n", filename);
 157                goto error;
 158        }
 159
 160        file = open (filename, O_RDONLY);
 161        if (file < 0) {
 162                fprintf (stderr, "Filename %s could not be opened for reading\n", filename);
 163                goto error;
 164        }
 165
 166        filebuf = malloc(buf.st_size);
 167        if (!filebuf) {
 168                fprintf (stderr, "out of memory\n");
 169                goto error_close;
 170        }
 171
 172        retval = read (file, filebuf, buf.st_size);
 173        if (retval < 0) {
 174                fprintf (stderr, "Can not read %s file\n", filename);
 175                goto error_free;
 176        }
 177
 178        sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
 179               "%08X%08X%08X%08X%08X%08X%08X",
 180                "070701",               /* magic */
 181                ino++,                  /* ino */
 182                mode,                   /* mode */
 183                (long) uid,             /* uid */
 184                (long) gid,             /* gid */
 185                1,                      /* nlink */
 186                (long) buf.st_mtime,    /* mtime */
 187                (int) buf.st_size,      /* filesize */
 188                3,                      /* major */
 189                1,                      /* minor */
 190                0,                      /* rmajor */
 191                0,                      /* rminor */
 192                (unsigned)strlen(location) + 1,/* namesize */
 193                0);                     /* chksum */
 194        push_hdr(s);
 195        push_string(location);
 196        push_pad();
 197
 198        for (i = 0; i < buf.st_size; ++i)
 199                fputc(filebuf[i], stdout);
 200        offset += buf.st_size;
 201        close(file);
 202        free(filebuf);
 203        push_pad();
 204        return;
 205        
 206error_free:
 207        free(filebuf);
 208error_close:
 209        close(file);
 210error:
 211        exit(-1);
 212}
 213
 214int main (int argc, char *argv[])
 215{
 216        cpio_mkdir("/dev", 0755, 0, 0);
 217        cpio_mknod("/dev/console", 0600, 0, 0, 'c', 5, 1);
 218        cpio_mkdir("/root", 0700, 0, 0);
 219        cpio_trailer();
 220
 221        exit(0);
 222
 223        /* silence compiler warnings */
 224        return 0;
 225        (void) argc;
 226        (void) argv;
 227}
 228
 229