| |
| /* |
| * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net> |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This software is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| */ |
| |
| #include <config.h> |
| #include <crm_internal.h> |
| |
| #include <sys/param.h> |
| |
| #include <stdio.h> |
| #include <sys/types.h> |
| #include <unistd.h> |
| #ifdef HAVE_STRING_H |
| # include <string.h> |
| #endif |
| |
| #include <stdlib.h> |
| #include <errno.h> |
| #include <fcntl.h> |
| |
| #include <crm/crm.h> |
| #include <crm/common/util.h> |
| #include <clplumbing/cl_uuid.h> |
| |
| #ifdef HAVE_GETOPT_H |
| # include <getopt.h> |
| #endif |
| |
| #define UUID_LEN 16 |
| |
| #define OPTARGS "?rw:" |
| |
| int read_local_hb_uuid(void); |
| int write_local_hb_uuid(const char *buffer); |
| |
| /* *INDENT-OFF* */ |
| static struct crm_option long_options[] = { |
| /* Top-level Options */ |
| {"help", 0, 0, '?', "\tThis text"}, |
| {"version", 0, 0, '$', "\t\tVersion information" }, |
| {"read", 0, 0, 'r', "\tRead the machine's Heartbeat UUID" }, |
| {"write", 1, 0, 'w', "\tChange the machine's Heartbeat UUID to a new value" }, |
| |
| {0, 0, 0, 0} |
| }; |
| /* *INDENT-ON* */ |
| |
| int |
| main(int argc, char **argv) |
| { |
| int flag; |
| int rc = 0; |
| int index = 0; |
| |
| if (argc == 1) { |
| /* no arguments specified, default to read */ |
| rc = read_local_hb_uuid(); |
| return rc; |
| } |
| |
| crm_log_cli_init("crm_uuid"); |
| crm_set_options(NULL, " [-r|-w new_ascii_value]", |
| long_options, "A tool for manipulating Heartbeat's UUID file"); |
| |
| while (1) { |
| flag = crm_get_option(argc, argv, &index); |
| if (flag == -1) |
| break; |
| |
| switch (flag) { |
| case '?': |
| case '$': |
| crm_help(flag, EX_OK); |
| break; |
| case 'r': |
| rc = read_local_hb_uuid(); |
| break; |
| case 'w': |
| rc = write_local_hb_uuid(optarg); |
| break; |
| default: |
| crm_help('?', EX_USAGE); |
| break; |
| } |
| } |
| return rc; |
| } |
| |
| int |
| read_local_hb_uuid(void) |
| { |
| int rc = 0; |
| cl_uuid_t uuid; |
| char *buffer = NULL; |
| long start = 0, read_len = 0; |
| |
| FILE *input = fopen(UUID_FILE, "r"); |
| |
| if (input == NULL) { |
| crm_perror(LOG_ERR, "Could not open UUID file %s\n", UUID_FILE); |
| return 1; |
| } |
| |
| /* see how big the file is */ |
| start = ftell(input); |
| fseek(input, 0L, SEEK_END); |
| if (UUID_LEN != ftell(input)) { |
| fprintf(stderr, "%s must contain exactly %d bytes\n", UUID_FILE, UUID_LEN); |
| abort(); |
| } |
| |
| fseek(input, 0L, start); |
| |
| if (start != ftell(input)) { |
| fprintf(stderr, "fseek not behaving: %ld vs. %ld\n", start, ftell(input)); |
| rc = 2; |
| goto bail; |
| } |
| |
| /* fprintf(stderr, "Reading %d bytes from: %s\n", UUID_LEN, UUID_FILE); */ |
| |
| buffer = malloc(50); |
| read_len = fread(uuid.uuid, 1, UUID_LEN, input); |
| if (read_len != UUID_LEN) { |
| fprintf(stderr, "Expected and read bytes differ: %d vs. %ld\n", UUID_LEN, read_len); |
| rc = 3; |
| goto bail; |
| |
| } else if (buffer != NULL) { |
| cl_uuid_unparse(&uuid, buffer); |
| fprintf(stdout, "%s\n", buffer); |
| |
| } else { |
| fprintf(stderr, "No buffer to unparse\n"); |
| rc = 4; |
| } |
| |
| bail: |
| free(buffer); |
| fclose(input); |
| |
| return rc; |
| } |
| |
| int |
| write_local_hb_uuid(const char *new_value) |
| { |
| int fd; |
| int rc = 0; |
| cl_uuid_t uuid; |
| char *buffer = strdup(new_value); |
| |
| rc = cl_uuid_parse(buffer, &uuid); |
| if (rc != 0) { |
| fprintf(stderr, "Invalid ASCII UUID supplied: [%s]\n", new_value); |
| fprintf(stderr, "ASCII UUIDs must be of the form" |
| " XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" " and contain only letters and digits\n"); |
| return 5; |
| } |
| |
| if ((fd = open(UUID_FILE, O_WRONLY | O_SYNC | O_CREAT, 0644)) < 0) { |
| crm_perror(LOG_ERR, "Could not open %s", UUID_FILE); |
| return 6; |
| } |
| |
| if (write(fd, uuid.uuid, UUID_LEN) != UUID_LEN) { |
| crm_perror(LOG_ERR, "Could not write UUID to %s", UUID_FILE); |
| rc = 7; |
| } |
| |
| if (close(fd) < 0) { |
| crm_perror(LOG_ERR, "Could not close %s", UUID_FILE); |
| rc = 8; |
| } |
| return rc; |
| } |