iscsi tools: fix iscsiadm return value on failed login
[open-iscsi.git] / utils / iscsi-iname.c
blob6347edc462936480720afce6882ae5b76ca35599
1 /*
2 * iSCSI InitiatorName creation utility
3 * Copyright (C) 2001 Cisco Systems, Inc.
4 * maintained by linux-iscsi-devel@lists.sourceforge.net
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
8 * by the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * See the file COPYING included with this distribution for more details.
18 * $Id: iscsi-iname.c,v 1.1.2.3 2005/03/15 06:33:44 wysochanski Exp $
20 * iscsi-iname.c - Compute an iSCSI InitiatorName for this host.
21 * Note that to ensure uniqueness, the system time is
22 * a factor. This name must be cached and only regenerated
23 * if there is no cached value.
26 #include <stdint.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <sys/utsname.h>
33 #include <sys/time.h>
35 #include "md5.h"
37 #define RANDOM_NUM_GENERATOR "/dev/urandom"
39 int
40 main(int argc, char *argv[])
42 char iname[256];
43 struct timeval time;
44 struct utsname system_info;
45 long hostid;
46 struct MD5Context context;
47 unsigned char digest[16];
48 unsigned char *bytes = digest;
49 unsigned char entropy[16];
50 int e;
51 int fd;
52 char *prefix;
54 /* initialize */
55 memset(iname, 0, sizeof (iname));
56 memset(digest, 0, sizeof (digest));
57 memset(&context, 0, sizeof (context));
58 MD5Init(&context);
60 /* take a prefix if given, otherwise use a default. */
61 if (argc > 1 && argv[1]) {
62 prefix = argv[1];
63 if (( strcmp(prefix, "-h") == 0 ) ||
64 ( strcmp(prefix, "--help") == 0 )) {
65 printf("\nGenerates a unique iSCSI node name "
66 "on every invocation.\n");
67 exit(0);
68 } else if ( strcmp(prefix, "-p") == 0 ) {
69 prefix = argv[2];
70 } else {
71 printf("\nUsage: iscsi-iname [-h | --help | "
72 "-p <prefix>]\n");
73 exit(0);
75 } else {
76 prefix = "iqn.2005-03.org.open-iscsi";
79 /* try to feed some entropy from the pool to MD5 in order to get
80 * uniqueness properties
83 if ((fd = open(RANDOM_NUM_GENERATOR, O_RDONLY))) {
84 e = read(fd, &entropy, 16);
85 if (e >= 1)
86 MD5Update(&context, (md5byte *)entropy, e);
87 close(fd);
90 /* time the name is created is a factor in order to get
91 * uniqueness properties
93 if (gettimeofday(&time, NULL) < 0) {
94 perror("error: gettimeofday failed");
95 return 1;
97 MD5Update(&context, (md5byte *) & time.tv_sec, sizeof (time.tv_sec));
98 MD5Update(&context, (md5byte *) & time.tv_usec, sizeof (time.tv_usec));
100 /* hostid */
101 hostid = gethostid();
102 MD5Update(&context, (md5byte *) & hostid, sizeof (hostid));
104 /* get the hostname and system name */
105 if (uname(&system_info) < 0) {
106 perror("error: uname failed");
107 return 1;
109 MD5Update(&context, (md5byte *) system_info.sysname,
110 sizeof (system_info.sysname));
111 MD5Update(&context, (md5byte *) system_info.nodename,
112 sizeof (system_info.nodename));
113 MD5Update(&context, (md5byte *) system_info.release,
114 sizeof (system_info.release));
115 MD5Update(&context, (md5byte *) system_info.version,
116 sizeof (system_info.version));
117 MD5Update(&context, (md5byte *) system_info.machine,
118 sizeof (system_info.machine));
120 /* compute the md5 hash of all the bits we just collected */
121 MD5Final(digest, &context);
123 /* vary which md5 bytes we pick (though we probably don't need to do
124 * this, since hopefully MD5 produces results such that each byte is as
125 * good as any other).
128 if ((fd = open(RANDOM_NUM_GENERATOR, O_RDONLY))) {
129 if (read(fd, entropy, 1) == 1)
130 bytes = &digest[(entropy[0] % (sizeof(digest) - 6))];
131 close(fd);
134 /* print the prefix followed by 6 bytes of the MD5 hash */
135 sprintf(iname, "%s:%x%x%x%x%x%x", prefix,
136 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5]);
138 iname[sizeof (iname) - 1] = '\0';
139 printf("%s\n", iname);
140 return 0;