source: trunk/base/src/pextlib1.0/compat.c @ 19376

Last change on this file since 19376 was 19376, checked in by yeled@…, 11 years ago

add svn:keywords Id

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.3 KB
Line 
1/*
2 * compat.c
3 * $Id: compat.c 19376 2006-09-02 03:19:06Z yeled@macports.org $
4 *
5 * Copyright (c) 2004 Paul Guyot, Darwinports Team.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of Darwinports Team nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#if HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include <sys/param.h>
38#include <stdlib.h>
39#include <errno.h>
40#include <unistd.h>
41
42#if HAVE_LIBGEN_H
43#include <libgen.h>
44#endif
45
46#if HAVE_STRING_H
47#include <string.h>
48#endif
49
50#include <tcl.h>
51#include <tclDecls.h>
52
53#include "compat.h"
54
55/* Avoid a warning with Tcl < 8.4, even if Tcl_GetIndexFromObj's tablePtr
56probably isn't modified. */
57#if (TCL_MAJOR_VERSION > 8) || (TCL_MINOR_VERSION >= 4)
58typedef CONST char* tableEntryString;
59#else
60typedef char* tableEntryString;
61#endif
62
63/* ========================================================================= **
64 * Definitions
65 * ========================================================================= */
66#pragma mark Definitions
67
68/* ------------------------------------------------------------------------- **
69 * Prototypes
70 * ------------------------------------------------------------------------- */
71int CompatFileNormalize(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[]);
72
73/* ========================================================================= **
74 * Entry points
75 * ========================================================================= */
76#pragma mark -
77#pragma mark Entry points
78
79
80/**
81 * compat filelinkhard subcommand entry point.
82 *
83 * @param interp                current interpreter
84 * @param objc                  number of parameters
85 * @param objv                  parameters
86 */
87int
88CompatFileLinkHard(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[])
89{
90        int theResult = TCL_OK;
91
92        do {
93                char* theSrcPath;
94                char* theDstPath;
95               
96                /* we only have two parameters. */
97                if (objc != 4) {
98                        Tcl_WrongNumArgs(interp, 1, objv, "filelinkhard dstpath srcpath");
99                        theResult = TCL_ERROR;
100                        break;
101                }
102
103                /* retrieve the parameters */
104                theDstPath = Tcl_GetString(objv[2]);
105                theSrcPath = Tcl_GetString(objv[3]);
106               
107                /* perform the hard link */
108                if (link(theSrcPath, theDstPath) < 0)
109                {
110                        /* some error occurred. Report it. */
111                        Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
112                        theResult = TCL_ERROR;
113                        break;
114                }
115    } while (0);
116   
117        return theResult;
118}
119
120/**
121 * compat filelinksymbolic subcommand entry point.
122 *
123 * @param interp                current interpreter
124 * @param objc                  number of parameters
125 * @param objv                  parameters
126 */
127int
128CompatFileLinkSymbolic(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[])
129{
130        int theResult = TCL_OK;
131
132        do {
133                char* theSrcPath;
134                char* theDstPath;
135               
136                /* we only have two parameters. */
137                if (objc != 4) {
138                        Tcl_WrongNumArgs(interp, 1, objv, "filelinksymbolic dstpath srcpath");
139                        theResult = TCL_ERROR;
140                        break;
141                }
142
143                /* retrieve the parameters */
144                theDstPath = Tcl_GetString(objv[2]);
145                theSrcPath = Tcl_GetString(objv[3]);
146               
147                /* perform the symbolic link */
148                if (symlink(theSrcPath, theDstPath) < 0)
149                {
150                        /* some error occurred. Report it. */
151                        Tcl_SetResult(interp, strerror(errno), TCL_VOLATILE);
152                        theResult = TCL_ERROR;
153                        break;
154                }
155    } while (0);
156   
157        return theResult;
158}
159
160/**
161 * compat filenormalize subcommand entry point.
162 *
163 * @param interp                current interpreter
164 * @param objc                  number of parameters
165 * @param objv                  parameters
166 */
167int
168CompatFileNormalize(Tcl_Interp* interp, int objc, Tcl_Obj* CONST objv[])
169{
170        int theResult = TCL_OK;
171
172        do {
173                char* thePath;
174                char tmpPath[PATH_MAX];
175                char* theBaseName;
176                char theNormalizedPath[PATH_MAX];
177                int pathlength;
178                int baselength;
179               
180                /*      unique (second) parameter is the file path */
181                if (objc != 3) {
182                        Tcl_WrongNumArgs(interp, 1, objv, "filenormalize path");
183                        theResult = TCL_ERROR;
184                        break;
185                }
186
187                /* retrieve the parameter */
188                thePath = Tcl_GetString(objv[2]);
189               
190                /* Some implementations of dirname(3) modify the memory
191                        referenced by its argument, so we make a copy of thePath
192                        just in case. */
193                (void) strncpy(tmpPath, (const char*) thePath, sizeof(tmpPath));
194
195                /* normalize the dir name */
196                (void) realpath(dirname(tmpPath), theNormalizedPath);
197               
198                /* append the base name */
199                pathlength = strlen(theNormalizedPath);
200                theBaseName = basename(thePath);
201                baselength = strlen(theBaseName);
202                if (pathlength + baselength + 1 >= PATH_MAX)
203                {
204                        Tcl_SetResult(interp, "path is too long", TCL_STATIC);
205                        theResult = TCL_ERROR;
206                        break;
207                }
208                theNormalizedPath[pathlength] = '/';
209                /* copy with null terminator */
210                (void) memcpy(
211                                        &theNormalizedPath[pathlength + 1],
212                                        theBaseName,
213                                        baselength + 1);
214               
215                Tcl_SetResult(interp, theNormalizedPath, TCL_VOLATILE);
216    } while (0);
217   
218        return theResult;
219}
220
221/**
222 * compat command entry point.
223 *
224 * @param clientData    custom data (ignored)
225 * @param interp                current interpreter
226 * @param objc                  number of parameters
227 * @param objv                  parameters
228 */
229int
230CompatCmd(
231                ClientData clientData UNUSED,
232                Tcl_Interp* interp,
233                int objc, 
234                Tcl_Obj* CONST objv[])
235{
236    typedef enum {
237        kCompatFileNormalize,
238        kCompatFileLinkHard,
239        kCompatFileLinkSymbolic
240    } EOption;
241   
242        static tableEntryString options[] = {
243                "filenormalize", "filelinkhard", "filelinksymbolic", NULL
244        };
245
246        int theResult = TCL_OK;
247        EOption theOptionIndex;
248
249        if (objc < 2) {
250                Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
251                return TCL_ERROR;
252        }
253
254        theResult = Tcl_GetIndexFromObj(
255                                interp,
256                                objv[1],
257                                options,
258                                "option",
259                                0,
260                                (int*) &theOptionIndex);
261        if (theResult == TCL_OK) {
262                switch (theOptionIndex)
263                {
264                        case kCompatFileNormalize:
265                                theResult = CompatFileNormalize(interp, objc, objv);
266                                break;
267
268                        case kCompatFileLinkHard:
269                                theResult = CompatFileLinkHard(interp, objc, objv);
270                                break;
271
272                        case kCompatFileLinkSymbolic:
273                                theResult = CompatFileLinkSymbolic(interp, objc, objv);
274                                break;
275                }
276        }
277       
278        return theResult;
279}
280
281/* ============================================================== **
282** As of next Thursday, UNIX will be flushed in favor of TOPS-10. **
283** Please update your programs.                                   **
284** ============================================================== */
Note: See TracBrowser for help on using the repository browser.