14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1992-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * *
204887Schin ***********************************************************************/
214887Schin #pragma prototyped
224887Schin /*
234887Schin * David Korn
244887Schin * AT&T Bell Laboratories
254887Schin *
264887Schin * dirname path [suffix]
274887Schin *
284887Schin * print the dirname of a pathname
294887Schin */
304887Schin
314887Schin static const char usage[] =
3210898Sroland.mainz@nrubsig.org "[-?\n@(#)$Id: dirname (AT&T Research) 2009-01-31 $\n]"
334887Schin USAGE_LICENSE
344887Schin "[+NAME?dirname - return directory portion of file name]"
354887Schin "[+DESCRIPTION?\bdirname\b treats \astring\a as a file name and returns "
364887Schin "the name of the directory containing the file name by deleting "
374887Schin "the last component from \astring\a.]"
384887Schin "[+?If \astring\a consists solely of \b/\b characters the output will "
394887Schin "be a single \b/\b unless \bPATH_LEADING_SLASHES\b returned by "
404887Schin "\bgetconf\b(1) is \b1\b and \astring\a consists of multiple "
414887Schin "\b/\b characters in which case \b//\b will be output. "
424887Schin "Otherwise, trailing \b/\b characters are removed, and if "
434887Schin "there are no remaining \b/\b characters in \astring\a, "
444887Schin "the string \b.\b will be written to standard output. "
454887Schin "Otherwise, all characters following the last \b/\b are removed. "
464887Schin "If the remaining string consists solely of \b/\b characters, "
474887Schin "the output will be as if the original string had consisted solely "
484887Schin "as \b/\b characters as described above. Otherwise, all "
494887Schin "trailing slashes are removed and the output will be this string "
504887Schin "unless this string is empty. If empty the output will be \b.\b.]"
5110898Sroland.mainz@nrubsig.org "[f:file?Print the \b$PATH\b relative regular file path for \astring\a.]"
5210898Sroland.mainz@nrubsig.org "[r:relative?Print the \b$PATH\b relative readable file path for \astring\a.]"
5310898Sroland.mainz@nrubsig.org "[x:executable?Print the \b$PATH\b relative executable file path for \astring\a.]"
544887Schin "\n"
5510898Sroland.mainz@nrubsig.org "\nstring\n"
564887Schin "\n"
574887Schin "[+EXIT STATUS?]{"
584887Schin "[+0?Successful Completion.]"
594887Schin "[+>0?An error occurred.]"
604887Schin "}"
6110898Sroland.mainz@nrubsig.org "[+SEE ALSO?\bbasename\b(1), \bgetconf\b(1), \bdirname\b(3), \bpathname\b(3)]"
624887Schin ;
634887Schin
644887Schin #include <cmd.h>
654887Schin
l_dirname(register Sfio_t * outfile,register const char * pathname)664887Schin static void l_dirname(register Sfio_t *outfile, register const char *pathname)
674887Schin {
684887Schin register const char *last;
694887Schin /* go to end of path */
704887Schin for(last=pathname; *last; last++);
714887Schin /* back over trailing '/' */
724887Schin while(last>pathname && *--last=='/');
734887Schin /* back over non-slash chars */
744887Schin for(;last>pathname && *last!='/';last--);
754887Schin if(last==pathname)
764887Schin {
774887Schin /* all '/' or "" */
784887Schin if(*pathname!='/')
794887Schin last = pathname = ".";
804887Schin }
814887Schin else
824887Schin {
834887Schin /* back over trailing '/' */
844887Schin for(;*last=='/' && last > pathname; last--);
854887Schin }
864887Schin /* preserve // */
874887Schin if(last!=pathname && pathname[0]=='/' && pathname[1]=='/')
884887Schin {
894887Schin while(pathname[2]=='/' && pathname<last)
904887Schin pathname++;
914887Schin if(last!=pathname && pathname[0]=='/' && pathname[1]=='/' && *astconf("PATH_LEADING_SLASHES",NiL,NiL)!='1')
924887Schin pathname++;
934887Schin }
944887Schin sfwrite(outfile,pathname,last+1-pathname);
954887Schin sfputc(outfile,'\n');
964887Schin }
974887Schin
984887Schin int
b_dirname(int argc,register char * argv[],void * context)994887Schin b_dirname(int argc,register char *argv[], void* context)
1004887Schin {
1014887Schin register int n;
10210898Sroland.mainz@nrubsig.org int mode = 0;
10310898Sroland.mainz@nrubsig.org char buf[PATH_MAX];
1044887Schin
1054887Schin cmdinit(argc, argv, context, ERROR_CATALOG, 0);
1064887Schin while (n = optget(argv, usage)) switch (n)
1074887Schin {
10810898Sroland.mainz@nrubsig.org case 'f':
10910898Sroland.mainz@nrubsig.org mode |= PATH_REGULAR;
11010898Sroland.mainz@nrubsig.org break;
11110898Sroland.mainz@nrubsig.org case 'r':
11210898Sroland.mainz@nrubsig.org mode &= ~PATH_REGULAR;
11310898Sroland.mainz@nrubsig.org mode |= PATH_READ;
11410898Sroland.mainz@nrubsig.org break;
11510898Sroland.mainz@nrubsig.org case 'x':
11610898Sroland.mainz@nrubsig.org mode |= PATH_EXECUTE;
11710898Sroland.mainz@nrubsig.org break;
1184887Schin case ':':
1194887Schin error(2, "%s", opt_info.arg);
1204887Schin break;
1214887Schin case '?':
1224887Schin error(ERROR_usage(2), "%s", opt_info.arg);
1234887Schin break;
1244887Schin }
1254887Schin argv += opt_info.index;
1264887Schin argc -= opt_info.index;
1274887Schin if(error_info.errors || argc != 1)
1284887Schin error(ERROR_usage(2),"%s", optusage(NiL));
12910898Sroland.mainz@nrubsig.org if(!mode)
13010898Sroland.mainz@nrubsig.org l_dirname(sfstdout,argv[0]);
13110898Sroland.mainz@nrubsig.org else if(pathpath(buf, argv[0], "", mode))
13210898Sroland.mainz@nrubsig.org sfputr(sfstdout, buf, '\n');
13310898Sroland.mainz@nrubsig.org else
13410898Sroland.mainz@nrubsig.org error(1|ERROR_WARNING, "%s: relative path not found", argv[0]);
1354887Schin return(0);
1364887Schin }
137