home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / sources / misc / 4172 < prev    next >
Encoding:
Text File  |  1992-12-13  |  57.3 KB  |  1,794 lines

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