xref: /titanic_41/usr/src/ucbcmd/ln/ln.c (revision cc6c5292fa8a241fe50604cf6a918edfbf7cd7d2)
1*cc6c5292Schin /*
2*cc6c5292Schin  * Copyright 1991 Sun Microsystems, Inc.  All rights reserved.
3*cc6c5292Schin  * Use is subject to license terms.
4*cc6c5292Schin  */
5*cc6c5292Schin 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
127c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
15*cc6c5292Schin #pragma ident	"%Z%%M%	%I%	%E% SMI"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate /*
187c478bd9Sstevel@tonic-gate  * ln
197c478bd9Sstevel@tonic-gate  */
207c478bd9Sstevel@tonic-gate #include <stdio.h>
217c478bd9Sstevel@tonic-gate #include <sys/types.h>
227c478bd9Sstevel@tonic-gate #include <sys/param.h>
237c478bd9Sstevel@tonic-gate #include <sys/stat.h>
247c478bd9Sstevel@tonic-gate #include <errno.h>
25*cc6c5292Schin #include <unistd.h>
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate struct	stat stb;
287c478bd9Sstevel@tonic-gate int	fflag;		/* force flag set? */
297c478bd9Sstevel@tonic-gate int	sflag;
307c478bd9Sstevel@tonic-gate 
31*cc6c5292Schin int linkit(char *, char *);
32*cc6c5292Schin void Perror(char *);
33*cc6c5292Schin 
34*cc6c5292Schin int
main(int argc,char ** argv)35*cc6c5292Schin main(int argc, char **argv)
367c478bd9Sstevel@tonic-gate {
37*cc6c5292Schin 	int i, r;
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate 	argc--, argv++;
407c478bd9Sstevel@tonic-gate again:
417c478bd9Sstevel@tonic-gate 	if (argc && strcmp(argv[0], "-f") == 0) {
427c478bd9Sstevel@tonic-gate 		fflag++;
437c478bd9Sstevel@tonic-gate 		argv++;
447c478bd9Sstevel@tonic-gate 		argc--;
457c478bd9Sstevel@tonic-gate 	}
467c478bd9Sstevel@tonic-gate 	if (argc && strcmp(argv[0], "-s") == 0) {
477c478bd9Sstevel@tonic-gate 		sflag++;
487c478bd9Sstevel@tonic-gate 		argv++;
497c478bd9Sstevel@tonic-gate 		argc--;
507c478bd9Sstevel@tonic-gate 	}
517c478bd9Sstevel@tonic-gate 	if (argc == 0)
527c478bd9Sstevel@tonic-gate 		goto usage;
537c478bd9Sstevel@tonic-gate 	else if (argc == 1) {
547c478bd9Sstevel@tonic-gate 		argv[argc] = ".";
557c478bd9Sstevel@tonic-gate 		argc++;
567c478bd9Sstevel@tonic-gate 	}
577c478bd9Sstevel@tonic-gate 	if (argc > 2) {
587c478bd9Sstevel@tonic-gate 		if (stat(argv[argc-1], &stb) < 0)
597c478bd9Sstevel@tonic-gate 			goto usage;
607c478bd9Sstevel@tonic-gate 		if ((stb.st_mode&S_IFMT) != S_IFDIR)
617c478bd9Sstevel@tonic-gate 			goto usage;
627c478bd9Sstevel@tonic-gate 	}
637c478bd9Sstevel@tonic-gate 	r = 0;
647c478bd9Sstevel@tonic-gate 	for (i = 0; i < argc-1; i++)
657c478bd9Sstevel@tonic-gate 		r |= linkit(argv[i], argv[argc-1]);
667c478bd9Sstevel@tonic-gate 	exit(r);
677c478bd9Sstevel@tonic-gate usage:
687c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr,
697c478bd9Sstevel@tonic-gate 	    "Usage: ln [-f] [-s] f1\n\
707c478bd9Sstevel@tonic-gate        ln [-f] [-s] f1 f2\n\
717c478bd9Sstevel@tonic-gate        ln [-f] [-s] f1 ... fn d1\n");
72*cc6c5292Schin 	return (1);
737c478bd9Sstevel@tonic-gate }
747c478bd9Sstevel@tonic-gate 
75*cc6c5292Schin int
linkit(char * from,char * to)76*cc6c5292Schin linkit(char *from, char *to)
777c478bd9Sstevel@tonic-gate {
787c478bd9Sstevel@tonic-gate 	char destname[MAXPATHLEN + 1];
797c478bd9Sstevel@tonic-gate 	char *tail;
807c478bd9Sstevel@tonic-gate 	int (*linkf)() = sflag ? symlink : link;
817c478bd9Sstevel@tonic-gate 	char *strrchr();
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate 	/* is target a directory? */
84*cc6c5292Schin 	if (sflag == 0 && fflag == 0 && stat(from, &stb) >= 0 &&
85*cc6c5292Schin 	    (stb.st_mode&S_IFMT) == S_IFDIR) {
867c478bd9Sstevel@tonic-gate 		printf("%s is a directory\n", from);
877c478bd9Sstevel@tonic-gate 		return (1);
887c478bd9Sstevel@tonic-gate 	}
897c478bd9Sstevel@tonic-gate 	if (stat(to, &stb) >= 0 && (stb.st_mode&S_IFMT) == S_IFDIR) {
907c478bd9Sstevel@tonic-gate 		tail = strrchr(from, '/');
917c478bd9Sstevel@tonic-gate 		if (tail == 0)
927c478bd9Sstevel@tonic-gate 			tail = from;
937c478bd9Sstevel@tonic-gate 		else
947c478bd9Sstevel@tonic-gate 			tail++;
95*cc6c5292Schin 		if (strlen(to) + strlen(tail) >= sizeof (destname) - 1) {
967c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "ln: %s/%s: Name too long\n",
977c478bd9Sstevel@tonic-gate 			    to, tail);
987c478bd9Sstevel@tonic-gate 			return (1);
997c478bd9Sstevel@tonic-gate 		}
1007c478bd9Sstevel@tonic-gate 		(void) sprintf(destname, "%s/%s", to, tail);
1017c478bd9Sstevel@tonic-gate 		to = destname;
1027c478bd9Sstevel@tonic-gate 	}
1037c478bd9Sstevel@tonic-gate 	if ((*linkf)(from, to) < 0) {
1047c478bd9Sstevel@tonic-gate 		if (errno == EEXIST || sflag)
1057c478bd9Sstevel@tonic-gate 			Perror(to);
1067c478bd9Sstevel@tonic-gate 		else if (access(from, 0) < 0)
1077c478bd9Sstevel@tonic-gate 			Perror(from);
1087c478bd9Sstevel@tonic-gate 		else
1097c478bd9Sstevel@tonic-gate 			Perror(to);
1107c478bd9Sstevel@tonic-gate 		return (1);
1117c478bd9Sstevel@tonic-gate 	}
1127c478bd9Sstevel@tonic-gate 	return (0);
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate 
115*cc6c5292Schin void
Perror(char * s)116*cc6c5292Schin Perror(char *s)
1177c478bd9Sstevel@tonic-gate {
1187c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "ln: ");
1197c478bd9Sstevel@tonic-gate 	perror(s);
1207c478bd9Sstevel@tonic-gate }
121