home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume34 / imagemagick / part04 < prev    next >
Text File  |  1992-12-14  |  58KB  |  1,788 lines

  1. Newsgroups: comp.sources.misc
  2. From: cristy@eplrx7.es.duPont.com (John Cristy)
  3. Subject:  v34i032:  imagemagick - X11 image processing and display v2.2, Part04/26
  4. Message-ID: <1992Dec13.202628.9134@sparky.imd.sterling.com>
  5. X-Md4-Signature: dec96e78722fbf562d89c95274db03a9
  6. Date: Sun, 13 Dec 1992 20:26:28 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: cristy@eplrx7.es.duPont.com (John Cristy)
  10. Posting-number: Volume 34, Issue 32
  11. Archive-name: imagemagick/part04
  12. Environment: UNIX, VMS, X11, SGI, DEC, Cray, Sun, Vax
  13.  
  14. #!/bin/sh
  15. # this is Part.04 (part 4 of a multipart archive)
  16. # do not concatenate these parts, unpack them in order with /bin/sh
  17. # file ImageMagick/xtp/xtp.c continued
  18. #
  19. if test ! -r _shar_seq_.tmp; then
  20.     echo 'Please unpack part 1 first!'
  21.     exit 1
  22. fi
  23. (read Scheck
  24.  if test "$Scheck" != 4; then
  25.     echo Please unpack part "$Scheck" next!
  26.     exit 1
  27.  else
  28.     exit 0
  29.  fi
  30. ) < _shar_seq_.tmp || exit 1
  31. if test ! -f _shar_wnt_.tmp; then
  32.     echo 'x - still skipping ImageMagick/xtp/xtp.c'
  33. else
  34. echo 'x - continuing file ImageMagick/xtp/xtp.c'
  35. sed 's/^X//' << 'SHAR_EOF' >> 'ImageMagick/xtp/xtp.c' &&
  36. %
  37. %  A description of each parameter follows:
  38. %
  39. %    o prune:  Specifies whether to recusively search for files.
  40. %
  41. %    o verbose: An unsigned integer.  A value other than zero dhows all
  42. %      responses from the remote server.
  43. %
  44. %
  45. */
  46. static void ProcessRequest(prune,verbose)
  47. unsigned int
  48. X  prune,
  49. X  verbose;
  50. {
  51. X  typedef struct _DirectoryNode
  52. X  {
  53. X    char
  54. X      *info,
  55. X      *name;
  56. X
  57. X    struct _DirectoryNode
  58. X      *next;
  59. X  } DirectoryNode;
  60. X
  61. X  char
  62. X    command[2048],
  63. X    directory[2048],
  64. X    *info,
  65. X    *name,
  66. X    *response;
  67. X
  68. X  DirectoryNode
  69. X    *next,
  70. X    *root;
  71. X
  72. X  register char
  73. X    *p;
  74. X
  75. X  register DirectoryNode
  76. X    **last,
  77. X    *node;
  78. X
  79. X  RegularExpression
  80. X    *date_expression,
  81. X    *mode_expression;
  82. X
  83. X  unsigned int
  84. X    unix_filesystem;
  85. X
  86. X  /*
  87. X    Initialize function variables.
  88. X  */
  89. X  root=(DirectoryNode *) NULL;
  90. X  last=(&root);
  91. X  *directory='\0';
  92. X  unix_filesystem=False;
  93. X  if (!prune)
  94. X    {
  95. X      /*
  96. X        Obtain a time sorted recursive directory if available.
  97. X      */
  98. X      (void) strcpy(command,"get ls-ltR.Z |zcat\r");
  99. X      (void) write(master,command,strlen(command));
  100. X      while (response=Wait())
  101. X        if ((status == 0) || (status == 5))
  102. X          break;
  103. X      if (status == 5)
  104. X        {
  105. X          /*
  106. X            Obtain a recursive directory if available.
  107. X          */
  108. X          while (Wait());
  109. X          (void) strcpy(command,"get ls-lR.Z |zcat\r");
  110. X          (void) write(master,command,strlen(command));
  111. X          while (response=Wait())
  112. X            if ((status == 0) || (status == 5))
  113. X              break;
  114. X        }
  115. X      if (status == 5)
  116. X        while (Wait());
  117. X      else
  118. X        {
  119. X          (void) fprintf(stderr,"Using existing directory listing...\n");
  120. X          unix_filesystem=True;
  121. X        }
  122. X    }
  123. X  if (prune || !unix_filesystem)
  124. X    {
  125. X      /*
  126. X        Determine if the FTP server has unix-style filenames.
  127. X      */
  128. X      mode_expression=CompileRegularExpression("^.[rwx-][rwx-][rwx-]");
  129. X      (void) strcpy(command,"dir\r");
  130. X      (void) write(master,command,strlen(command));
  131. X      while (response=Wait())
  132. X        if (!unix_filesystem)
  133. X          if (*response != '\0')
  134. X            unix_filesystem=ExecuteRegularExpression(mode_expression,response);
  135. X      (void) free((char *) mode_expression);
  136. X      /*
  137. X        Obtain recursive directory listing with the FTP directory command.
  138. X      */
  139. X      if (prune)
  140. X        (void) strcpy(command,"dir\r");
  141. X      else
  142. X        if (unix_filesystem)
  143. X          (void) strcpy(command,"ls -ltR\r");
  144. X        else
  145. X          (void) strcpy(command,"ls [...]\r");
  146. X      (void) write(master,command,strlen(command));
  147. X      while (response=Wait())
  148. X        if ((status == 0) || (status == 5))
  149. X          break;
  150. X      if (status == 5)
  151. X        {
  152. X          /*
  153. X            Directory command has limited functionality.
  154. X          */
  155. X          while (Wait());
  156. X          (void) strcpy(command,"dir\r");
  157. X          (void) write(master,command,strlen(command));
  158. X          while (response=Wait())
  159. X            if (status == 0)
  160. X              break;
  161. X        }
  162. X    }
  163. X  status=(-1);
  164. X  if (response == (char *) NULL)
  165. X    return;
  166. X  if (!unix_filesystem)
  167. X    do
  168. X    {
  169. X      /*
  170. X        Link non unix-style file into file list.
  171. X      */
  172. X      if ((status > 0) || (*response == '\0'))
  173. X        continue;
  174. X      while (*response == ' ')
  175. X        response++;
  176. X      /*
  177. X        Extract file name & info.
  178. X      */
  179. X      name=response;
  180. X      info=response;
  181. X      while ((*info != ' ') && *info)
  182. X        info++;
  183. X      *info='\0';
  184. X      node=(DirectoryNode *) malloc(sizeof(DirectoryNode));
  185. X      if (node == (DirectoryNode *) NULL)
  186. X        Error("unable to allocate memory",(char *) NULL);
  187. X      node->name=(char *) malloc((strlen(name)+1)*sizeof(char));
  188. X      node->info=(char *) malloc((strlen(info)+1)*sizeof(char));
  189. X      if ((node->name == (char *) NULL) || (node->info == (char *) NULL))
  190. X        Error("unable to allocate memory",(char *) NULL);
  191. X      (void) strcpy(node->name,name);
  192. X      (void) strcpy(node->info,info);
  193. X      node->next=(DirectoryNode *) NULL;
  194. X      if (exclude_expression)
  195. X        if (ExecuteRegularExpression(exclude_expression,node->name))
  196. X          {
  197. X            /*
  198. X              Free allocated memory for this node.
  199. X            */
  200. X            (void) free((char *) node->info);
  201. X            (void) free((char *) node->name);
  202. X            (void) free((char *) node);
  203. X            continue;
  204. X          }
  205. X      *last=node;
  206. X      last=(&node->next);
  207. X    }
  208. X    while (response=Wait());
  209. X  else
  210. X    {
  211. X      RegularExpression
  212. X        *access_expression;
  213. X
  214. X      access_expression=
  215. X        CompileRegularExpression("Permission denied|not found|cannot access");
  216. X      date_expression=
  217. X        CompileRegularExpression(" [0-9][0-9][0-9][0-9]|[0-9][0-9]:[0-9][0-9]");
  218. X      do
  219. X      {
  220. X        /*
  221. X           Link unix-style file into file list.
  222. X        */
  223. X        if ((status > 0) || (*response == '\0'))
  224. X          continue;
  225. X        while (*response == ' ')
  226. X          response++;
  227. X        p=response+strlen(response)-1;
  228. X        if ((*response == '-') || (*response == 'F'))
  229. X          {
  230. X            if (ExecuteRegularExpression(access_expression,response))
  231. X              continue;
  232. X            /*
  233. X              Extract file info & name.
  234. X            */
  235. X            while (p-- > (response+5))
  236. X              if (*p == ' ')
  237. X                if (!ExecuteRegularExpression(date_expression,p-5))
  238. X                  *p='_';
  239. X                else
  240. X                  break;
  241. X            *p++='\0';
  242. X            while (*p == ' ')
  243. X              p++;
  244. X            name=p;
  245. X            info=response;
  246. X            node=(DirectoryNode *) malloc(sizeof(DirectoryNode));
  247. X            if (node == (DirectoryNode *) NULL)
  248. X              Error("unable to allocate memory",(char *) NULL);
  249. X            node->name=(char *) malloc(strlen(directory)+strlen(name)+1);
  250. X            node->info=(char *) malloc(strlen(info)+1);
  251. X            if ((node->name == (char *) NULL) || (node->info == (char *) NULL))
  252. X              Error("unable to allocate memory",(char *) NULL);
  253. X            (void) strcpy(node->name,directory);
  254. X            (void) strcat(node->name,name);
  255. X            (void) strcpy(node->info,info);
  256. X            node->next=(DirectoryNode *) NULL;
  257. X            if (exclude_expression)
  258. X              if (ExecuteRegularExpression(exclude_expression,node->name))
  259. X                {
  260. X                  /*
  261. X                    Free allocated memory for this node.
  262. X                  */
  263. X                  (void) free((char *) node->info);
  264. X                  (void) free((char *) node->name);
  265. X                  (void) free((char *) node);
  266. X                  continue;
  267. X                }
  268. X            *last=node;
  269. X            last=(&node->next);
  270. X          }
  271. X        else
  272. X          if (*p == ':')
  273. X            {
  274. X              /*
  275. X                File is a directory.
  276. X              */
  277. X              do { p--; } while (*p == ' ');
  278. X              *(++p)='\0';
  279. X              (void) strcpy(directory,response);
  280. X              (void) strcat(directory,"/");
  281. X            }
  282. X      }
  283. X      while (response=Wait());
  284. X      (void) free((char *) access_expression);
  285. X      (void) free((char *) date_expression);
  286. X    }
  287. X  /*
  288. X    Traverse the file list and act on a filename if it matches the regular
  289. X    expression.
  290. X  */
  291. X  status=(-1);
  292. X  node=root;
  293. X  while (node)
  294. X  {
  295. X    if (directory_expression)
  296. X      if (ExecuteRegularExpression(directory_expression,node->name))
  297. X        (void) DirectoryRequest(node->info,node->name);
  298. X    if (print_expression)
  299. X      if (ExecuteRegularExpression(print_expression,node->name))
  300. X        (void) PrintRequest(node->name,verbose);
  301. X    if (retrieve_expression)
  302. X      if (ExecuteRegularExpression(retrieve_expression,node->name))
  303. X        (void) RetrieveRequest(node->name,verbose);
  304. X    /*
  305. X      Free allocated memory for this node.
  306. X    */
  307. X    (void) free((char *) node->info);
  308. X    (void) free((char *) node->name);
  309. X    next=node->next;
  310. X    (void) free((char *) node);
  311. X    node=next;
  312. X  }
  313. X  if (status < 0)
  314. X    Warning("no files matched your expression",(char *) NULL);
  315. }
  316. X
  317. /*
  318. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  319. %                                                                             %
  320. %                                                                             %
  321. %                                                                             %
  322. %   R e t r i e v e R e q u e s t                                             %
  323. %                                                                             %
  324. %                                                                             %
  325. %                                                                             %
  326. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  327. %
  328. %  Function RetrieveRequest retrieves a file from the remote FTP server.
  329. %
  330. %  The format of the RetrieveRequest routine is:
  331. %
  332. %    RetrieveRequest(filename,verbose)
  333. %
  334. %  A description of each parameter follows:
  335. %
  336. %    o filename:  Specifies a pointer to a character array that contains
  337. %      the name of the file to retrieve.
  338. %
  339. %    o verbose: An unsigned integer.  A value other than zero dhows all
  340. %      responses from the remote server.
  341. %
  342. %
  343. */
  344. static void RetrieveRequest(filename,verbose)
  345. char
  346. X  *filename;
  347. X
  348. unsigned int
  349. X  verbose;
  350. {
  351. X  char
  352. X    command[2048],
  353. X    *response;
  354. X
  355. X  /*
  356. X    get remote-file
  357. X  */
  358. X  (void) MakeDirectory(filename);
  359. X  (void) sprintf(command,"get %s\r",filename);
  360. X  (void) write(master,command,strlen(command));
  361. X  while (response=Wait())
  362. X    if (status == 0)
  363. X      (void) fprintf(stdout,"%s\n",response);
  364. X    else
  365. X      if ((status == 5) || verbose)
  366. X        (void) fprintf(stderr,"%s\n",response);
  367. }
  368. X
  369. /*
  370. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  371. %                                                                             %
  372. %                                                                             %
  373. %                                                                             %
  374. %   S i g n a l C h i l d                                                     %
  375. %                                                                             %
  376. %                                                                             %
  377. %                                                                             %
  378. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  379. %
  380. %  Function SignalChild is called if the status of the child process changes.
  381. %
  382. %  The format of the SignalChild routine is:
  383. %
  384. %    SignalChild()
  385. %
  386. %
  387. */
  388. static void SignalChild()
  389. {
  390. X  char
  391. X    message[2048];
  392. X
  393. X  int
  394. X    process_status;
  395. X
  396. X  while (waitpid((pid_t) NULL,&process_status,WNOHANG) > 0);
  397. X  (void) sprintf(message,"child died, status %x",process_status);
  398. X  Error(message,(char *) NULL);
  399. }
  400. X
  401. /*
  402. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  403. %                                                                             %
  404. %                                                                             %
  405. %                                                                             %
  406. %   U s a g e                                                                 %
  407. %                                                                             %
  408. %                                                                             %
  409. %                                                                             %
  410. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  411. %
  412. %  Procedure Usage displays the program usage;
  413. %
  414. %  The format of the Usage routine is:
  415. %
  416. %      Usage()
  417. %
  418. %
  419. */
  420. static void Usage()
  421. {
  422. X  char
  423. X    **p;
  424. X
  425. X  static char
  426. X    *options[]=
  427. X    {
  428. X      "-binary                retrieve files as binary",
  429. X      "-exclude expression    exclude files that match the expression",
  430. X      "-directory expression  list file names that match the expression",
  431. X      "-ident password        specifies password",
  432. X      "-port number           port number of FTP server",
  433. X      "-print expression      print files that match the expression",
  434. X      "-prune                 do not recursively search for files",
  435. X      "-retrieve expression   retrieve files that match the expression",
  436. X      "-send expression       send files that match the expression",
  437. X      "-timeout seconds       specifies maximum seconds of XTP session",
  438. X      "-user name             identify yourself to the remote FTP server",
  439. X      "-verbose               show all responses from the remote server",
  440. X      NULL
  441. X    };
  442. X  (void) fprintf(stderr,
  443. X    "Usage: %s [-options ...] <host/ip address> [ <home directory> ]\n",
  444. X    application_name);
  445. X  (void) fprintf(stderr,"\nWhere options include:\n");
  446. X  for (p=options; *p; p++)
  447. X    (void) fprintf(stderr,"  %s\n",*p);
  448. X  exit(1);
  449. }
  450. X
  451. /*
  452. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  453. %                                                                             %
  454. %                                                                             %
  455. %                                                                             %
  456. %   W a i t                                                                   %
  457. %                                                                             %
  458. %                                                                             %
  459. %                                                                             %
  460. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  461. %
  462. %  Function Wait reads a line of output from the remote FTP server.
  463. %
  464. %  The format of the Wait() routine is:
  465. %
  466. %    response=Wait()
  467. %
  468. %  A description of each parameter follows:
  469. %
  470. %    o response:  Function Wait returns this pointer to the output obtained
  471. %      from the remote FTP server.
  472. %
  473. %
  474. */
  475. static char *Wait()
  476. {
  477. X  register char
  478. X    *p;
  479. X
  480. X  static char
  481. X    buffer[1024],
  482. X    *q;
  483. X
  484. X  static char
  485. X    line[1024];
  486. X
  487. X  static int
  488. X    count=0;
  489. X
  490. X  status=0;
  491. X  p=line;
  492. X  do
  493. X  {
  494. X    if (count <= 0)
  495. X      {
  496. X        /*
  497. X          The buffer is empty;  read output from the remote FTP server.
  498. X        */
  499. X        count=read(master,buffer,sizeof(buffer));
  500. X        q=buffer;
  501. X        if (count <= 0)
  502. X          {
  503. X            if (p == line)
  504. X              return((char *) NULL);
  505. X            break;
  506. X          }
  507. X      }
  508. X    count--;
  509. X    *p=(*q++);
  510. X    if (*p == '\n')
  511. X      break;
  512. X    p++;
  513. X    if ((p-line) >= 5)
  514. X      if (!strncmp(p-5,"ftp> ",5))
  515. X        if (count == 0)
  516. X          return((char *) NULL);
  517. X  } while (p < (line+sizeof(line)));
  518. X  *p='\0';
  519. X  if (isdigit(*line))
  520. X    status=atoi(line)/100;
  521. X  return(line);
  522. }
  523. X
  524. /*
  525. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  526. %                                                                             %
  527. %                                                                             %
  528. %                                                                             %
  529. %   m a i n                                                                   %
  530. %                                                                             %
  531. %                                                                             %
  532. %                                                                             %
  533. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  534. %
  535. %
  536. */
  537. main(argc,argv)
  538. int
  539. X  argc;
  540. X
  541. register char
  542. X  **argv;
  543. {
  544. #include <pwd.h>
  545. X
  546. X  char
  547. X    command[2048],
  548. X    *home_directory,
  549. X    *host_info,
  550. X    *host_name,
  551. X    *ident,
  552. X    *port,
  553. X    *send_expression,
  554. X    *user;
  555. X
  556. X  int
  557. X    binary,
  558. X    child,
  559. X    process_status;
  560. X
  561. X  register char
  562. X    *p,
  563. X    *response;
  564. X
  565. X  struct sigaction
  566. X    action;
  567. X
  568. X  unsigned int
  569. X    prune,
  570. X    timeout,
  571. X    verbose;
  572. X
  573. X  /*
  574. X    Initialize program variables.
  575. X  */
  576. X  application_name=argv[0];
  577. X  binary=False;
  578. X  directory_expression=(RegularExpression *) NULL;
  579. X  exclude_expression=(RegularExpression *) NULL;
  580. X  ident=(char *) NULL;
  581. X  port=(char *) NULL;
  582. X  print_expression=(RegularExpression *) NULL;
  583. X  prune=False;
  584. X  retrieve_expression=(RegularExpression *) NULL;
  585. X  send_expression=(char *) NULL;
  586. X  timeout=0;
  587. X  user=(char *) NULL;
  588. X  verbose=False;
  589. X  /*
  590. X    Parse command line arguments.
  591. X  */
  592. X  for (p=(*argv++); *argv && (**argv == '-'); argv++)
  593. X    switch (argv[0][1])
  594. X    {
  595. X      case 'b':
  596. X      {
  597. X        binary=True;
  598. X        break;
  599. X      }
  600. X      case 'd':
  601. X      {
  602. X        directory_expression=CompileRegularExpression(*++argv);
  603. X        if (!directory_expression)
  604. X          exit(1);
  605. X        break;
  606. X      }
  607. X      case 'e':
  608. X      {
  609. X        exclude_expression=CompileRegularExpression(*++argv);
  610. X        if (!exclude_expression)
  611. X          exit(1);
  612. X        break;
  613. X      }
  614. X      case 'i':
  615. X      {
  616. X        ident=(*++argv);
  617. X        break;
  618. X      }
  619. X      case 'p':
  620. X      {
  621. X        if (strncmp("port",*argv+1,2) == 0)
  622. X          port=(*++argv);
  623. X        else
  624. X          if (strncmp("prune",*argv+1,3) == 0)
  625. X            prune=(**argv == '-');
  626. X          else
  627. X            {
  628. X              print_expression=CompileRegularExpression(*++argv);
  629. X              if (!print_expression)
  630. X                exit(1);
  631. X            }
  632. X        break;
  633. X      }
  634. X      case 'r':
  635. X      {
  636. X        retrieve_expression=CompileRegularExpression(*++argv);
  637. X        if (!retrieve_expression)
  638. X          exit(1);
  639. X        break;
  640. X      }
  641. X      case 's':
  642. X      {
  643. X        send_expression=(*++argv);
  644. X        break;
  645. X      }
  646. X      case 't':
  647. X      {
  648. X        timeout=atoi(*++argv);
  649. X        break;
  650. X      }
  651. X      case 'u':
  652. X      {
  653. X        user=(*++argv);
  654. X        break;
  655. X      }
  656. X      case 'v':
  657. X      {
  658. X        verbose=True;
  659. X        break;
  660. X      }
  661. X      default:
  662. X      {
  663. X        Error("unrecognized option",(char *) NULL);
  664. X        break;
  665. X      }
  666. X    }
  667. X  if ((argc < 2) || (*argv == (char *) NULL))
  668. X    Usage();
  669. X  host_name=argv[0];
  670. X  home_directory=argv[1];
  671. X  if ((directory_expression == (RegularExpression *) NULL) &&
  672. X      (print_expression == (RegularExpression *) NULL) &&
  673. X      (retrieve_expression == (RegularExpression *) NULL) &&
  674. X      (send_expression == (char *) NULL))
  675. X    directory_expression=CompileRegularExpression("");
  676. X  if ((ident == (char *) NULL) && (user == (char *) NULL))
  677. X    {
  678. X      static char
  679. X        name[2048];
  680. X
  681. X      struct passwd
  682. X        *user_info;
  683. X
  684. X      /*
  685. X        Identify user as user@host.domain.
  686. X      */
  687. X      user_info=getpwuid(geteuid());
  688. X      if (user_info == (struct passwd *) NULL)
  689. X        (void) strcpy(name,"anonymous");
  690. X      else
  691. X        (void) strcpy(name,user_info->pw_name);
  692. X      p=name+strlen(name);
  693. X      *p++='@';
  694. X      (void) gethostname(p,64);
  695. X      while (*p)
  696. X        p++;
  697. X      *p++='.';
  698. X      (void) getdomainname(p,64);
  699. X      user="anonymous";
  700. X      ident=name;
  701. X    }
  702. X  else
  703. X    if (ident == (char *) NULL)
  704. X      ident=(char *) GetPassword("Password: ");
  705. X    else
  706. X      if (user == (char *) NULL)
  707. X        user="anonymous";
  708. X  host_info=GetHostInfo(host_name);
  709. X  if (host_info == (char *) NULL)
  710. X    Error("unknown host",host_name);
  711. X  if (home_directory == (char *) NULL)
  712. X    (void) fprintf(stdout,"%s\n",host_info);
  713. X  else
  714. X    (void) fprintf(stdout,"%s %s\n",host_info,home_directory);
  715. X  (void) GetPseudoTerminal();
  716. X  /*
  717. X    Connect and logon to host.
  718. X  */
  719. X  action.sa_handler=SignalChild;
  720. X  (void) sigemptyset(&action.sa_mask);
  721. X  action.sa_flags=0;
  722. X  (void) sigaction(SIGCHLD,&action,(struct sigaction *) NULL);
  723. X  if (timeout > 0)
  724. X    (void) alarm(timeout/10);  /* enable login timer. */
  725. X  child=fork();
  726. X  if (child < 0)
  727. X    Error("unable to fork",(char *) NULL);
  728. X  if (child == 0)
  729. X    ExecuteFtp(host_name,port);
  730. X  while (response=Wait())
  731. X    if (verbose)
  732. X      (void) fprintf(stderr,"%s\n",response);
  733. X  (void) sprintf(command,"user %s %s\r",user,ident);
  734. X  (void) write(master,command,strlen(command));
  735. X  while (response=Wait())
  736. X  {
  737. X    if (verbose)
  738. X      (void) fprintf(stderr,"%s\n",response);
  739. X    if (status == 5)
  740. X      Error(response,user);
  741. X  }
  742. X  if (timeout > 0)
  743. X    (void) alarm(timeout);  /* enable session timer. */
  744. X  if (home_directory != (char *) NULL)
  745. X    {
  746. X      /*
  747. X        Change remote working directory.
  748. X      */
  749. X      (void) sprintf(command,"cd %s\r",home_directory);
  750. X      (void) write(master,command,strlen(command));
  751. X      while (response=Wait())
  752. X      {
  753. X        if (verbose)
  754. X          (void) fprintf(stderr,"%s\n",response);
  755. X        if (status == 5)
  756. X          Error("no such directory",home_directory);
  757. X      }
  758. X      (void) strcpy(command,"pwd\r");
  759. X      (void) write(master,command,strlen(command));
  760. X      while (response=Wait())
  761. X        if (verbose)
  762. X          (void) fprintf(stderr,"%s\n",response);
  763. X    }
  764. X  if (binary)
  765. X    {
  766. X      /*
  767. X        Set file transfer type.
  768. X      */
  769. X      (void) strcpy(command,"binary\r");
  770. X      (void) write(master,command,strlen(command));
  771. X      while (response=Wait())
  772. X        if (verbose)
  773. X          (void) fprintf(stderr,"%s\n",response);
  774. X      (void) strcpy(command,"type\r");
  775. X      (void) write(master,command,strlen(command));
  776. X      while (response=Wait())
  777. X        if (verbose)
  778. X          (void) fprintf(stderr,"%s\n",response);
  779. X    }
  780. X  if (retrieve_expression != (RegularExpression *) NULL)
  781. X    {
  782. X      /*
  783. X        Ensure retrieved files are unique.
  784. X      */
  785. X      (void) strcpy(command,"runique\r");
  786. X      (void) write(master,command,strlen(command));
  787. X      while (response=Wait())
  788. X        if (verbose)
  789. X          (void) fprintf(stderr,"%s\n",response);
  790. X    }
  791. X  if (send_expression == (char *) NULL)
  792. X    ProcessRequest(prune,verbose);
  793. X  else
  794. X    {
  795. X      /*
  796. X        Process send request.
  797. X      */
  798. X      (void) strcpy(command,"glob on\r");
  799. X      (void) write(master,command,strlen(command));
  800. X      while (response=Wait())
  801. X        if (verbose)
  802. X          (void) fprintf(stderr,"%s\n",response);
  803. X      (void) sprintf(command,"mput %s\r",send_expression);
  804. X      (void) write(master,command,strlen(command));
  805. X      while (response=Wait())
  806. X        if ((status == 5) || verbose)
  807. X          (void) fprintf(stderr,"%s\n",response);
  808. X    }
  809. X  (void) strcpy(command,"quit\r");
  810. X  (void) write(master,command,strlen(command));
  811. X  /*
  812. X    Wait for child to finish.
  813. X  */
  814. X  action.sa_handler=SIG_DFL;
  815. X  (void) sigemptyset(&action.sa_mask);
  816. X  action.sa_flags=0;
  817. X  (void) sigaction(SIGCHLD,&action,(struct sigaction *) NULL);
  818. X  (void) waitpid(child,&process_status,WNOHANG);
  819. X  (void) close(master);
  820. X  (void) free((char *) directory_expression);
  821. X  (void) free((char *) exclude_expression);
  822. X  (void) free((char *) print_expression);
  823. X  (void) free((char *) retrieve_expression);
  824. X  return(status < 0);
  825. }
  826. SHAR_EOF
  827. echo 'File ImageMagick/xtp/xtp.c is complete' &&
  828. chmod 0644 ImageMagick/xtp/xtp.c ||
  829. echo 'restore of ImageMagick/xtp/xtp.c failed'
  830. Wc_c="`wc -c < 'ImageMagick/xtp/xtp.c'`"
  831. test 41314 -eq "$Wc_c" ||
  832.     echo 'ImageMagick/xtp/xtp.c: original size 41314, current size' "$Wc_c"
  833. rm -f _shar_wnt_.tmp
  834. fi
  835. # ============= ImageMagick/xtp/xtp.man ==============
  836. if test -f 'ImageMagick/xtp/xtp.man' -a X"$1" != X"-c"; then
  837.     echo 'x - skipping ImageMagick/xtp/xtp.man (File already exists)'
  838.     rm -f _shar_wnt_.tmp
  839. else
  840. > _shar_wnt_.tmp
  841. echo 'x - extracting ImageMagick/xtp/xtp.man (Text)'
  842. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/xtp/xtp.man' &&
  843. .ad l
  844. .nh
  845. .TH XTP 1 "10 October 1992"
  846. .SH NAME
  847. xtp - file transfer program
  848. .SH SYNOPSIS
  849. .B "xtp"
  850. [ \fI-options\fP ... ] \fI<host/ip address>\fP [ \fI<home directory>\fP ]
  851. .SH DESCRIPTION
  852. .PP
  853. .I Xtp
  854. is a utility for retrieving, listing, or printing files from a remote
  855. network site, or sending files to a remote network site.
  856. .I Xtp
  857. performs most of the same functions as the \fIftp\fP program, but does
  858. not require any interactive commands.  You simply specify the file transfer
  859. task on the command line and \fIxtp\fP performs the task automatically.
  860. .SH EXAMPLES
  861. .PP
  862. To retrieve file display.tar.Z from host wizard.dupont.com, use:
  863. .PP
  864. X     xtp -binary -retrieve display.tar.Z wizard.dupont.com
  865. .PP
  866. To retrieve all the files from directory \fIpublic/documents\fP from host
  867. wizard.dupont.com, use:
  868. .PP
  869. X     xtp -binary -retrieve documents/ wizard.dupont.com public
  870. .PP
  871. .SH OPTIONS
  872. .TP
  873. .B "-binary"
  874. retrieve files as binary.
  875. .TP
  876. .B "-exclude \fIexpression\fP"
  877. exclude files that match the \fIregular expression\fP.
  878. .TP
  879. .B "-directory \fIexpression\fP"
  880. list the names of files and their attributes that match the
  881. \fIregular expression\fP.
  882. .TP
  883. .B "-ident \fIpassword\fP"
  884. specifies password.
  885. .TP
  886. .B "-port \fInumber\fP"
  887. If no port number is specified, xtp attempts to contact a FTP server
  888. at the default port.  Otherwise, the specfied port number is used.
  889. .TP
  890. .B "-print \fIexpression\fP"
  891. print files that match the \fIregular expression\fP.
  892. .TP
  893. .B "-prune"
  894. do not recursively search for files.
  895. .TP
  896. .B "-retrieve \fIexpression\fP"
  897. retrieve files that match the \fIregular expression\fP.
  898. X
  899. Retrieved files are stored on your local host directory as the full
  900. name of the retrieved file.  For example, if the retrieved file is
  901. named \fIdocuments/xtp.man\fP on the remote FTP server, it will appear
  902. in your home directory as \fIdocuments/xtp.man\fP.
  903. .TP
  904. .B "-send \fIexpression\fP"
  905. send files that match the \fIregular expression\fP.
  906. .TP
  907. .B "-timeout \fIseconds\fP"
  908. specifies the maximum seconds to complete your remote FTP server request.
  909. If this time expires, the program terminates.  The program also terminates if
  910. one tenth of this value is exceeded while logging onto the remote FTP
  911. server.
  912. .TP
  913. .B "-user \fIname\fP"
  914. identify yourself to the remote FTP server.
  915. .PP
  916. If \fB-user\fP is specified but not \fB-ident\fP, the password is obtained
  917. from you interactively.
  918. .TP
  919. .B "-verbose"
  920. show all responses from the remote server.
  921. .PP
  922. If neither \fB-print\fP, \fB-retrieve\fP, or \fB-send\fP are specified
  923. on the command line, a directory of files is listed for the remote
  924. network host.
  925. .PP
  926. \fIxtp\fP recursively descends the directory hierarchy from the home
  927. directory. Some remote hosts may have thousands of files causing a
  928. significant delay satisfying your request.  This can be wasteful if the
  929. files you are interested in reside in a known directory.  You can
  930. reduce the searching required by specifying \fI<home directory>\fP on
  931. the command line.  This limits the filename search to the specified
  932. directory and any of its subdirectories.  Alternatively, \fB-prune\fP
  933. restricts the search to the home directory only.
  934. .PP
  935. If only the program name is specified on the command line, the program command
  936. syntax and options are listed.
  937. .SH REGULAR EXPRESSIONS
  938. A \fIregular expression\fP is zero or more branches, separated by
  939. \fB|\fP.  It matches anything that matches one of the branches.
  940. .PP
  941. A branch is zero or more pieces, concatenated.  It matches a match for
  942. the first, followed by a match for the second, etc.
  943. .PP
  944. A piece is an atom possibly followed by \fB*\fP, \fB+\fP, or \fB?\fP.
  945. An atom followed by \fB*\fP matches a sequence of 0 or more matches of
  946. the atom.  An atom followed by \fB+\fP matches a sequence of 1 or more
  947. matches of the atom.  An atom followed by \fB?\fP matches a match of
  948. the atom, or the null pattern.
  949. .PP
  950. An atom is a \fIregular expression\fP in parentheses (matching a match
  951. for the \fIregular expression\fP), a range (see below), \fB.\fP
  952. (matching any single character), \fB^\fP (matching the null pattern at
  953. the beginning of the input pattern), \fB$\fP (matching the null pattern
  954. at the end of the input pattern), a \fB\'\fP followed by a single
  955. character (matching that character), or a single character with no
  956. other significance (matching that character).
  957. .PP
  958. A range is a sequence of characters enclosed in \fB[]\fP.  It normally
  959. matches any single character from the sequence.  If the sequence begins
  960. with \fB^\fP, it matches any single character not from the rest of the
  961. sequence.  If two characters in the sequence are separated by \fB-\fP,
  962. this is shorthand for the full list of ASCII characters between them
  963. (e.g.  \fB[0-9]\fP matches any decimal digit). To include a literal
  964. \fB]\fP in the sequence, make it the first character (following a
  965. possible \fB^\fP).  To include a literal \fB-\fP, make it the first or
  966. last character.
  967. .SH SEE ALSO
  968. ftp(1C)
  969. .SH COPYRIGHT
  970. Copyright 1990 E. I. Dupont de Nemours & Company
  971. .PP
  972. Permission to use, copy, modify, distribute, and sell this software and
  973. its documentation for any purpose is hereby granted without fee,
  974. provided that the above copyright notice appear in all copies and that
  975. both that copyright notice and this permission notice appear in
  976. supporting documentation, and that the name of E. I. Dupont de Nemours
  977. & Company not be used in advertising or publicity pertaining to
  978. distribution of the software without specific, written prior
  979. permission.  E. I. Dupont de Nemours & Company makes no representations
  980. about the suitability of this software for any purpose.  It is provided
  981. "as is" without express or implied warranty.
  982. .PP
  983. E. I. Dupont de Nemours & Company disclaims all warranties with regard
  984. to this software, including all implied warranties of merchantability
  985. and fitness, in no event shall E. I. Dupont de Nemours & Company be
  986. liable for any special, indirect or consequential damages or any
  987. damages whatsoever resulting from loss of use, data or profits, whether
  988. in an action of contract, negligence or other tortious action, arising
  989. out of or in connection with the use or performance of this software.
  990. .SH ACKNOWLEDGEMENTS
  991. Steve Singles, University of Delaware, for the initial implementation of
  992. this program.
  993. .PP
  994. Henry Spencer, University of Toronto, for the implementation of the
  995. \fIregular expression\fP interpreter and the text in \fBREGULAR
  996. EXPRESSIONS\fP.
  997. .SH AUTHOR
  998. John Cristy, E.I. DuPont De Nemours & Company Incorporated
  999. X
  1000. X
  1001. SHAR_EOF
  1002. chmod 0644 ImageMagick/xtp/xtp.man ||
  1003. echo 'restore of ImageMagick/xtp/xtp.man failed'
  1004. Wc_c="`wc -c < 'ImageMagick/xtp/xtp.man'`"
  1005. test 6431 -eq "$Wc_c" ||
  1006.     echo 'ImageMagick/xtp/xtp.man: original size 6431, current size' "$Wc_c"
  1007. rm -f _shar_wnt_.tmp
  1008. fi
  1009. # ============= ImageMagick/xtp/get ==============
  1010. if test -f 'ImageMagick/xtp/get' -a X"$1" != X"-c"; then
  1011.     echo 'x - skipping ImageMagick/xtp/get (File already exists)'
  1012.     rm -f _shar_wnt_.tmp
  1013. else
  1014. > _shar_wnt_.tmp
  1015. echo 'x - extracting ImageMagick/xtp/get (Text)'
  1016. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/xtp/get' &&
  1017. #!/usr/bin/perl
  1018. #
  1019. # Retrieve files from remote host using standard 'host: filename' string:
  1020. #
  1021. #   get export.lcs.mit.edu: contrib/ImageMagick.tar.Z
  1022. #
  1023. $host=shift || die "Usage: get host/ip-address file\n";
  1024. $file=shift || die "Usage: get host/ip-address file\n";
  1025. $host=~s/:$//;
  1026. $directory=`dirname $file`;
  1027. chop($directory);
  1028. $file=`basename $file`;
  1029. chop($file);
  1030. printf("Getting %s in directory %s from host %s...\n",$file,$directory,$host);
  1031. $pid=fork;
  1032. if ($pid == 0)
  1033. X  {
  1034. X    exec("xtp -r $file -b $host $directory");
  1035. X    exit(0);
  1036. X  }
  1037. exit(0);
  1038. SHAR_EOF
  1039. chmod 0644 ImageMagick/xtp/get ||
  1040. echo 'restore of ImageMagick/xtp/get failed'
  1041. Wc_c="`wc -c < 'ImageMagick/xtp/get'`"
  1042. test 541 -eq "$Wc_c" ||
  1043.     echo 'ImageMagick/xtp/get: original size 541, current size' "$Wc_c"
  1044. rm -f _shar_wnt_.tmp
  1045. fi
  1046. # ============= ImageMagick/xtp/network.c ==============
  1047. if test -f 'ImageMagick/xtp/network.c' -a X"$1" != X"-c"; then
  1048.     echo 'x - skipping ImageMagick/xtp/network.c (File already exists)'
  1049.     rm -f _shar_wnt_.tmp
  1050. else
  1051. > _shar_wnt_.tmp
  1052. echo 'x - extracting ImageMagick/xtp/network.c (Text)'
  1053. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/xtp/network.c' &&
  1054. /*
  1055. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1056. %                                                                             %
  1057. %                                                                             %
  1058. %                                                                             %
  1059. %             N   N  EEEEE  TTTTT  W   W   OOO   RRRR   K   K                 %
  1060. %             NN  N  E        T    W   W  O   O  R   R  K  K                  %
  1061. %             N N N  EEE      T    W W W  O   O  RRRR   KKK                   %
  1062. %             N  NN  E        T    WW WW  O   O  R R    K  K                  %
  1063. %             N   N  EEEEE    T    W   W   OOO   R  R   K   K                 %
  1064. %                                                                             %
  1065. %                                                                             %
  1066. %                          Network Routines.                                  %
  1067. %                                                                             %
  1068. %                                                                             %
  1069. %                           Software Design                                   %
  1070. %                             John Cristy                                     %
  1071. %                             October 1992                                    %
  1072. %                                                                             %
  1073. %                                                                             %
  1074. %  Copyright 1992 E. I. Dupont de Nemours & Company                           %
  1075. %                                                                             %
  1076. %  Permission to use, copy, modify, distribute, and sell this software and    %
  1077. %  its documentation for any purpose is hereby granted without fee,           %
  1078. %  provided that the above Copyright notice appear in all copies and that     %
  1079. %  both that Copyright notice and this permission notice appear in            %
  1080. %  supporting documentation, and that the name of E. I. Dupont de Nemours     %
  1081. %  & Company not be used in advertising or publicity pertaining to            %
  1082. %  distribution of the software without specific, written prior               %
  1083. %  permission.  E. I. Dupont de Nemours & Company makes no representations    %
  1084. %  about the suitability of this software for any purpose.  It is provided    %
  1085. %  "as is" without express or implied warranty.                               %
  1086. %                                                                             %
  1087. %  E. I. Dupont de Nemours & Company disclaims all warranties with regard     %
  1088. %  to this software, including all implied warranties of merchantability      %
  1089. %  and fitness, in no event shall E. I. Dupont de Nemours & Company be        %
  1090. %  liable for any special, indirect or consequential damages or any           %
  1091. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  1092. %  in an action of contract, negligence or other tortious action, arising     %
  1093. %  out of or in connection with the use or performance of this software.      %
  1094. %                                                                             %
  1095. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1096. %
  1097. %
  1098. */
  1099. X
  1100. #include "xtp.h"
  1101. #include "regular.h"
  1102. #include <unistd.h>
  1103. X
  1104. /*
  1105. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1106. %                                                                             %
  1107. %                                                                             %
  1108. %                                                                             %
  1109. %   G e t H o s t I n f o                                                     %
  1110. %                                                                             %
  1111. %                                                                             %
  1112. %                                                                             %
  1113. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1114. %
  1115. %  Function GetHostInfo accepts a host name or address, verifies it is valid,
  1116. %  and returns both the host name and address from the network host entry.
  1117. %
  1118. %  The format of the GetHostInfo routine is:
  1119. %
  1120. %    info=GetHostInfo(name)
  1121. %
  1122. %  A description of each parameter follows:
  1123. %
  1124. %    o info:  Function GetHostInfo returns a pointer to the host name and
  1125. %      IP address.  A null pointer is returned if there the host cannot be
  1126. %      located.
  1127. %
  1128. %    o name:  Specifies a pointer to a character array that contains either
  1129. %      a name of a host or an IP address.
  1130. %
  1131. %
  1132. */
  1133. char *GetHostInfo(name)
  1134. char
  1135. X  *name;
  1136. {
  1137. #include <sys/socket.h>
  1138. #include <netinet/in.h>
  1139. #include <netdb.h>
  1140. #include <arpa/inet.h>
  1141. X
  1142. X  char
  1143. X    info[2048],
  1144. X    *p;
  1145. X
  1146. X  struct in_addr
  1147. X    in;
  1148. X
  1149. X  struct hostent
  1150. X    *hp;
  1151. X
  1152. X  /*
  1153. X    Get host name and address.
  1154. X  */
  1155. X  if (isascii(*name) && isdigit(*name))
  1156. X    in.s_addr=inet_addr(name);
  1157. X  else
  1158. X    {
  1159. X      in.s_addr=(unsigned long) -1;
  1160. X      hp=gethostbyname(name);
  1161. X      if (hp != (struct hostent *) NULL)
  1162. X        in.s_addr=(*(int *) hp->h_addr);
  1163. X    }
  1164. X  hp=gethostbyaddr((char *) &in.s_addr,sizeof(in.s_addr),AF_INET);
  1165. X  if (hp == (struct hostent *) NULL)
  1166. X    {
  1167. X      hp=gethostbyname(name);
  1168. X      if (hp == (struct hostent *) NULL)
  1169. X        return((char *) NULL);
  1170. X    }
  1171. X  /*
  1172. X    Convert hostname to lower-case characters.
  1173. X  */
  1174. X  p=hp->h_name;
  1175. X  while (*p)
  1176. X  {
  1177. X    if (isupper(*p))
  1178. X      *p=tolower(*p);
  1179. X    p++;
  1180. X  }
  1181. X  (void) sprintf(info,"%s [%s]: \0",hp->h_name,inet_ntoa(in));
  1182. X  return(info);
  1183. }
  1184. SHAR_EOF
  1185. chmod 0644 ImageMagick/xtp/network.c ||
  1186. echo 'restore of ImageMagick/xtp/network.c failed'
  1187. Wc_c="`wc -c < 'ImageMagick/xtp/network.c'`"
  1188. test 5587 -eq "$Wc_c" ||
  1189.     echo 'ImageMagick/xtp/network.c: original size 5587, current size' "$Wc_c"
  1190. rm -f _shar_wnt_.tmp
  1191. fi
  1192. # ============= ImageMagick/image.c ==============
  1193. if test -f 'ImageMagick/image.c' -a X"$1" != X"-c"; then
  1194.     echo 'x - skipping ImageMagick/image.c (File already exists)'
  1195.     rm -f _shar_wnt_.tmp
  1196. else
  1197. > _shar_wnt_.tmp
  1198. echo 'x - extracting ImageMagick/image.c (Text)'
  1199. sed 's/^X//' << 'SHAR_EOF' > 'ImageMagick/image.c' &&
  1200. /*
  1201. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1202. %                                                                             %
  1203. %                                                                             %
  1204. %                                                                             %
  1205. %                     IIIII  M   M   AAA   GGGG  EEEEE                        %
  1206. %                       I    MM MM  A   A G      E                            %
  1207. %                       I    M M M  AAAAA G  GG  EEE                          %
  1208. %                       I    M   M  A   A G   G  E                            %
  1209. %                     IIIII  M   M  A   A  GGGG  EEEEE                        %
  1210. %                                                                             %
  1211. %                                                                             %
  1212. %                    Utiltity Image Routines for Display                      %
  1213. %                                                                             %
  1214. %                                                                             %
  1215. %                                                                             %
  1216. %                           Software Design                                   %
  1217. %                             John Cristy                                     %
  1218. %                              July 1992                                      %
  1219. %                                                                             %
  1220. %                                                                             %
  1221. %  Copyright 1992 E. I. du Pont de Nemours & Company                          %
  1222. %                                                                             %
  1223. %  Permission to use, copy, modify, distribute, and sell this software and    %
  1224. %  its documentation for any purpose is hereby granted without fee,           %
  1225. %  provided that the above Copyright notice appear in all copies and that     %
  1226. %  both that Copyright notice and this permission notice appear in            %
  1227. %  supporting documentation, and that the name of E. I. du Pont de Nemours    %
  1228. %  & Company not be used in advertising or publicity pertaining to            %
  1229. %  distribution of the software without specific, written prior               %
  1230. %  permission.  E. I. du Pont de Nemours & Company makes no representations   %
  1231. %  about the suitability of this software for any purpose.  It is provided    %
  1232. %  "as is" without express or implied warranty.                               %
  1233. %                                                                             %
  1234. %  E. I. du Pont de Nemours & Company disclaims all warranties with regard    %
  1235. %  to this software, including all implied warranties of merchantability      %
  1236. %  and fitness, in no event shall E. I. du Pont de Nemours & Company be       %
  1237. %  liable for any special, indirect or consequential damages or any           %
  1238. %  damages whatsoever resulting from loss of use, data or profits, whether    %
  1239. %  in an action of contract, negligence or other tortious action, arising     %
  1240. %  out of or in connection with the use or performance of this software.      %
  1241. %                                                                             %
  1242. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1243. %
  1244. %
  1245. %
  1246. */
  1247. X
  1248. /*
  1249. X  Include declarations.
  1250. */
  1251. #include "display.h"
  1252. #include "image.h"
  1253. #include "alien.h"
  1254. #include "X.h"
  1255. #include "compress.h"
  1256. X
  1257. /*
  1258. X  External declarations.
  1259. */
  1260. extern char
  1261. X  *application_name;
  1262. X
  1263. /*
  1264. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1265. %                                                                             %
  1266. %                                                                             %
  1267. %                                                                             %
  1268. %   A l l o c a t e I m a g e                                                 %
  1269. %                                                                             %
  1270. %                                                                             %
  1271. %                                                                             %
  1272. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1273. %
  1274. %  Function AllocateImage allocates an Image structure and initializes each
  1275. %  field to a default value.
  1276. %
  1277. %  The format of the AllocateImage routine is:
  1278. %
  1279. %      allocated_image=AllocateImage(magick)
  1280. %
  1281. %  A description of each parameter follows:
  1282. %
  1283. %    o allocated_image: Function AllocateImage returns a pointer to an image
  1284. %      structure initialized to default values.  A null image is returned if
  1285. %      there is a a memory shortage or if the image cannot be read.
  1286. %
  1287. %    o magick: Specifies the image format (i.e. MIFF, GIF, JPEG, etc.).
  1288. %
  1289. %
  1290. */
  1291. Image *AllocateImage(magick)
  1292. char
  1293. X  *magick;
  1294. {
  1295. X  Image
  1296. X    *allocated_image;
  1297. X
  1298. X  /*
  1299. X    Allocate image structure.
  1300. X  */
  1301. X  allocated_image=(Image *) malloc(sizeof(Image));
  1302. X  if (allocated_image == (Image *) NULL)
  1303. X    {
  1304. X      Warning("unable to allocate image","memory allocation error");
  1305. X      return((Image *) NULL);
  1306. X    }
  1307. X  /*
  1308. X    Initialize Image structure.
  1309. X  */
  1310. X  allocated_image->file=(FILE *) NULL;
  1311. X  *allocated_image->filename='\0';
  1312. X  if (strlen(magick) < sizeof(allocated_image->magick))
  1313. X    (void) strcpy(allocated_image->magick,magick);
  1314. X  allocated_image->comments=(char *) NULL;
  1315. X  allocated_image->label=(char *) NULL;
  1316. X  allocated_image->id=UndefinedId;
  1317. X  allocated_image->class=DirectClass;
  1318. X  allocated_image->alpha=False;
  1319. X  allocated_image->compression=RunlengthEncodedCompression;
  1320. X  allocated_image->columns=0;
  1321. X  allocated_image->rows=0;
  1322. X  allocated_image->colors=0;
  1323. X  allocated_image->scene=0;
  1324. X  allocated_image->quality=75;
  1325. X  allocated_image->montage=(char *) NULL;
  1326. X  allocated_image->directory=(char *) NULL;
  1327. X  allocated_image->colormap=(ColorPacket *) NULL;
  1328. X  allocated_image->signature=(char *) NULL;
  1329. X  allocated_image->pixels=(RunlengthPacket *) NULL;
  1330. X  allocated_image->packet=(RunlengthPacket *) NULL;
  1331. X  allocated_image->packets=0;
  1332. X  allocated_image->packet_size=0;
  1333. X  allocated_image->packed_pixels=(unsigned char *) NULL;
  1334. X  allocated_image->orphan=False;
  1335. X  allocated_image->last=(Image *) NULL;
  1336. X  allocated_image->next=(Image *) NULL;
  1337. X  return(allocated_image);
  1338. }
  1339. X
  1340. /*
  1341. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1342. %                                                                             %
  1343. %                                                                             %
  1344. %                                                                             %
  1345. %   B o r d e r I m a g e                                                     %
  1346. %                                                                             %
  1347. %                                                                             %
  1348. %                                                                             %
  1349. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1350. %
  1351. %  Function BorderImage takes an image and puts a border around it of a
  1352. %  particular color.  It allocates the memory necessary for the new Image
  1353. %  structure and returns a pointer to the new image.
  1354. %
  1355. %  The format of the BorderImage routine is:
  1356. %
  1357. %      bordered_image=BorderImage(image,border_width,border_height,
  1358. %        border_color)
  1359. %
  1360. %  A description of each parameter follows:
  1361. %
  1362. %    o bordered_image: Function BorderImage returns a pointer to the bordered
  1363. %      image.  A null image is returned if there is a a memory shortage.
  1364. %
  1365. %    o image: The address of a structure of type Image.
  1366. %
  1367. %    o border_width: An integer that specifies the number of pixels in width of
  1368. %      the bordered image.
  1369. %
  1370. %    o border_height: An integer that specifies the number of pixels in height
  1371. %      of the bordered image.
  1372. %
  1373. %    o border_color: A pointer to a ColorPacket which contains the red, green,
  1374. %      and blue components of the border color.
  1375. %
  1376. %
  1377. */
  1378. Image *BorderImage(image,border_width,border_height,border_color)
  1379. Image
  1380. X  *image;
  1381. X
  1382. unsigned int
  1383. X  border_width,
  1384. X  border_height;
  1385. X
  1386. ColorPacket
  1387. X  border_color;
  1388. {
  1389. X  Image
  1390. X    *bordered_image;
  1391. X
  1392. X  register int
  1393. X    i,
  1394. X    x,
  1395. X    y;
  1396. X
  1397. X  register RunlengthPacket
  1398. X    *p,
  1399. X    *q;
  1400. X
  1401. X  /*
  1402. X    Initialize bordered image attributes.
  1403. X  */
  1404. X  bordered_image=CopyImage(image,image->columns+border_width*2,
  1405. X    image->rows+border_height*2,False);
  1406. X  if (bordered_image == (Image *) NULL)
  1407. X    {
  1408. X      Warning("unable to border image","memory allocation failed");
  1409. X      return((Image *) NULL);
  1410. X    }
  1411. X  /*
  1412. X    Copy image and put border around it.
  1413. X  */
  1414. X  p=image->pixels;
  1415. X  q=bordered_image->pixels;
  1416. X  image->runlength=p->length+1;
  1417. X  for (i=0; i < (bordered_image->columns*border_height); i++)
  1418. X  {
  1419. X    q->red=border_color.red;
  1420. X    q->green=border_color.green;
  1421. X    q->blue=border_color.blue;
  1422. X    q->index=border_color.index;
  1423. X    q->length=0;
  1424. X    q++;
  1425. X  }
  1426. X  for (y=0; y < image->rows; y++)
  1427. X  {
  1428. X    /*
  1429. X      Initialize scanline with border color.
  1430. X    */
  1431. X    for (i=0; i < border_width; i++)
  1432. X    {
  1433. X      q->red=border_color.red;
  1434. X      q->green=border_color.green;
  1435. X      q->blue=border_color.blue;
  1436. X      q->index=border_color.index;
  1437. X      q->length=0;
  1438. X      q++;
  1439. X    }
  1440. X    /*
  1441. X      Transfer scanline.
  1442. X    */
  1443. X    for (x=0; x < image->columns; x++)
  1444. X    {
  1445. X      if (image->runlength > 0)
  1446. X        image->runlength--;
  1447. X      else
  1448. X        {
  1449. X          p++;
  1450. X          image->runlength=p->length;
  1451. X        }
  1452. X      q->red=p->red;
  1453. X      q->green=p->green;
  1454. X      q->blue=p->blue;
  1455. X      q->index=p->index;
  1456. X      q->length=0;
  1457. X      q++;
  1458. X    }
  1459. X    for (i=0; i < border_width; i++)
  1460. X    {
  1461. X      q->red=border_color.red;
  1462. X      q->green=border_color.green;
  1463. X      q->blue=border_color.blue;
  1464. X      q->index=border_color.index;
  1465. X      q->length=0;
  1466. X      q++;
  1467. X    }
  1468. X  }
  1469. X  for (i=0; i < (bordered_image->columns*border_height); i++)
  1470. X  {
  1471. X    q->red=border_color.red;
  1472. X    q->green=border_color.green;
  1473. X    q->blue=border_color.blue;
  1474. X    q->index=border_color.index;
  1475. X    q->length=0;
  1476. X    q++;
  1477. X  }
  1478. X  return(bordered_image);
  1479. }
  1480. X
  1481. /*
  1482. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1483. %                                                                             %
  1484. %                                                                             %
  1485. %                                                                             %
  1486. %   C l i p I m a g e                                                         %
  1487. %                                                                             %
  1488. %                                                                             %
  1489. %                                                                             %
  1490. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1491. %
  1492. %  Function ClipImage creates a new image that is a subregion of an existing
  1493. %  one.  It allocates the memory necessary for the new Image structure and
  1494. %  returns a pointer to the new image.  The pixels are copied from the source
  1495. %  image as defined by the region formed from x_offset, y_offset, width, and
  1496. %  height.
  1497. %
  1498. %  The format of the ClipImage routine is:
  1499. %
  1500. %      clipped_image=ClipImage(image,x_offset,y_offset,width,height)
  1501. %
  1502. %  A description of each parameter follows:
  1503. %
  1504. %    o clipped_image: Function ClipImage returns a pointer to the clipped
  1505. %      image.  A null image is returned if there is a a memory shortage or
  1506. %      if the image width or height is zero.
  1507. %
  1508. %    o image: The address of a structure of type Image.
  1509. %
  1510. %    o x_offset: An integer that specifies the column offset of the
  1511. %      clipped image.
  1512. %
  1513. %    o y_offset: An integer that specifies the row offset of the clipped
  1514. %      image.
  1515. %
  1516. %    o width: An integer that specifies the number of pixels in width of the
  1517. %      clipped image.
  1518. %
  1519. %    o height: An integer that specifies the number of pixels in height of the
  1520. %      clipped image.
  1521. %
  1522. %
  1523. */
  1524. Image *ClipImage(image,x_offset,y_offset,width,height)
  1525. Image
  1526. X  *image;
  1527. X
  1528. int
  1529. X  x_offset,
  1530. X  y_offset;
  1531. X
  1532. unsigned int
  1533. X  width,
  1534. X  height;
  1535. {
  1536. X  Image
  1537. X    *clipped_image;
  1538. X
  1539. X  register int
  1540. X    x,
  1541. X    y;
  1542. X
  1543. X  register RunlengthPacket
  1544. X    *p,
  1545. X    *q;
  1546. X
  1547. X  /*
  1548. X    Check clip geometry.
  1549. X  */
  1550. X  if ((width == 0) || (height == 0))
  1551. X    {
  1552. X      Warning("unable to clip image","image size is zero");
  1553. X      return((Image *) NULL);
  1554. X    }
  1555. X  if (((x_offset+(int) width) < 0) || ((y_offset+(int) height) < 0) ||
  1556. X      (x_offset > (int) image->columns) || (y_offset > (int) image->rows))
  1557. X    {
  1558. X      Warning("unable to clip image","geometry does not contain image");
  1559. X      return((Image *) NULL);
  1560. X    }
  1561. X  if ((x_offset+(int) width) > (int) image->columns)
  1562. X    width=(unsigned int) ((int) image->columns-x_offset);
  1563. X  if ((y_offset+(int) height) > (int) image->rows)
  1564. X    height=(unsigned int) ((int) image->rows-y_offset);
  1565. X  if (x_offset < 0)
  1566. X    {
  1567. X      width-=(unsigned int) (-x_offset);
  1568. X      x_offset=0;
  1569. X    }
  1570. X  if (y_offset < 0)
  1571. X    {
  1572. X      height-=(unsigned int) (-y_offset);
  1573. X      y_offset=0;
  1574. X    }
  1575. X  /*
  1576. X    Initialize clipped image attributes.
  1577. X  */
  1578. X  clipped_image=CopyImage(image,width,height,False);
  1579. X  if (clipped_image == (Image *) NULL)
  1580. X    {
  1581. X      Warning("unable to clip image","memory allocation failed");
  1582. X      return((Image *) NULL);
  1583. X    }
  1584. X  /*
  1585. X    Skip pixels up to the clipped image.
  1586. X  */
  1587. X  p=image->pixels;
  1588. X  image->runlength=p->length+1;
  1589. X  for (x=0; x < (y_offset*image->columns+x_offset); x++)
  1590. X    if (image->runlength > 0)
  1591. X      image->runlength--;
  1592. X    else
  1593. X      {
  1594. X        p++;
  1595. X        image->runlength=p->length;
  1596. X      }
  1597. X  /*
  1598. X    Extract clipped image.
  1599. X  */
  1600. X  q=clipped_image->pixels;
  1601. X  for (y=0; y < clipped_image->rows; y++)
  1602. X  {
  1603. X    /*
  1604. X      Transfer scanline.
  1605. X    */
  1606. X    for (x=0; x < clipped_image->columns; x++)
  1607. X    {
  1608. X      if (image->runlength > 0)
  1609. X        image->runlength--;
  1610. X      else
  1611. X        {
  1612. X          p++;
  1613. X          image->runlength=p->length;
  1614. X        }
  1615. X      q->red=p->red;
  1616. X      q->green=p->green;
  1617. X      q->blue=p->blue;
  1618. X      q->index=p->index;
  1619. X      q->length=0;
  1620. X      q++;
  1621. X    }
  1622. X    /*
  1623. X      Skip to next scanline.
  1624. X    */
  1625. X    for (x=0; x < (image->columns-clipped_image->columns); x++)
  1626. X      if (image->runlength > 0)
  1627. X        image->runlength--;
  1628. X      else
  1629. X        {
  1630. X          p++;
  1631. X          image->runlength=p->length;
  1632. X        }
  1633. X  }
  1634. X  return(clipped_image);
  1635. }
  1636. X
  1637. /*
  1638. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1639. %                                                                             %
  1640. %                                                                             %
  1641. %                                                                             %
  1642. %   C l o s e I m a g e                                                       %
  1643. %                                                                             %
  1644. %                                                                             %
  1645. %                                                                             %
  1646. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1647. %
  1648. %  Function CloseImage closes a file associated with the image.
  1649. %
  1650. %  The format of the CloseImage routine is:
  1651. %
  1652. %      CloseImage(image)
  1653. %
  1654. %  A description of each parameter follows:
  1655. %
  1656. %    o image: The address of a structure of type Image.
  1657. %
  1658. %
  1659. */
  1660. void CloseImage(image)
  1661. Image
  1662. X  *image;
  1663. {
  1664. X  /*
  1665. X    Close image file.
  1666. X  */
  1667. X  if (image->file != (FILE *) NULL)
  1668. X    if (((int) strlen(image->filename) < 3) ||
  1669. X        (strcmp(image->filename+strlen(image->filename)-2,".Z") != 0))
  1670. X      (void) fclose(image->file);
  1671. X    else
  1672. X      (void) pclose(image->file);
  1673. X  image->file=(FILE *) NULL;
  1674. }
  1675. X
  1676. /*
  1677. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1678. %                                                                             %
  1679. %                                                                             %
  1680. %                                                                             %
  1681. %   C o m p r e s s C o l o r m a p                                           %
  1682. %                                                                             %
  1683. %                                                                             %
  1684. %                                                                             %
  1685. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1686. %
  1687. %  Function CompressColormap compresses an image colormap removing any
  1688. %  unused color entries.
  1689. %
  1690. %  The format of the CompressColormap routine is:
  1691. %
  1692. %      CompressColormap(image)
  1693. %
  1694. %  A description of each parameter follows:
  1695. %
  1696. %    o image: The address of a structure of type Image.
  1697. %
  1698. %
  1699. */
  1700. void CompressColormap(image)
  1701. Image
  1702. X  *image;
  1703. {
  1704. X  ColorPacket
  1705. X    *colormap;
  1706. X
  1707. X  int
  1708. X    number_colors;
  1709. X
  1710. X  register int
  1711. X    i;
  1712. X
  1713. X  register RunlengthPacket
  1714. X    *p;
  1715. X
  1716. X  register unsigned short
  1717. X    index;
  1718. X
  1719. X  /*
  1720. X    Determine if colormap can be compressed.
  1721. X  */
  1722. X  if (image->class != PseudoClass)
  1723. X    return;
  1724. X  number_colors=image->colors;
  1725. X  for (i=0; i < image->colors; i++)
  1726. X    image->colormap[i].flags=False;
  1727. X  image->colors=0;
  1728. X  p=image->pixels;
  1729. X  for (i=0; i < image->packets; i++)
  1730. X  {
  1731. X    if (!image->colormap[p->index].flags)
  1732. X      {
  1733. X        image->colormap[p->index].index=image->colors;
  1734. X        image->colormap[p->index].flags=True;
  1735. X        image->colors++;
  1736. X      }
  1737. X    p++;
  1738. X  }
  1739. X  if (image->colors == number_colors)
  1740. X    return;  /* no unused entries */
  1741. X  /*
  1742. X    Compress colormap.
  1743. X  */
  1744. X  colormap=(ColorPacket *) malloc(image->colors*sizeof(ColorPacket));
  1745. X  if (colormap == (ColorPacket *) NULL)
  1746. X    {
  1747. X      Warning("unable to compress colormap","memory allocation error");
  1748. X      image->colors=number_colors;
  1749. X      return;
  1750. X    }
  1751. X  for (i=0; i < number_colors; i++)
  1752. X    if (image->colormap[i].flags)
  1753. X      {
  1754. X        index=image->colormap[i].index;
  1755. X        colormap[index].red=image->colormap[i].red;
  1756. X        colormap[index].green=image->colormap[i].green;
  1757. X        colormap[index].blue=image->colormap[i].blue;
  1758. X      }
  1759. X  /*
  1760. X    Remap pixels.
  1761. X  */
  1762. X  p=image->pixels;
  1763. X  for (i=0; i < image->packets; i++)
  1764. X  {
  1765. X    p->index=image->colormap[p->index].index;
  1766. X    p++;
  1767. X  }
  1768. X  (void) free((char *) image->colormap);
  1769. X  image->colormap=colormap;
  1770. }
  1771. X
  1772. /*
  1773. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1774. %                                                                             %
  1775. %                                                                             %
  1776. %                                                                             %
  1777. %   C o m p r e s s I m a g e                                                 %
  1778. %                                                                             %
  1779. %                                                                             %
  1780. SHAR_EOF
  1781. true || echo 'restore of ImageMagick/image.c failed'
  1782. fi
  1783. echo 'End of  part 4'
  1784. echo 'File ImageMagick/image.c is continued in part 5'
  1785. echo 5 > _shar_seq_.tmp
  1786. exit 0
  1787. exit 0 # Just in case...
  1788.