~ubuntu-branches/ubuntu/trusty/util-linux/trusty-proposed

« back to all changes in this revision

Viewing changes to misc-utils/mcookie.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones
  • Date: 2011-11-03 15:38:23 UTC
  • mto: (4.5.5 sid) (1.6.4)
  • mto: This revision was merged to the branch mainline in revision 85.
  • Revision ID: package-import@ubuntu.com-20111103153823-10sx16jprzxlhkqf
ImportĀ upstreamĀ versionĀ 2.20.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *
19
19
 */
20
20
 
 
21
#include "c.h"
 
22
#include "md5.h"
 
23
#include "nls.h"
 
24
#include <fcntl.h>
 
25
#include <getopt.h>
 
26
#include <stddef.h>
21
27
#include <stdio.h>
22
28
#include <stdlib.h>
23
 
#include <fcntl.h>
24
 
#include "md5.h"
25
29
#include <sys/time.h>
26
30
#include <unistd.h>
27
 
#include "nls.h"
28
31
 
29
 
#define BUFFERSIZE 4096
 
32
#define BUFFERSIZE      4096
30
33
 
31
34
struct rngs {
32
 
   const char *path;
33
 
   int minlength, maxlength;
 
35
        const char *path;
 
36
        int minlength, maxlength;
34
37
} rngs[] = {
35
 
   { "/dev/random",              16,  16 }, /* 16 bytes = 128 bits suffice */
36
 
   { "/proc/interrupts",          0,   0 },
37
 
   { "/proc/slabinfo",            0,   0 },
38
 
   { "/proc/stat",                0,   0 },
39
 
   { "/dev/urandom",             32,  64 },
 
38
        {"/dev/random",         16, 16},  /* 16 bytes = 128 bits suffice */
 
39
        {"/proc/interrupts",     0,  0},
 
40
        {"/proc/slabinfo",       0,  0},
 
41
        {"/proc/stat",           0,  0},
 
42
        {"/dev/urandom",        32, 64},
40
43
};
 
44
 
41
45
#define RNGS (sizeof(rngs)/sizeof(struct rngs))
42
46
 
43
 
int Verbose = 0;
44
 
 
45
47
/* The basic function to hash a file */
46
 
static off_t
47
 
hash_file(struct MD5Context *ctx, int fd)
48
 
{
49
 
   off_t count = 0;
50
 
   ssize_t r;
51
 
   unsigned char buf[BUFFERSIZE];
52
 
 
53
 
   while ((r = read(fd, buf, sizeof(buf))) > 0) {
54
 
      MD5Update(ctx, buf, r);
55
 
      count += r;
56
 
   }
57
 
   /* Separate files with a null byte */
58
 
   buf[0] = 0;
59
 
   MD5Update(ctx, buf, 1);
60
 
   return count;
61
 
}
62
 
 
63
 
int main( int argc, char **argv )
64
 
