setuname.c revision 1952:807c8f7f45e0
118334Speter/*
290075Sobrien * CDDL HEADER START
3169689Skan *
4169689Skan * The contents of this file are subject to the terms of the
518334Speter * Common Development and Distribution License (the "License").
690075Sobrien * You may not use this file except in compliance with the License.
718334Speter *
890075Sobrien * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
990075Sobrien * or http://www.opensolaris.org/os/licensing.
1090075Sobrien * See the License for the specific language governing permissions
1190075Sobrien * and limitations under the License.
1218334Speter *
1390075Sobrien * When distributing Covered Code, include this CDDL HEADER in each
1490075Sobrien * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1590075Sobrien * If applicable, add the following below this CDDL HEADER, with the
1690075Sobrien * fields enclosed by brackets "[]" replaced with your own identifying
1718334Speter * information: Portions Copyright [yyyy] [name of copyright owner]
1818334Speter *
1990075Sobrien * CDDL HEADER END
20169689Skan */
21169689Skan/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
2218334Speter/*	  All Rights Reserved  	*/
2318334Speter
2450397Sobrien
25132718Skan/*
26132718Skan * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
2750397Sobrien * Use is subject to license terms.
2850397Sobrien */
2950397Sobrien
3018334Speter#pragma ident	"%Z%%M%	%I%	%E% SMI"       /* SVr4.0 1.3 */
3190075Sobrien
3218334Speter/*
3318334Speter *  setuname [-t] [-s name] [-n node]
3418334Speter */
3590075Sobrien
3618334Speter/*
3790075Sobrien *  Header files referenced:
3818334Speter *	<stdio.h>	Standard I/O
39169689Skan *	<unistd.h>	Standard UNIX definitions
4052284Sobrien *	<string.h>	String handling
4118334Speter *	<fmtmsg.h>	Standard message generation
4218334Speter *	<ctype.h>	Character types
4318334Speter *	<errno.h>	Error handling
4418334Speter *	<signal.h>	Signal handling
4550397Sobrien *	<sys/types.h>	Data types
4690075Sobrien *	<sys/fcntl.h>	File control
4796263Sobrien *	<sys/utsname.h>	System Name
48169689Skan *	<sys/sys3b.h>	sys3b() definitions
4918334Speter *	<nlist.h>	Definitions for Sun symbol table entries
5018334Speter */
5118334Speter
5218334Speter#include	<stdio.h>
5318334Speter#include	<unistd.h>
5418334Speter#include	<string.h>
5518334Speter#include	<fmtmsg.h>
5618334Speter#include	<ctype.h>
5718334Speter#include	<errno.h>
5818334Speter#include	<signal.h>
5918334Speter#include	<sys/types.h>
6018334Speter#include	<sys/uio.h>
6118334Speter#include	<sys/fcntl.h>
6218334Speter#include	<sys/psw.h>
6318334Speter#include	<sys/utsname.h>
6418334Speter
6552284Sobrien#if u3b || u3b15 || u3b2
6652284Sobrien#include	<sys/sys3b.h>
6752284Sobrien#endif
6852284Sobrien
6918334Speter#if sun
7018334Speter#include	<nlist.h>
7118334Speter#include	<kvm.h>
7218334Speter#endif
7318334Speter
7418334Speter/*
7518334Speter * Externals referenced (and not defined in a header)
7618334Speter *	optind		index to the next arg for getopt()
7718334Speter *	opterr		FLAG, TRUE tells getopt() to write messages
7818334Speter *	optarg		Ptr to an option's argument
7918334Speter *	getopt()	Gets an option from the command line
8018334Speter *	putenv()	Writes values into the environment
8118334Speter *	exit()		Exit the process
8218334Speter *	access()	Check accessibility of a file
8318334Speter *	malloc()	Allocate a block of main memory
8418334Speter *	free()		Free allocated space
8550397Sobrien *	lseek()		Seek within a file
8618334Speter *	open()		Open a file
8718334Speter *	close()		Close an open file
8818334Speter */
8918334Speter
90169689Skanextern	int		optind;		/* argv[] index of next arg */
9118334Speterextern	int		opterr;		/* TRUE if getopt() is to print msgs */
9218334Speterextern	char	       *optarg;		/* Argument to parsed option */
9318334Speterextern	int		getopt();	/* Get an option from the command line */
9418334Speterextern	int	       	putenv();	/* Put a value into the environment */
9518334Speterextern	void		exit();		/* Exit the process */
9618334Speterextern	int		access();	/* Check the accessibility of a file */
9718334Speterextern	void	       *malloc();	/* Get a chunk of main memory */
9818334Speterextern	void		free();		/* Free alloc'd space */
9918334Speterextern	long		lseek();	/* Seek within a file */
10018334Speterextern	int		open();		/* Open a file */
10118334Speterextern	int		close();	/* Close an open a file */
102169689Skan
103169689Skan/*
104169689Skan *  L O C A L   D E F I N I T I O N S
105169689Skan */
106169689Skan
10718334Speter/*
10818334Speter * Constants
10918334Speter */
11018334Speter
11118334Speter#ifndef	TRUE
11218334Speter#define	TRUE		(1)
113169689Skan#endif
114169689Skan
115169689Skan#ifndef	FALSE
116169689Skan#define	FALSE		(0)
11718334Speter#endif
11818334Speter
11918334Speter#ifndef	NULL
12018334Speter#define	NULL		(0)
12118334Speter#endif
12218334Speter
12318334Speter#define	OPTSTRING	"tn:s:"
12418334Speter
12518334Speter#define	EX_OK		0
126169689Skan#define	EX_ERROR	1
127169689Skan
128169689Skan#define	RC_FILENAME	"/etc/rc2.d/S18setuname"
129169689Skan#define RC_DIRNAME	"/etc/rc2.d"
13018334Speter
13190075Sobrien
13218334Speter/*
13352284Sobrien *  Messages
13418334Speter */
135169689Skan
136169689Skan#define	E_USAGE		"usage: setuname [-t] [-s name] [-n node]"
13718334Speter#define	E_MISSING	"Either -s name or -n node must be specified"
13852284Sobrien#define	E_UNAME		"Unable to get existing uname values"
13952284Sobrien#define E_INVNAME	"System-name invalid: %s"
14052284Sobrien#define E_LONGNAME	"System-name too long: %s"
14150397Sobrien#define E_INVNODE	"Network node-name invalid: %s"
14252284Sobrien#define E_LONGNODE	"Network node-name too long: %s"
14318334Speter#define E_NOPERMS	"No permissions, request denied"
14418334Speter#define E_NOSUCHDIR	"Directory doesn't exist: %s"
14518334Speter#define	E_INTERNAL	"Internal error: %d"
14618334Speter
14718334Speter/*
14850397Sobrien * Macros:
14950397Sobrien *	stdmsg(r,l,s,t)	    Write a standard message.
15018334Speter *				'r' is the recoverability flag
15118334Speter *				'l' is the label
152117395Skan *				's' is the severity
15350397Sobrien *				't' is the text.
15450397Sobrien *	strend(p)	    Return the address of the end of a string
15550397Sobrien *			    (This is supposed to be defined in <sys/inline.h>
15650397Sobrien *			    but that file has string-handing def'ns that
15750397Sobrien *			    conflict with <string.h>, so we can't use it!
158132718Skan *			    MR dn89-04701 requests this fix.
159132718Skan */
160132718Skan
161132718Skan#define	stdmsg(r,l,s,t)	(void) fmtmsg(MM_PRINT|MM_UTIL|r,l,s,t,MM_NULLACT,MM_NULLTAG)
162132718Skan#define strend(p)       strrchr(p,'\0')
16318334Speter
16418334Speter/*
16518334Speter * Local functions:
16618334Speter *	setuname	Changes the system name and the network node name
16718334Speter */
16818334Speter
16918334Speterstatic int	setuname();		/* This does the "real" work */
17018334Speter
17118334Speter
17218334Speter/*
17318334Speter * Local data
17418334Speter *	lbl		Buffer for the standard message label
17518334Speter *	txt		Buffer for the standard message text
17618334Speter */
17752284Sobrien
17852284Sobrienstatic	char		lbl[MM_MXLABELLN+1];	/* Space for std msg label */
17952284Sobrienstatic	char		msg[MM_MXTXTLN+1];	/* Space for std msg text  */
18052284Sobrien
18152284Sobrien/*
18218334Speter *  int main(argc, argv)
18318334Speter *	int	argc
18418334Speter *	char   *argv;
18590075Sobrien */
18652284Sobrien
18752284Sobrienint
18818334Spetermain(argc, argv)
18918334Speter	int	argc;			/* Argument count  */
19052284Sobrien	char   *argv[];			/* Argument vector */
19152284Sobrien{
19252284Sobrien	/* Automatic data */
19352284Sobrien	char	       *n_arg;			/* Ptr to arg for -n */
19452284Sobrien	char	       *s_arg;			/* Ptr to arg for -s */
19518334Speter	int		t_seen;			/* FLAG, -t option seen */
19652284Sobrien	char	       *cmdname;		/* Ptr to the command's name */
19752284Sobrien	char	       *p;			/* Temp pointer */
19852284Sobrien	int		usageerr;		/* FLAG, TRUE if usage error */
19952284Sobrien	int		exitcode;		/* Value to exit with */
20052284Sobrien	int		c;			/* Temp character */
20118334Speter	int		ok;			/* Flag, everything okay? */
20252284Sobrien
20352284Sobrien	/* Build the standard-message label */
20452284Sobrien	if (p = strrchr(argv[0], '/')) cmdname = p+1;
20518334Speter	else cmdname = argv[0];
20652284Sobrien	(void) strcat(strcpy(lbl, "UX:"), cmdname);
20752284Sobrien
20852284Sobrien	/* Make only the text in standard messages appear (SVR4.0 only) */
20952284Sobrien	(void) putenv("MSGVERB=text");
21052284Sobrien
21118334Speter
21218334Speter	/* Initializations */
21352284Sobrien	n_arg = s_arg = (char *) NULL;
21452284Sobrien	t_seen = FALSE;
21552284Sobrien
21652284Sobrien
21752284Sobrien	/*
21852284Sobrien	 * Parse command
21950397Sobrien	 */
22052284Sobrien
22152284Sobrien	usageerr = FALSE;
22252284Sobrien	opterr = FALSE;
22352284Sobrien	while (!usageerr && (c = getopt(argc, argv, OPTSTRING)) != EOF) switch(c) {
22452284Sobrien
22550397Sobrien	case 'n':			/* -n node */
22652284Sobrien	    if (n_arg) usageerr = TRUE;
22752284Sobrien	    else n_arg = optarg;
22852284Sobrien	    break;
22952284Sobrien
23018334Speter	case 's':			/* -s name */
23118334Speter	    if (s_arg) usageerr = TRUE;
23218334Speter	    else s_arg = optarg;
23318334Speter	    break;
23418334Speter
23518334Speter	case 't':			/* -t */
23618334Speter	    if (t_seen) usageerr = TRUE;
23718334Speter	    else t_seen = TRUE;
23818334Speter	    break;
23918334Speter
24018334Speter	default:			/* Something that doesn't exist */
24118334Speter	    usageerr = TRUE;
24218334Speter	}   /* switch() */
24318334Speter
24490075Sobrien	/* If there was a usage error, report the error and exit */
24518334Speter	if ((argc >= (optind+1)) || usageerr) {
24618334Speter	    stdmsg(MM_NRECOV, lbl, MM_ERROR, E_USAGE);
24718334Speter	    exit(EX_ERROR);
24818334Speter	}
24918334Speter
25018334Speter	/* Either -n <node> or -s <name> has to be specified */
25118334Speter	if (!(n_arg || s_arg)) {
25218334Speter	    stdmsg(MM_NRECOV, lbl, MM_ERROR, E_MISSING);
25318334Speter	    exit(EX_ERROR);
25490075Sobrien	}
25518334Speter
25652284Sobrien
25790075Sobrien	/*
25818334Speter	 * Validate arguments:
25990075Sobrien	 *  - The length of the system name must be less than SYS_NMLN-1
26090075Sobrien	 *    characters,
26190075Sobrien	 *  - The length of the network node-name must be less than
26290075Sobrien	 *    SYS_NMLN-1 characters,
26318334Speter	 *  - The system name must equal [a-zA-Z0-9-_]+,
26418334Speter	 *  - The network node-name must equal [a-zA-Z0-9-_]+.
26518334Speter	 */
26618334Speter
26718334Speter	/* Check the length and the character-set of the system name */
26818334Speter	if (s_arg) {
26918334Speter
27018334Speter	    /* Check length of the system name */
27118334Speter	    if (strlen(s_arg) > (size_t)(SYS_NMLN-1)) {
27218334Speter		(void) sprintf(msg, E_LONGNAME, s_arg);
27318334Speter		stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
27418334Speter		exit(EX_ERROR);
27518334Speter	    }
27618334Speter
27718334Speter	    /* Check the character-set */
27818334Speter	    ok = TRUE;
27918334Speter	    for (p = s_arg ; ok && *p ; p++) {
28018334Speter		if (!isalnum(*p) && (*p != '-') && (*p != '_')) ok = FALSE;
28118334Speter	    }
28218334Speter	    if (!ok || (p == s_arg)) {
28318334Speter		(void) sprintf(msg, E_INVNAME, s_arg);
284169689Skan		stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
28518334Speter		exit(EX_ERROR);
28652284Sobrien	    }
28752284Sobrien	}
288169689Skan
28952284Sobrien	/* Check the length and the character-set of the network node-name */
29052284Sobrien
29190075Sobrien	if (n_arg) {
292169689Skan
29318334Speter	    /* Check length of the network node-name */
29490075Sobrien	    if (strlen(n_arg) > (size_t)(SYS_NMLN-1)) {
29590075Sobrien		(void) sprintf(msg, E_LONGNODE, n_arg);
29690075Sobrien		stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
29790075Sobrien		exit(EX_ERROR);
29852284Sobrien	    }
29952284Sobrien
30052284Sobrien	    /* Check the character-set */
30152284Sobrien	    ok = TRUE;
30252284Sobrien	    for (p = n_arg ; ok && *p ; p++) {
30352284Sobrien		if (!isalnum(*p) && (*p != '-') && (*p != '_')) ok = FALSE;
30418334Speter	    }
30518334Speter	    if (!ok || (p == n_arg)) {
30618334Speter		(void) sprintf(msg, E_INVNODE, n_arg);
30718334Speter		stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
30818334Speter		exit(EX_ERROR);
30918334Speter	    }
31052284Sobrien	}
31118334Speter
31250397Sobrien
31350397Sobrien	/*
314132718Skan	 * Make sure we have access to needed resources:
315132718Skan	 *   -  Read/write access to kernel memory (/dev/kmem)
31618334Speter	 *   -  If -t is not specified, read/write access to /etc/rc2.d
31750397Sobrien	 *   -  If -t is not specified, read access to /etc/rc2.d/S18setuname
318132718Skan	 */
319132718Skan
32050397Sobrien	if (access("/dev/kmem", R_OK|W_OK) == 0) {
32118334Speter	    if (access(RC_DIRNAME, R_OK|W_OK) == 0) {
32218334Speter		if ((access(RC_FILENAME, R_OK) != 0) &&
32318334Speter		    (access(RC_FILENAME, F_OK) == 0)) {
32418334Speter		    stdmsg(MM_NRECOV, lbl, MM_ERROR, E_NOPERMS);
32550397Sobrien		    exit(EX_ERROR);
32650397Sobrien		}
32752284Sobrien	    }
32818334Speter	    else {
32990075Sobrien		if (access(RC_DIRNAME, F_OK) == 0) {
33052284Sobrien		    stdmsg(MM_NRECOV, lbl, MM_ERROR, E_NOPERMS);
33152284Sobrien		    exit(EX_ERROR);
33290075Sobrien		}
33390075Sobrien		else {
33452284Sobrien		    (void) sprintf(msg, E_NOSUCHDIR, RC_DIRNAME);
33590075Sobrien		    stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
33690075Sobrien		    exit(EX_ERROR);
33752284Sobrien		}
33852284Sobrien	    }
33918334Speter	}
34018334Speter	else {
34118334Speter	    stdmsg(MM_NRECOV, lbl, MM_ERROR, E_NOPERMS);
34218334Speter	    exit(EX_ERROR);
34318334Speter	}
34418334Speter
34518334Speter
34618334Speter	/* Attempt the setuname */
34718334Speter	if (setuname(t_seen, s_arg, n_arg) == 0) exitcode = EX_OK;
34818334Speter	else {
34990075Sobrien	    (void) sprintf(msg, E_INTERNAL, errno);
35018334Speter	    stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
35118334Speter	    exitcode = EX_ERROR;
352117395Skan	}
35318334Speter
35452284Sobrien	/* Finished */
35518334Speter	return (exitcode);
35618334Speter}  /* main() */
35718334Speter
35852284Sobrien/*
35952284Sobrien * int setuname(temp, name, node)
36052284Sobrien *	int	temp
36118334Speter *	char   *name
36218334Speter *	char   *node
36318334Speter *
364117395Skan *	Set any or all of the following machine parameters, either
365117395Skan *	temporarily or permanently, depending on <temp>.
366117395Skan *	    - System name
367117395Skan *	    - Network Node-name
368117395Skan */
369117395Skan
37018334Speterstatic int
371117395Skansetuname(temp, sysname, nodename)
37218334Speter	int	temp;		/* Set in kernel only flag */
373132718Skan	char   *sysname;	/* System name */
37418334Speter	char   *nodename;	/* Network node-name */
37518334Speter{
37618334Speter	/* Automatic Data */
37718334Speter	struct utsname	utsname;	/* Space for the kernel's utsname information */
37818334Speter#if u3b || u3b15 || u3b2
379132718Skan	struct s3bsym  *symbtbl;	/* The kernel's symbol table */
380132718Skan#endif
381132718Skan#if sun
382132718Skan	struct nlist nl[] = {
383132718Skan		{"utsname", 0, 0, 0, 0, 0},
384132718Skan		{NULL}
385132718Skan	};
386132718Skan	kvm_t *kd;
38752284Sobrien#endif
388132718Skan	uintptr_t	utsname_addr;	/* Addr of "utsname" in the kernel */
389132718Skan	char	       *sysnm = (char *)NULL;		/* System name to set (from file or arg) */
390132718Skan	char	       *nodenm = (char *)NULL;		/* Network node-name to set (from file or arg) */
391132718Skan	FILE	       *fd;		/* Std I/O File Descriptor for /etc/rc2.d/S18setuname */
392132718Skan	char	       *p;		/* Temp pointer */
393132718Skan	void	      (*oldsighup)();	/* Function to call for SIGHUP */
394132718Skan	void	      (*oldsigint)();	/* Function to call for SIGINT */
395132718Skan	int		rtncd;		/* Value to return to the caller */
396132718Skan	unsigned long	symbtblsz;	/* The size of the kernel's symbol table, in bytes */
397132718Skan	int		memfd;		/* File descriptor:  open kernel memory */
398132718Skan	int		i;		/* Temp counter */
399169689Skan
400132718Skan
401132718Skan	/* Nothing's gone wrong yet (but we've only just begun!) */
402132718Skan	rtncd = 0;
403132718Skan
404132718Skan
405132718Skan	/*
406132718Skan	 * Get the virtual address of the symbol "utsname" in the kernel
407132718Skan	 * so we can get set the system name and/or the network node-name
408132718Skan	 * directly in the kernel's memory space.
409132718Skan	 */
410132718Skan
411169689Skan#if u3b || u3b15 || u3b2
412132718Skan	if ((sys3b(S3BSYM, (struct s3bsym *) &symbtblsz, sizeof(symbtblsz)) == 0) &&
413132718Skan	    (symbtbl = (struct s3bsym *) malloc(symbtblsz))) {
414132718Skan
415132718Skan	    (void) sys3b(S3BSYM, symbtbl, symbtblsz);
416132718Skan	    p = (char *) symbtbl;
417132718Skan	    for (i = symbtbl->count; i-- && (strcmp(p, "utsname") != 0) ; p = S3BNXTSYM(p)) ;
418132718Skan	    if (i >= 0) utsname_addr = S3BSVAL(p);
419132718Skan	    else rtncd = -1;
420132718Skan	    free((void *) symbtbl);
421132718Skan
422132718Skan	} else rtncd = -1;
423132718Skan
424132718Skan#elif sun
425132718Skan        /* Check out namelist and memory files. */
426132718Skan	if ((kd = kvm_open(NULL, NULL, NULL, O_RDWR, NULL)) == NULL)
427132718Skan		rtncd = -1;
428132718Skan	else if (kvm_nlist(kd, nl) != 0)
429132718Skan		rtncd = -1;
430132718Skan	else if (nl[0].n_value == 0)
431132718Skan		rtncd = -1;
432132718Skan	else
433132718Skan		utsname_addr = (uintptr_t)nl[0].n_value;
434132718Skan#else
435132718Skan	if (nlist("/unix", nl) != 0)
436169689Skan		rtncd = -1;
437132718Skan#endif
438132718Skan	if (rtncd != 0) return(rtncd);
439132718Skan
440132718Skan	/*
441132718Skan	 * Open the kernel's memory, get the existing "utsname" structure,
44252284Sobrien	 * change the system name and/or the network node-name in that struct,
443132718Skan	 * write it back out to kernel memory, then close kernel memory.
44452284Sobrien	 */
445132718Skan#ifdef sun
446169689Skan	if (kvm_kread(kd, utsname_addr, &utsname, sizeof (utsname)) ==
447169689Skan	    sizeof (utsname)) {
448169689Skan		if (sysname)
44918334Speter			(void) strncpy(utsname.sysname, sysname,
45018334Speter			    sizeof (utsname.sysname));
45118334Speter		if (nodename)
45218334Speter			(void) strncpy(utsname.nodename, nodename,
453132718Skan			    sizeof (utsname.nodename));
45418334Speter		(void) kvm_kwrite(kd, utsname_addr, &utsname, sizeof (utsname));
45590075Sobrien		kvm_close(kd);
45618334Speter	} else
45718334Speter		return (-1);
45818334Speter#else /* sun */
45918334Speter	if ((memfd = open("/dev/kmem", O_RDWR, 0)) > 0) {
46018334Speter	    if ((lseek(memfd, (long) utsname_addr, SEEK_SET) != -1) &&
46190075Sobrien		(read(memfd, &utsname, sizeof(utsname)) == sizeof(utsname))) {
46250397Sobrien		if (sysname) (void) strncpy(utsname.sysname, sysname, sizeof(utsname.sysname));
46350397Sobrien		if (nodename) (void) strncpy(utsname.nodename, nodename, sizeof(utsname.nodename));
46490075Sobrien		(void) lseek(memfd, (long) utsname_addr, SEEK_SET);
46590075Sobrien		(void) write(memfd, &utsname, sizeof(utsname));
46650397Sobrien		(void) close(memfd);
46718334Speter	    } else rtncd = -1;
46818334Speter	} else rtncd = -1;
46918334Speter	if (rtncd != 0) return(rtncd);
47018334Speter#endif /* sun */
47118334Speter
47250397Sobrien
47318334Speter	/*
47418334Speter	 * If the "temp" flag is FALSE, we need to permanently set the
47518334Speter	 * system name in the file  /etc/rc2.d/S18setuname
47618334Speter	 */
47750397Sobrien
47818334Speter	if (!temp) {
47918334Speter	    /*
48018334Speter	     * If a name was specified by the caller, use that, otherwise, use
48118334Speter	     * whatever was in the "rc" file.
48218334Speter	     */
48318334Speter
48450397Sobrien		if (sysname) sysnm = sysname;
48550397Sobrien		if (nodename) nodenm = nodename;
48650397Sobrien
48790075Sobrien
48818334Speter	    /*
48918334Speter	     * Write the file /etc/rc2.d/S18setuname so that the system name is
49018334Speter	     * set on boots and state changes.
49118334Speter	     *
49218334Speter	     * DISABLED SIGNALS: SIGHUP, SIGINT
49318334Speter	     */
49418334Speter
49518334Speter	    /* Give us a reasonable chance to complete without interruptions */
49618334Speter		oldsighup = signal(SIGHUP, SIG_IGN);
49718334Speter		oldsigint = signal(SIGINT, SIG_IGN);
49850397Sobrien
49918334Speter	    /* Write the new setuname "rc" file */
500132718Skan		if (sysname != NULL) {
50190075Sobrien			if ((fd = fopen(RC_FILENAME, "w")) != (FILE *) NULL) {
50290075Sobrien				(void) fprintf(fd, "# %s\n", sysnm);
50390075Sobrien				(void) fprintf(fd, "#\n");
50452284Sobrien				(void) fprintf(fd, "# This script, generated by the setuname command,\n");
50550397Sobrien				(void) fprintf(fd, "# sets the system's system-name\n");
50652284Sobrien				(void) fprintf(fd, "#\n");
50752284Sobrien			if (sysnm && *sysnm)
50850397Sobrien				(void) fprintf(fd, "setuname -t -s %s\n", sysnm);
50952284Sobrien			(void) fclose(fd);
51052284Sobrien			} else return(rtncd = -1);
511132718Skan		}
51252284Sobrien
51352284Sobrien		if(nodename != NULL) {
51450397Sobrien			char curname[SYS_NMLN];
51552284Sobrien			int curlen;
51652284Sobrien			FILE *file;
517132718Skan
51890075Sobrien			if ((file = fopen("/etc/nodename", "r")) != NULL) {
51990075Sobrien				curlen = fread(curname, sizeof(char), SYS_NMLN, file);
52050397Sobrien				for (i = 0; i < curlen; i++) {
52152284Sobrien					if (curname[i] == '\n') {
52252284Sobrien						curname[i] = '\0';
52352284Sobrien						break;
52452284Sobrien					}
52552284Sobrien				}
52652284Sobrien				if (i == curlen) {
52752284Sobrien					curname[curlen] = '\0';
52852284Sobrien				}
52952284Sobrien				(void)fclose(file);
53052284Sobrien			} else {
53118334Speter				curname[0] = '\0';
53218334Speter			}
53352284Sobrien			if (strcmp(curname, nodenm) != 0) {
53452284Sobrien				if ((file = fopen("/etc/nodename", "w")) == NULL) {
53590075Sobrien					(void) fprintf(stderr, "setuname: error in writing name\n");
53652284Sobrien					exit(1);
537132718Skan				}
53852284Sobrien				if (fprintf(file, "%s\n", nodenm) < 0) {
53990075Sobrien					(void) fprintf(stderr, "setuname: error in writing name\n");
540169689Skan					exit(1);
54190075Sobrien				}
542169689Skan				(void)fclose(file);
543169689Skan			}
544169689Skan		}
545169689Skan	    /* Restore signal handling */
54690075Sobrien		(void) signal(SIGHUP, oldsighup);
547169689Skan		(void) signal(SIGINT, oldsigint);
548169689Skan	}	/* if (!temp) */
549169689Skan
550169689Skan	/* Fini */
551169689Skan	return(rtncd);
552169689Skan}
553169689Skan