rock.c
上传用户:xiejiait
上传日期:2007-01-06
资源大小:881k
文件大小:16k
源码类别:

SCSI/ASPI

开发平台:

MultiPlatform

  1. /*
  2.  * File rock.c - generate RRIP  records for iso9660 filesystems.
  3.    Written by Eric Youngdale (1993).
  4.    Copyright 1993 Yggdrasil Computing, Incorporated
  5.    This program is free software; you can redistribute it and/or modify
  6.    it under the terms of the GNU General Public License as published by
  7.    the Free Software Foundation; either version 2, or (at your option)
  8.    any later version.
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.    You should have received a copy of the GNU General Public License
  14.    along with this program; if not, write to the Free Software
  15.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16. static char rcsid[] ="$Id: rock.c,v 1.8 1999/03/02 03:41:26 eric Exp $";
  17. #include "config.h"
  18. #include <stdlib.h>
  19. #include <unixstd.h>
  20. #include <device.h>
  21. #include "mkisofs.h"
  22. #include "iso9660.h"
  23. #include <string.h>
  24. #ifdef DOESNT_WORK
  25. #ifdef NON_UNIXFS
  26. /*
  27.  * This is the dead code
  28.  */
  29. #define S_ISLNK(m) (0)
  30. #else
  31. #ifndef S_ISLNK
  32. #define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
  33. #endif
  34. #endif
  35. #else
  36. /*
  37.  * This is the new code
  38.  */
  39. #include <statdefs.h>
  40. #endif
  41. #ifdef USE_LIBSCHILY
  42. #include <standard.h>
  43. #endif
  44. #define SU_VERSION 1
  45. #define SL_ROOT    8
  46. #define SL_PARENT  4
  47. #define SL_CURRENT 2
  48. #define SL_CONTINUE 1
  49. #define CE_SIZE 28
  50. #define CL_SIZE 12
  51. #define ER_SIZE 8
  52. #define NM_SIZE 5
  53. #define PL_SIZE 12
  54. #define PN_SIZE 20
  55. #define PX_SIZE 36
  56. #define RE_SIZE 4
  57. #define SL_SIZE 20
  58. #define ZZ_SIZE 15
  59. #ifdef __QNX__
  60. #define TF_SIZE (5 + 4 * 7)
  61. #else
  62. #define TF_SIZE (5 + 3 * 7)
  63. #endif
  64. /* If we need to store this number of bytes, make sure we
  65.    do not box ourselves in so that we do not have room for
  66.    a CE entry for the continuation record */
  67. #define MAYBE_ADD_CE_ENTRY(BYTES) 
  68.     (BYTES + CE_SIZE + currlen + (ipnt - recstart) > reclimit ? 1 : 0) 
  69. /*
  70.  * Buffer to build RR attributes
  71.  */
  72. static unsigned char Rock[16384];
  73. static unsigned char symlink_buff[256];
  74. static int ipnt = 0;
  75. static int recstart = 0;
  76. static int currlen = 0;
  77. static int mainrec = 0;
  78. static int reclimit;
  79. static void add_CE_entry __PR((void));
  80. static void add_CE_entry(){
  81.           if(recstart)
  82.     set_733((char*)Rock + recstart - 8, ipnt + 28 - recstart);
  83.   Rock[ipnt++] ='C';
  84.   Rock[ipnt++] ='E';
  85.   Rock[ipnt++] = CE_SIZE;
  86.   Rock[ipnt++] = SU_VERSION;
  87.   set_733((char*)Rock + ipnt, 0);
  88.   ipnt += 8;
  89.   set_733((char*)Rock + ipnt, 0);
  90.   ipnt += 8;
  91.   set_733((char*)Rock + ipnt, 0);
  92.   ipnt += 8;
  93.   recstart = ipnt;
  94.   currlen = 0;
  95.   if(!mainrec) mainrec = ipnt;
  96.   reclimit = SECTOR_SIZE - 8; /* Limit to one sector */
  97. }
  98. #ifdef __STDC__
  99. int generate_rock_ridge_attributes (char * whole_name, char * name,
  100.     struct directory_entry * s_entry,
  101.     struct stat * statbuf,
  102.     struct stat * lstatbuf,
  103.     int deep_opt)
  104. #else
  105. int generate_rock_ridge_attributes (whole_name, name,
  106.     s_entry,
  107.     statbuf,
  108.     lstatbuf,
  109.     deep_opt)
  110. char * whole_name; char * name; struct directory_entry * s_entry;
  111. struct stat * statbuf, *lstatbuf;
  112. int deep_opt;
  113. #endif
  114. {
  115.   int flagpos, flagval;
  116.   int need_ce;
  117.   statbuf = statbuf;        /* this shuts up unreferenced compiler warnings */
  118.   mainrec = recstart = ipnt = 0;
  119.   reclimit = 0xf8;
  120.   /* no need to fill in the RR stuff if we won't see the file */
  121.   if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY)
  122.     return 0;
  123.   /* Obtain the amount of space that is currently used for the directory
  124.      record.  Assume max for name, since name conflicts may cause us
  125.      to rename the file later on */
  126.   currlen = sizeof(s_entry->isorec);
  127.   /* Identify that we are using the SUSP protocol */
  128.   if(deep_opt & NEED_SP){
  129.   Rock[ipnt++] ='S';
  130.   Rock[ipnt++] ='P';
  131.   Rock[ipnt++] = 7;
  132.   Rock[ipnt++] = SU_VERSION;
  133.   Rock[ipnt++] = 0xbe;
  134.   Rock[ipnt++] = 0xef;
  135.   Rock[ipnt++] = 0;
  136.   };
  137.   /* First build the posix name field */
  138.   Rock[ipnt++] ='R';
  139.   Rock[ipnt++] ='R';
  140.   Rock[ipnt++] = 5;
  141.   Rock[ipnt++] = SU_VERSION;
  142.   flagpos = ipnt;
  143.   flagval = 0;
  144.   Rock[ipnt++] = 0;   /* We go back and fix this later */
  145.   if(strcmp(name,".")  && strcmp(name,"..")){
  146.     char * npnt;
  147.     int remain, use;
  148.     remain = strlen(name);
  149.     npnt = name;
  150.     while(remain){
  151.           use = remain;
  152.   need_ce = 0;
  153.   /* Can we fit this SUSP and a CE entry? */
  154.   if(use + currlen + CE_SIZE + (ipnt - recstart) > reclimit) {
  155.     use = reclimit - currlen - CE_SIZE - (ipnt - recstart);
  156.     need_ce++;
  157.   }
  158.   /* Only room for 256 per SUSP field */
  159.   if(use > 0xf8) use = 0xf8;
  160.   /* First build the posix name field */
  161.   Rock[ipnt++] ='N';
  162.   Rock[ipnt++] ='M';
  163.   Rock[ipnt++] = NM_SIZE + use;
  164.   Rock[ipnt++] = SU_VERSION;
  165.   Rock[ipnt++] = (remain != use ? 1 : 0);
  166.   flagval |= (1<<3);
  167.   strncpy((char *)&Rock[ipnt], npnt, use);
  168.   npnt += use;
  169.   ipnt += use;
  170.   remain -= use;
  171.   if(remain && need_ce) add_CE_entry();
  172. };
  173.   };
  174.   /*
  175.    * Add the posix modes 
  176.    */
  177.   if(MAYBE_ADD_CE_ENTRY(PX_SIZE)) add_CE_entry();
  178.   Rock[ipnt++] ='P';
  179.   Rock[ipnt++] ='X';
  180.   Rock[ipnt++] = PX_SIZE;
  181.   Rock[ipnt++] = SU_VERSION;  
  182.   flagval |= (1<<0);
  183.   set_733((char*)Rock + ipnt, lstatbuf->st_mode);
  184.   ipnt += 8;
  185.   set_733((char*)Rock + ipnt, lstatbuf->st_nlink);
  186.   ipnt += 8;
  187.   set_733((char*)Rock + ipnt, lstatbuf->st_uid);
  188.   ipnt += 8;
  189.   set_733((char*)Rock + ipnt, lstatbuf->st_gid);
  190.   ipnt += 8;
  191.   /*
  192.    * Check for special devices
  193.    */
  194. #if defined(S_IFCHR) || defined(S_IFBLK)
  195. #ifndef NON_UNIXFS
  196.   if (S_ISCHR(lstatbuf->st_mode) || S_ISBLK(lstatbuf->st_mode)) {
  197.     if(MAYBE_ADD_CE_ENTRY(PN_SIZE)) add_CE_entry();
  198.     Rock[ipnt++] ='P';
  199.     Rock[ipnt++] ='N';
  200.     Rock[ipnt++] = PN_SIZE;
  201.     Rock[ipnt++] = SU_VERSION;  
  202.     flagval |= (1<<1);
  203. #if 1
  204.     /*
  205.      * This is the new and only code which uses <device.h>
  206.      */
  207.     set_733((char*)Rock + ipnt, major(lstatbuf->st_rdev ));
  208.     ipnt += 8;
  209.     set_733((char*)Rock + ipnt, minor(lstatbuf->st_rdev));
  210.     ipnt += 8;
  211. #else
  212.     /*
  213.      * If we don't have sysmacros.h, then we have to guess as to how
  214.      * best to pick apart the device number for major/minor.
  215.      * Note: this may very well be wrong for many systems, so
  216.      * it is always best to use the major/minor macros if the
  217.      * system supports it.
  218.      */
  219.     if(sizeof(dev_t) <= 2) {
  220.         set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8));
  221.         ipnt += 8;
  222.         set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xff);
  223.         ipnt += 8;
  224.     }
  225.     else if(sizeof(dev_t) <= 4) {
  226.         set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 8) >> 8);
  227.         ipnt += 8;
  228.         set_733((char*)Rock + ipnt, lstatbuf->st_rdev & 0xffff);
  229.         ipnt += 8;
  230.     }
  231.     else {
  232.         set_733((char*)Rock + ipnt, (lstatbuf->st_rdev >> 16) >> 16);
  233.         ipnt += 8;
  234.         set_733((char*)Rock + ipnt, lstatbuf->st_rdev);
  235.         ipnt += 8;
  236.     }
  237. #endif
  238.   };
  239. #endif
  240. #endif /* defined(S_IFCHR) || defined(S_IFBLK) */
  241.   /*
  242.    * Check for and symbolic links.  VMS does not have these.
  243.    */
  244. #ifdef S_IFLNK
  245.   if (S_ISLNK(lstatbuf->st_mode)){
  246.     int lenpos, lenval, j0, j1;
  247.     int nchar;
  248.     unsigned char * cpnt, *cpnt1;
  249. #ifdef HAVE_READLINK
  250.     nchar = readlink(whole_name, (char *)symlink_buff, sizeof(symlink_buff));
  251. #else
  252.     nchar = -1;
  253. #endif /* HAVE_READLINK */
  254.     symlink_buff[nchar < 0 ? 0 : nchar] = 0;
  255.     nchar = strlen((char *) symlink_buff);
  256.     set_733(s_entry->isorec.size, 0);
  257.     cpnt = &symlink_buff[0];
  258.     flagval |= (1<<2);
  259.     if (! split_SL_field) 
  260.       {
  261. int sl_bytes = 0;
  262. for (cpnt1 = cpnt; *cpnt1 != ''; cpnt1++) 
  263.   {
  264.     if (*cpnt1 == '/') 
  265.       {
  266. sl_bytes += 4;
  267.       } 
  268.     else 
  269.       {
  270. sl_bytes += 1;
  271.       }
  272.   }
  273. if (sl_bytes > 250) 
  274.   {
  275.     /* 
  276.      * the symbolic link won't fit into one SL System Use Field
  277.      * print an error message and continue with splited one 
  278.      */
  279.     fprintf(stderr,"symbolic link ``%s'' to long for one SL System Use Field, splitting", cpnt);
  280.   }
  281.        if(MAYBE_ADD_CE_ENTRY(SL_SIZE + sl_bytes)) add_CE_entry();
  282.      }
  283.     while(nchar){
  284.       if(MAYBE_ADD_CE_ENTRY(SL_SIZE)) add_CE_entry();
  285.       Rock[ipnt++] ='S';
  286.       Rock[ipnt++] ='L';
  287.       lenpos = ipnt;
  288.       Rock[ipnt++] = SL_SIZE;
  289.       Rock[ipnt++] = SU_VERSION;  
  290.       Rock[ipnt++] = 0; /* Flags */
  291.       lenval = 5;
  292.       while(*cpnt){
  293. cpnt1 = (unsigned char *) strchr((char *) cpnt, '/');
  294. if(cpnt1) {
  295.   nchar--;
  296.   *cpnt1 = 0;
  297. };
  298. /* We treat certain components in a special way.  */
  299. if(cpnt[0] == '.' && cpnt[1] == '.' && cpnt[2] == 0){
  300.   if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
  301.   Rock[ipnt++] = SL_PARENT;
  302.   Rock[ipnt++] = 0;  /* length is zero */
  303.   lenval += 2;
  304.   nchar -= 2;
  305. } else if(cpnt[0] == '.' && cpnt[1] == 0){
  306.   if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
  307.   Rock[ipnt++] = SL_CURRENT;
  308.   Rock[ipnt++] = 0;  /* length is zero */
  309.   lenval += 2;
  310.   nchar -= 1;
  311. } else if(cpnt[0] == 0){
  312.   if(MAYBE_ADD_CE_ENTRY(2)) add_CE_entry();
  313.   Rock[ipnt++] = SL_ROOT;
  314.   Rock[ipnt++] = 0;  /* length is zero */
  315.   lenval += 2;
  316. } else {
  317.   /* If we do not have enough room for a component, start
  318.      a new continuations segment now */
  319.          if(split_SL_component ? MAYBE_ADD_CE_ENTRY(6) :
  320.                                  MAYBE_ADD_CE_ENTRY(6 + strlen ((char *) cpnt))) 
  321.    {
  322.      add_CE_entry();
  323.      if(cpnt1)
  324.        {
  325.  *cpnt1 = '/';
  326.  nchar++;
  327.  cpnt1 = NULL; /* A kluge so that we can restart properly */
  328.        }
  329.      break;
  330.    }
  331.   j0 = strlen((char *) cpnt);
  332.   while(j0) {
  333.     j1 = j0;
  334.     if(j1 > 0xf8) j1 = 0xf8;
  335.     need_ce = 0;
  336.     if(j1 + currlen + CE_SIZE + (ipnt - recstart) > reclimit) {
  337.       j1 = reclimit - currlen - CE_SIZE - (ipnt - recstart);
  338.       need_ce++;
  339.     }
  340.     Rock[ipnt++] = (j1 != j0 ? SL_CONTINUE : 0);
  341.     Rock[ipnt++] = j1;
  342.     strncpy((char *) Rock + ipnt, (char *) cpnt, j1);
  343.     ipnt += j1;
  344.     lenval += j1 + 2;
  345.     cpnt += j1;
  346.     nchar -= j1;  /* Number we processed this time */
  347.     j0 -= j1;
  348.     if(need_ce) {
  349.       add_CE_entry();
  350.       if(cpnt1) {
  351. *cpnt1 = '/';
  352.                 nchar++;
  353. cpnt1 = NULL; /* A kluge so that we can restart properly */
  354.       }
  355.       break;
  356.     }
  357.   }
  358. };
  359. if(cpnt1) {
  360.   cpnt = cpnt1 + 1;
  361. } else
  362.   break;
  363.       }
  364.       Rock[lenpos] = lenval;
  365.       if(nchar) Rock[lenpos + 2] = SL_CONTINUE; /* We need another SL entry */
  366.     } /* while nchar */
  367.   } /* Is a symbolic link */
  368. #endif /* S_IFLNK */
  369.   /* 
  370.    * Add in the Rock Ridge TF time field
  371.    */
  372.   if(MAYBE_ADD_CE_ENTRY(TF_SIZE)) add_CE_entry();
  373.   Rock[ipnt++] ='T';
  374.   Rock[ipnt++] ='F';
  375.   Rock[ipnt++] = TF_SIZE;
  376.   Rock[ipnt++] = SU_VERSION;
  377. #ifdef __QNX__
  378.   Rock[ipnt++] = 0x0f;
  379. #else
  380.   Rock[ipnt++] = 0x0e;
  381. #endif
  382.   flagval |= (1<<7);
  383. #ifdef __QNX__
  384.   iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ftime);
  385.   ipnt += 7;
  386. #endif
  387.   iso9660_date((char *) &Rock[ipnt], lstatbuf->st_mtime);
  388.   ipnt += 7;
  389.   iso9660_date((char *) &Rock[ipnt], lstatbuf->st_atime);
  390.   ipnt += 7;
  391.   iso9660_date((char *) &Rock[ipnt], lstatbuf->st_ctime);
  392.   ipnt += 7;
  393.   /* 
  394.    * Add in the Rock Ridge RE time field
  395.    */
  396.   if(deep_opt & NEED_RE){
  397.           if(MAYBE_ADD_CE_ENTRY(RE_SIZE)) add_CE_entry();
  398.   Rock[ipnt++] ='R';
  399.   Rock[ipnt++] ='E';
  400.   Rock[ipnt++] = RE_SIZE;
  401.   Rock[ipnt++] = SU_VERSION;
  402.   flagval |= (1<<6);
  403.   };
  404.   /* 
  405.    * Add in the Rock Ridge PL record, if required.
  406.    */
  407.   if(deep_opt & NEED_PL){
  408.           if(MAYBE_ADD_CE_ENTRY(PL_SIZE)) add_CE_entry();
  409.   Rock[ipnt++] ='P';
  410.   Rock[ipnt++] ='L';
  411.   Rock[ipnt++] = PL_SIZE;
  412.   Rock[ipnt++] = SU_VERSION;
  413.   set_733((char*)Rock + ipnt, 0);
  414.   ipnt += 8;
  415.   flagval |= (1<<5);
  416.   };
  417.   /* 
  418.    * Add in the Rock Ridge CL field, if required.
  419.    */
  420.   if(deep_opt & NEED_CL){
  421.           if(MAYBE_ADD_CE_ENTRY(CL_SIZE)) add_CE_entry();
  422.   Rock[ipnt++] ='C';
  423.   Rock[ipnt++] ='L';
  424.   Rock[ipnt++] = CL_SIZE;
  425.   Rock[ipnt++] = SU_VERSION;
  426.   set_733((char*)Rock + ipnt, 0);
  427.   ipnt += 8;
  428.   flagval |= (1<<4);
  429.   };
  430. #ifndef VMS
  431.   /* If transparent compression was requested, fill in the correct
  432.      field for this file */
  433.   if(transparent_compression && 
  434.      S_ISREG(lstatbuf->st_mode) &&
  435.      strlen(name) > 3 &&
  436.      strcmp(name + strlen(name) - 3,".gZ") == 0){
  437.     FILE * zipfile;
  438.     char * checkname;
  439.     unsigned int file_size;
  440.     unsigned char header[8];
  441.     int OK_flag;
  442.     /* First open file and verify that the correct algorithm was used */
  443.     file_size = 0;
  444.     OK_flag = 1;
  445.     zipfile = fopen(whole_name, "rb");
  446.     fread(header, 1, sizeof(header), zipfile);
  447.     /* Check some magic numbers from gzip. */
  448.     if(header[0] != 0x1f || header[1] != 0x8b || header[2] != 8) OK_flag = 0;
  449.     /* Make sure file was blocksized. */
  450.     if(((header[3] & 0x40) == 0)) OK_flag = 0;
  451.     /* OK, now go to the end of the file and get some more info */
  452.     if(OK_flag){
  453.       int status;
  454.       status = (long)lseek(fileno(zipfile), (off_t)(-8), SEEK_END);
  455.       if(status == -1) OK_flag = 0;
  456.     }
  457.     if(OK_flag){
  458.       if(read(fileno(zipfile), (char*)header, sizeof(header)) != sizeof(header))
  459. OK_flag = 0;
  460.       else {
  461. int blocksize;
  462. blocksize = (header[3] << 8) | header[2];
  463. file_size = ((unsigned int)header[7] << 24) | 
  464.     ((unsigned int)header[6] << 16) | 
  465.     ((unsigned int)header[5] << 8)  | header[4];
  466. #if 0
  467. fprintf(stderr,"Blocksize = %d %dn", blocksize, file_size);
  468. #endif
  469. if(blocksize != SECTOR_SIZE) OK_flag = 0;
  470.       }
  471.     }
  472.     fclose(zipfile);
  473.     checkname = strdup(whole_name);
  474.     checkname[strlen(whole_name)-3] = 0;
  475.     zipfile = fopen(checkname, "rb");
  476.     if(zipfile) {
  477.       OK_flag = 0;
  478. #ifdef USE_LIBSCHILY
  479.       errmsg("Unable to insert transparent compressed file - name conflictn");
  480. #else
  481.       fprintf(stderr, "Unable to insert transparent compressed file - name conflictn");
  482. #endif
  483.       fclose(zipfile);
  484.     }
  485.     free(checkname);
  486.     if(OK_flag){
  487.       if(MAYBE_ADD_CE_ENTRY(ZZ_SIZE)) add_CE_entry();
  488.       Rock[ipnt++] ='Z';
  489.       Rock[ipnt++] ='Z';
  490.       Rock[ipnt++] = ZZ_SIZE;
  491.       Rock[ipnt++] = SU_VERSION;
  492.       Rock[ipnt++] = 'g'; /* Identify compression technique used */
  493.       Rock[ipnt++] = 'z';
  494.       Rock[ipnt++] = 3;
  495.       set_733((char*)Rock + ipnt, file_size); /* Real file size */
  496.       ipnt += 8;
  497.     };
  498.   }
  499. #endif
  500.   /* 
  501.    * Add in the Rock Ridge CE field, if required.  We use  this for the
  502.    * extension record that is stored in the root directory.
  503.    */
  504.   if(deep_opt & NEED_CE) add_CE_entry();
  505.   /*
  506.    * Done filling in all of the fields.  Now copy it back to a buffer for the
  507.    * file in question.
  508.    */
  509.   /* Now copy this back to the buffer for the file */
  510.   Rock[flagpos] = flagval;
  511.   /* If there was a CE, fill in the size field */
  512.   if(recstart)
  513.     set_733((char*)Rock + recstart - 8, ipnt - recstart);
  514.   s_entry->rr_attributes = (unsigned char *) e_malloc(ipnt);
  515.   s_entry->total_rr_attr_size = ipnt;
  516.   s_entry->rr_attr_size = (mainrec ? mainrec : ipnt);
  517.   memcpy(s_entry->rr_attributes, Rock, ipnt);
  518.   return ipnt;
  519. }
  520. /* Guaranteed to  return a single sector with the relevant info */
  521. char * FDECL4(generate_rr_extension_record, char *, id,  char  *, descriptor,
  522.     char *, source, int  *, size){
  523.   int lipnt = 0;
  524.   char * pnt;
  525.   int len_id, len_des, len_src;
  526.   len_id = strlen(id);
  527.   len_des =  strlen(descriptor);
  528.   len_src = strlen(source);
  529.   Rock[lipnt++] ='E';
  530.   Rock[lipnt++] ='R';
  531.   Rock[lipnt++] = ER_SIZE + len_id + len_des + len_src;
  532.   Rock[lipnt++] = 1;
  533.   Rock[lipnt++] = len_id;
  534.   Rock[lipnt++] = len_des;
  535.   Rock[lipnt++] = len_src;
  536.   Rock[lipnt++] = 1;
  537.   memcpy(Rock  + lipnt, id, len_id);
  538.   lipnt += len_id;
  539.   memcpy(Rock  + lipnt, descriptor, len_des);
  540.   lipnt += len_des;
  541.   memcpy(Rock  + lipnt, source, len_src);
  542.   lipnt += len_src;
  543.   if(lipnt  > SECTOR_SIZE) {
  544. #ifdef USE_LIBSCHILY
  545.   comerrno(EX_BAD, "Extension record too longn");
  546. #else
  547.   fprintf(stderr,"Extension record too longn");
  548.   exit(1);
  549. #endif
  550.   };
  551.   pnt = (char *) e_malloc(SECTOR_SIZE);
  552.   memset(pnt, 0,  SECTOR_SIZE);
  553.   memcpy(pnt, Rock, lipnt);
  554.   *size = lipnt;
  555.   return pnt;
  556. }