tclMacUnix.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:10k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* 
  2.  * tclMacUnix.c --
  3.  *
  4.  * This file contains routines to implement several features
  5.  * available to the Unix implementation, but that require
  6.  *      extra work to do on a Macintosh.  These include routines
  7.  *      Unix Tcl normally hands off to the Unix OS.
  8.  *
  9.  * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
  10.  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
  11.  *
  12.  * See the file "license.terms" for information on usage and redistribution
  13.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  14.  *
  15.  * RCS: @(#) $Id: tclMacUnix.c,v 1.5 2002/10/09 11:54:45 das Exp $
  16.  */
  17. #include <Files.h>
  18. #include <Strings.h>
  19. #include <TextUtils.h>
  20. #include <Finder.h>
  21. #include <FSpCompat.h>
  22. #include <Aliases.h>
  23. #include <Errors.h>
  24. #include "tclInt.h"
  25. #include "tclMacInt.h"
  26. /*
  27.  * The following two Includes are from the More Files package
  28.  */
  29. #include "FileCopy.h"
  30. #include "MoreFiles.h"
  31. #include "MoreFilesExtras.h"
  32. /*
  33.  * The following may not be defined in some versions of
  34.  * MPW header files.
  35.  */
  36. #ifndef kIsInvisible
  37. #define kIsInvisible 0x4000
  38. #endif
  39. #ifndef kIsAlias
  40. #define kIsAlias 0x8000
  41. #endif
  42. /*
  43.  * Missing error codes
  44.  */
  45. #define usageErr 500
  46. #define noSourceErr 501
  47. #define isDirErr 502
  48. /*
  49.  *----------------------------------------------------------------------
  50.  *
  51.  * Tcl_EchoCmd --
  52.  *
  53.  *    Implements the TCL echo command:
  54.  *        echo ?str ...?
  55.  *
  56.  * Results:
  57.  *      Always returns TCL_OK.
  58.  *
  59.  * Side effects:
  60.  * None.
  61.  *
  62.  *----------------------------------------------------------------------
  63.  */
  64. int
  65. Tcl_EchoCmd(
  66.     ClientData dummy, /* Not used. */
  67.     Tcl_Interp *interp, /* Current interpreter. */
  68.     int argc, /* Number of arguments. */
  69.     CONST char **argv) /* Argument strings. */
  70. {
  71.     Tcl_Channel chan;
  72.     int mode, result, i;
  73.     chan = Tcl_GetChannel(interp, "stdout", &mode);
  74.     if (chan == (Tcl_Channel) NULL) {
  75.         return TCL_ERROR;
  76.     }
  77.     for (i = 1; i < argc; i++) {
  78. result = Tcl_WriteChars(chan, argv[i], -1);
  79. if (result < 0) {
  80.     Tcl_AppendResult(interp, "echo: ", Tcl_GetChannelName(chan),
  81.     ": ", Tcl_PosixError(interp), (char *) NULL);
  82.     return TCL_ERROR;
  83. }
  84.         if (i < (argc - 1)) {
  85.     Tcl_WriteChars(chan, " ", -1);
  86. }
  87.     }
  88.     Tcl_WriteChars(chan, "n", -1);
  89.     return TCL_OK;
  90. }
  91. /*
  92.  *----------------------------------------------------------------------
  93.  *
  94.  * Tcl_LsObjCmd --
  95.  *
  96.  * This procedure is invoked to process the "ls" Tcl command.
  97.  * See the user documentation for details on what it does.
  98.  *
  99.  * Results:
  100.  * A standard Tcl result.
  101.  *
  102.  * Side effects:
  103.  * See the user documentation.
  104.  *
  105.  *----------------------------------------------------------------------
  106.  */
  107. int
  108. Tcl_LsObjCmd(
  109.     ClientData dummy, /* Not used. */
  110.     Tcl_Interp *interp, /* Current interpreter. */
  111.     int objc, /* Number of arguments. */
  112.     Tcl_Obj *CONST objv[]) /* Argument strings. */
  113. {
  114. #define STRING_LENGTH 80
  115. #define CR 'n'
  116.     int i, j;
  117.     int fieldLength, len = 0, maxLen = 0, perLine;
  118.     OSErr err;
  119.     CInfoPBRec paramBlock;
  120.     HFileInfo *hpb = (HFileInfo *)&paramBlock;
  121.     DirInfo *dpb = (DirInfo *)&paramBlock;
  122.     char theFile[256];
  123.     char theLine[STRING_LENGTH + 2];
  124.     int fFlag = false, pFlag = false, aFlag = false, lFlag = false,
  125. cFlag = false, hFlag = false;
  126.     char *argv;
  127.     Tcl_Obj *newObjv[2], *resultObjPtr;
  128.     /*
  129.      * Process command flags.  End if argument doesn't start
  130.      * with a dash or is a dash by itself.  The remaining arguments
  131.      * should be files.
  132.      */
  133.     for (i = 1; i < objc; i++) {
  134.      argv = Tcl_GetString(objv[i]);
  135. if (argv[0] != '-') {
  136.     break;
  137. }
  138. if (!strcmp(argv, "-")) {
  139.     i++;
  140.     break;
  141. }
  142. for (j = 1 ; argv[j] ; ++j) {
  143.     switch(argv[j]) {
  144.     case 'a':
  145.     case 'A':
  146. aFlag = true;
  147. break;
  148.     case '1':
  149. cFlag = false;
  150. break;
  151.     case 'C':
  152. cFlag = true;
  153. break;
  154.     case 'F':
  155. fFlag = true;
  156. break;
  157.     case 'H':
  158. hFlag = true;
  159. break;
  160.     case 'p':
  161. pFlag = true;
  162. break;
  163.     case 'l':
  164. pFlag = false;
  165. lFlag = true;
  166. break;
  167.     default:
  168. Tcl_AppendResult(interp, "error - unknown flag ",
  169. "usage: ls -apCFHl1 ?files? ", NULL);
  170. return TCL_ERROR;
  171.     }
  172. }
  173.     }
  174.     objv += i;
  175.     objc -= i;
  176.     /*
  177.      * No file specifications means we search for all files.
  178.      * Glob will be doing most of the work.
  179.      */
  180.      if (!objc) {
  181. objc = 1;
  182. newObjv[0] = Tcl_NewStringObj("*", -1);
  183. newObjv[1] = NULL;
  184. objv = newObjv;
  185.     }
  186.     if (Tcl_GlobObjCmd(NULL, interp, objc + 1, objv - 1) != TCL_OK) {
  187.      Tcl_ResetResult(interp);
  188.      return TCL_ERROR;
  189.     }
  190.     resultObjPtr = Tcl_GetObjResult(interp);
  191.     Tcl_IncrRefCount(resultObjPtr);
  192.     if (Tcl_ListObjGetElements(interp, resultObjPtr, &objc, (Tcl_Obj ***)&objv) != TCL_OK) {
  193.      Tcl_DecrRefCount(resultObjPtr);
  194.      return TCL_ERROR;
  195.     }
  196.     Tcl_ResetResult(interp);
  197.     /*
  198.      * There are two major methods for listing files: the long
  199.      * method and the normal method.
  200.      */
  201.     if (lFlag) {
  202. char creator[5], type[5], time[16], date[16];
  203. char lineTag;
  204. long size;
  205. unsigned short flags;
  206. Tcl_Obj *objPtr;
  207. char *string;
  208. int length;
  209. /*
  210.  * Print the header for long listing.
  211.  */
  212. if (hFlag) {
  213.     sprintf(theLine, "T %7s %8s %8s %4s %4s %6s %s",
  214.     "Size", "ModTime", "ModDate",
  215.     "CRTR", "TYPE", "Flags", "Name");
  216.     Tcl_AppendResult(interp, theLine, "n", NULL);
  217.     Tcl_AppendResult(interp,
  218.     "-------------------------------------------------------------n",
  219.     NULL);
  220. }
  221. for (i = 0; i < objc; i++) {
  222.     strcpy(theFile, Tcl_GetString(objv[i]));
  223.     c2pstr(theFile);
  224.     hpb->ioCompletion = NULL;
  225.     hpb->ioVRefNum = 0;
  226.     hpb->ioFDirIndex = 0;
  227.     hpb->ioNamePtr = (StringPtr) theFile;
  228.     hpb->ioDirID = 0L;
  229.     err = PBGetCatInfoSync(&paramBlock);
  230.     p2cstr((StringPtr) theFile);
  231.     if (hpb->ioFlAttrib & 16) {
  232. /*
  233.  * For directories use zero as the size, use no Creator
  234.  * type, and use 'DIR ' as the file type.
  235.  */
  236. if ((aFlag == false) && (dpb->ioDrUsrWds.frFlags & 0x1000)) {
  237.     continue;
  238. }
  239. lineTag = 'D';
  240. size = 0;
  241. IUTimeString(dpb->ioDrMdDat, false, (unsigned char *)time);
  242. p2cstr((StringPtr)time);
  243. IUDateString(dpb->ioDrMdDat, shortDate, (unsigned char *)date);
  244. p2cstr((StringPtr)date);
  245. strcpy(creator, "    ");
  246. strcpy(type, "DIR ");
  247. flags = dpb->ioDrUsrWds.frFlags;
  248. if (fFlag || pFlag) {
  249.     strcat(theFile, ":");
  250. }
  251.     } else {
  252. /*
  253.  * All information for files should be printed.  This
  254.  * includes size, modtime, moddate, creator type, file
  255.  * type, flags, anf file name.
  256.  */
  257. if ((aFlag == false) &&
  258. (hpb->ioFlFndrInfo.fdFlags & kIsInvisible)) {
  259.     continue;
  260. }
  261. lineTag = 'F';
  262. size = hpb->ioFlLgLen + hpb->ioFlRLgLen;
  263. IUTimeString(hpb->ioFlMdDat, false, (unsigned char *)time);
  264. p2cstr((StringPtr)time);
  265. IUDateString(hpb->ioFlMdDat, shortDate, (unsigned char *)date);
  266. p2cstr((StringPtr)date);
  267. strncpy(creator, (char *) &hpb->ioFlFndrInfo.fdCreator, 4);
  268. creator[4] = 0;
  269. strncpy(type, (char *) &hpb->ioFlFndrInfo.fdType, 4);
  270. type[4] = 0;
  271. flags = hpb->ioFlFndrInfo.fdFlags;
  272. if (fFlag) {
  273.     if (hpb->ioFlFndrInfo.fdFlags & kIsAlias) {
  274. strcat(theFile, "@");
  275.     } else if (hpb->ioFlFndrInfo.fdType == 'APPL') {
  276. strcat(theFile, "*");
  277.     }
  278. }
  279.     }
  280.     sprintf(theLine, "%c %7ld %8s %8s %-4.4s %-4.4s 0x%4.4X %s",
  281.     lineTag, size, time, date, creator, type, flags, theFile);
  282.  
  283.     Tcl_AppendResult(interp, theLine, "n", NULL);
  284.     
  285. }
  286. objPtr = Tcl_GetObjResult(interp);
  287. string = Tcl_GetStringFromObj(objPtr, &length);
  288. if ((length > 0) && (string[length - 1] == 'n')) {
  289.     Tcl_SetObjLength(objPtr, length - 1);
  290. }
  291.     } else {
  292. /*
  293.  * Not in long format. We only print files names.  If the
  294.  * -C flag is set we need to print in multiple coloumns.
  295.  */
  296. int argCount, linePos;
  297. Boolean needNewLine = false;
  298. /*
  299.  * Fiend the field length: the length each string printed
  300.  * to the terminal will be.
  301.  */
  302. if (!cFlag) {
  303.     perLine = 1;
  304.     fieldLength = STRING_LENGTH;
  305. } else {
  306.     for (i = 0; i < objc; i++) {
  307.      argv = Tcl_GetString(objv[i]);
  308. len = strlen(argv);
  309. if (len > maxLen) {
  310.     maxLen = len;
  311. }
  312.     }
  313.     fieldLength = maxLen + 3;
  314.     perLine = STRING_LENGTH / fieldLength;
  315. }
  316. argCount = 0;
  317. linePos = 0;
  318. memset(theLine, ' ', STRING_LENGTH);
  319. while (argCount < objc) {
  320.     strcpy(theFile, Tcl_GetString(objv[argCount]));
  321.     c2pstr(theFile);
  322.     hpb->ioCompletion = NULL;
  323.     hpb->ioVRefNum = 0;
  324.     hpb->ioFDirIndex = 0;
  325.     hpb->ioNamePtr = (StringPtr) theFile;
  326.     hpb->ioDirID = 0L;
  327.     err = PBGetCatInfoSync(&paramBlock);
  328.     p2cstr((StringPtr) theFile);
  329.     if (hpb->ioFlAttrib & 16) {
  330. /*
  331.  * Directory. If -a show hidden files.  If -f or -p
  332.  * denote that this is a directory.
  333.  */
  334. if ((aFlag == false) && (dpb->ioDrUsrWds.frFlags & 0x1000)) {
  335.     argCount++;
  336.     continue;
  337. }
  338. if (fFlag || pFlag) {
  339.     strcat(theFile, ":");
  340. }
  341.     } else {
  342. /*
  343.  * File: If -a show hidden files, if -f show links
  344.  * (aliases) and executables (APPLs).
  345.  */
  346. if ((aFlag == false) &&
  347. (hpb->ioFlFndrInfo.fdFlags & kIsInvisible)) {
  348.     argCount++;
  349.     continue;
  350. }
  351. if (fFlag) {
  352.     if (hpb->ioFlFndrInfo.fdFlags & kIsAlias) {
  353. strcat(theFile, "@");
  354.     } else if (hpb->ioFlFndrInfo.fdType == 'APPL') {
  355. strcat(theFile, "*");
  356.     }
  357. }
  358.     }
  359.     /*
  360.      * Print the item, taking into account multi-
  361.      * coloum output.
  362.      */
  363.     strncpy(theLine + (linePos * fieldLength), theFile,
  364.     strlen(theFile));
  365.     linePos++;
  366.     if (linePos == perLine) {
  367. theLine[STRING_LENGTH] = '';
  368. if (needNewLine) {
  369.     Tcl_AppendResult(interp, "n", theLine, NULL);
  370. } else {
  371.     Tcl_AppendResult(interp, theLine, NULL);
  372.     needNewLine = true;
  373. }
  374. linePos = 0;
  375. memset(theLine, ' ', STRING_LENGTH);
  376.     }
  377.     argCount++;
  378. }
  379. if (linePos != 0) {
  380.     theLine[STRING_LENGTH] = '';
  381.     if (needNewLine) {
  382. Tcl_AppendResult(interp, "n", theLine, NULL);
  383.     } else {
  384. Tcl_AppendResult(interp, theLine, NULL);
  385.     }
  386. }
  387.     }
  388.     Tcl_DecrRefCount(resultObjPtr);
  389.     
  390.     return TCL_OK;
  391. }