{
65
 
   int               i;
66
 
   struct MD5Context ctx;
67
 
   unsigned char     digest[16];
68
 
   unsigned char     buf[BUFFERSIZE];
69
 
   int               fd;
70
 
   int               c;
71
 
   pid_t             pid;
72
 
   char              *file = NULL;
73
 
   int               r;
74
 
   struct timeval    tv;
75
 
   struct timezone   tz;
76
 
 
77
 
   setlocale(LC_ALL, "");
78
 
   bindtextdomain(PACKAGE, LOCALEDIR);
79
 
   textdomain(PACKAGE);
80
 
 
81
 
   while ((c = getopt( argc, argv, "vf:" )) != -1)
82
 
      switch (c) {
83
 
      case 'v': ++Verbose;     break;
84
 
      case 'f': file = optarg; break;
85
 
      }
86
 
 
87
 
   MD5Init( &ctx );
88
 
   gettimeofday( &tv, &tz );
89
 
   MD5Update( &ctx, (unsigned char *)&tv, sizeof( tv ) );
90
 
 
91
 
   pid = getppid();
92
 
   MD5Update( &ctx, (unsigned char *)&pid, sizeof( pid ));
93
 
   pid = getpid();
94
 
   MD5Update( &ctx, (unsigned char *)&pid, sizeof( pid ));
95
 
 
96
 
   if (file) {
97
 
      int count = 0;
98
 
      
99
 
      if (file[0] == '-' && !file[1])
100
 
         fd = fileno(stdin);
101
 
      else
102
 
         fd = open( file, O_RDONLY );
103
 
 
104
 
      if (fd < 0) {
105
 
         fprintf( stderr, _("Could not open %s\n"), file );
106
 
      } else {
107
 
         count = hash_file( &ctx, fd );
108
 
         if (Verbose)
109
 
            fprintf( stderr, _("Got %d bytes from %s\n"), count, file );
110
 
 
111
 
         if (file[0] != '-' || file[1]) close( fd );
112
 
      }
113
 
   }
114
 
 
115
 
   for (i = 0; i < RNGS; i++) {
116
 
      if ((fd = open( rngs[i].path, O_RDONLY|O_NONBLOCK )) >= 0) {
117
 
         int count = sizeof(buf);
118
 
 
119
 
         if (rngs[i].maxlength && count > rngs[i].maxlength)
120
 
            count = rngs[i].maxlength;
121
 
         r = read( fd, buf, count );
122
 
         if (r > 0)
123
 
            MD5Update( &ctx, buf, r );
124
 
         else
125
 
            r = 0;
126
 
         close( fd );
127
 
         if (Verbose)
128
 
            fprintf( stderr, _("Got %d bytes from %s\n"), r, rngs[i].path );
129
 
         if (rngs[i].minlength && r >= rngs[i].minlength)
130
 
            break;
131
 
      } else if (Verbose)
132
 
         fprintf( stderr, _("Could not open %s\n"), rngs[i].path );
133
 
   }
134
 
 
135
 
   MD5Final( digest, &ctx );
136
 
   for (i = 0; i < 16; i++) printf( "%02x", digest[i] );
137
 
   putchar ( '\n' );
138
 
   
139
 
   /*
140
 
    * The following is important for cases like disk full, so shell scripts
141
 
    * can bomb out properly rather than think they succeeded.
142
 
    */
143
 
   if (fflush(stdout) < 0 || fclose(stdout) < 0)
144
 
      return 1;
145
 
 
146
 
   return 0;
 
48
static off_t hash_file(struct MD5Context *ctx, int fd)
 
49
{
 
50
        off_t count = 0;
 
51
        ssize_t r;
 
52
        unsigned char buf[BUFFERSIZE];
 
53
 
 
54
        while ((r = read(fd, buf, sizeof(buf))) > 0) {
 
55
                MD5Update(ctx, buf, r);
 
56
                count += r;
 
57
        }
 
58
        /* Separate files with a null byte */
 
59
        buf[0] = '\0';
 
60
        MD5Update(ctx, buf, 1);
 
61
        return count;
 
62
}
 
63
 
 
64
static void __attribute__ ((__noreturn__)) usage(FILE * out)
 
65
{
 
66
        fputs(_("\nUsage:\n"), out);
 
67
        fprintf(out,
 
68
              _(" %s [options]\n"), program_invocation_short_name);
 
69
 
 
70
        fputs(_("\nOptions:\n"), out);
 
71
        fputs(_(" -f, --file <file> use file as a cookie seed\n"
 
72
                " -v, --verbose     explain what is being done\n"
 
73
                " -V, --version     output version information and exit\n"
 
74
                " -h, --help        display this help and exit\n\n"), out);
 
75
 
 
76
        exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
 
77
}
 
78
 
 
79
int main(int argc, char **argv)
 
80
{
 
81
        size_t i;
 
82
        struct MD5Context ctx;
 
83
        unsigned char digest[MD5LENGTH];
 
84
        unsigned char buf[BUFFERSIZE];
 
85
        int fd;
 
86
        int c;
 
87
        pid_t pid;
 
88
        char *file = NULL;
 
89
        int verbose = 0;
 
90
        int r;
 
91
        struct timeval tv;
 
92
        struct timezone tz;
 
93
 
 
94
        static const struct option longopts[] = {
 
95
                {"file", required_argument, NULL, 'f'},
 
96
                {"verbose", no_argument, NULL, 'v'},
 
97
                {"version", no_argument, NULL, 'V'},
 
98
                {"help", no_argument, NULL, 'h'},
 
99
                {NULL, 0, NULL, 0}
 
100
        };
 
101
 
 
102
        setlocale(LC_ALL, "");
 
103
        bindtextdomain(PACKAGE, LOCALEDIR);
 
104
        textdomain(PACKAGE);
 
105
 
 
106
        while ((c =
 
107
                getopt_long(argc, argv, "f:vVh", longopts, NULL)) != -1)
 
108
                switch (c) {
 
109
                case 'v':
 
110
                        verbose = 1;
 
111
                        break;
 
112
                case 'f':
 
113
                        file = optarg;
 
114
                        break;
 
115
                case 'V':
 
116
                        printf(_("%s from %s\n"),
 
117
                               program_invocation_short_name,
 
118
                               PACKAGE_STRING);
 
119
                        return EXIT_SUCCESS;
 
120
                case 'h':
 
121
                        usage(stdout);
 
122
                default:
 
123
                        usage(stderr);
 
124
                }
 
125
 
 
126
        MD5Init(&ctx);
 
127
        gettimeofday(&tv, &tz);
 
128
        MD5Update(&ctx, (unsigned char *) &tv, sizeof(tv));
 
129
 
 
130
        pid = getppid();
 
131
        MD5Update(&ctx, (unsigned char *) &pid, sizeof(pid));
 
132
        pid = getpid();
 
133
        MD5Update(&ctx, (unsigned char *) &pid, sizeof(pid));
 
134
 
 
135
        if (file) {
 
136
                int count = 0;
 
137
 
 
138
                if (file[0] == '-' && !file[1])
 
139
                        fd = STDIN_FILENO;
 
140
                else
 
141
                        fd = open(file, O_RDONLY);
 
142
 
 
143
                if (fd < 0) {
 
144
                        warn(_("Could not open %s"), file);
 
145
                } else {
 
146
                        count = hash_file(&ctx, fd);
 
147
                        if (verbose)
 
148
                                fprintf(stderr,
 
149
                                        _("Got %d bytes from %s\n"), count,
 
150
                                        file);
 
151
 
 
152
                        if (fd != STDIN_FILENO)
 
153
                                if (close(fd))
 
154
                                        err(EXIT_FAILURE,
 
155
                                            _("closing %s failed"), file);
 
156
                }
 
157
        }
 
158
 
 
159
        for (i = 0; i < RNGS; i++) {
 
160
                if ((fd = open(rngs[i].path, O_RDONLY | O_NONBLOCK)) >= 0) {
 
161
                        int count = sizeof(buf);
 
162
 
 
163
                        if (rngs[i].maxlength && count > rngs[i].maxlength)
 
164
                                count = rngs[i].maxlength;
 
165
                        r = read(fd, buf, count);
 
166
                        if (r > 0)
 
167
                                MD5Update(&ctx, buf, r);
 
168
                        else
 
169
                                r = 0;
 
170
                        close(fd);
 
171
                        if (verbose)
 
172
                                fprintf(stderr,
 
173
                                        _("Got %d bytes from %s\n"), r,
 
174
                                        rngs[i].path);
 
175
                        if (rngs[i].minlength && r >= rngs[i].minlength)
 
176
                                break;
 
177
                } else if (verbose)
 
178
                        warn(_("Could not open %s"), rngs[i].path);
 
179
        }
 
180
 
 
181
        MD5Final(digest, &ctx);
 
182
        for (i = 0; i < MD5LENGTH; i++)
 
183
                printf("%02x", digest[i]);
 
184
        putchar('\n');
 
185
 
 
186
        /*
 
187
         * The following is important for cases like disk full,
 
188
         * so shell scripts can bomb out properly rather than
 
189
         * think they succeeded.
 
190
         */
 
191
        if (fflush(stdout) < 0 || fclose(stdout) < 0)
 
192
                return EXIT_FAILURE;
 
193
 
 
194
        return EXIT_SUCCESS;
147
195
}