home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / util / unix / macutil2.sha / macutil / fileio / wrfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-05  |  19.0 KB  |  848 lines

  1. #ifdef TYPES_H
  2. #include <sys/types.h>
  3. #endif /* TYPES_H */
  4. #include <sys/stat.h>
  5. #include <ctype.h>
  6. #include <stdio.h>
  7. #include "machdr.h"
  8. #include "wrfile.h"
  9. #include "wrfileopt.h"
  10. #include "../util/util.h"
  11. #ifdef AUFSPLUS
  12. #include "../util/curtime.h"
  13. #define AUFS
  14. #endif /* AUFSPLUS */
  15. #ifdef AUFS
  16. #include "aufs.h"
  17. #define APPLESHARE
  18. #endif /* AUFS */
  19. #ifdef APPLEDOUBLE
  20. #include "appledouble.h"
  21. #include "../util/curtime.h"
  22. #define APPLESHARE
  23. #endif /* APPLEDOUBLE */
  24.  
  25. #define TEXT 0
  26. #define DATA 1
  27. #define RSRC 2
  28. #define FULL 3
  29. #define MACB 4
  30. #define FORK 5
  31. #define APSH 6
  32. #define MACS 7
  33. #define UNIX 8
  34. #ifdef SCAN
  35. #define MACI 9
  36. #endif /* SCAN */
  37.  
  38. extern char *malloc();
  39. extern char *realloc();
  40. extern char *strcpy();
  41. extern char *strncpy();
  42. extern char *strcat();
  43. extern void exit();
  44.  
  45. #ifdef UNDEF /* Do not declare sprintf; not portable (but lint will complain) */
  46. char *sprintf();
  47. #endif /* UNDEF */
  48.  
  49. #ifdef AUFS
  50. static void check_aufs();
  51. static void aufs_namings();
  52. static void wr_aufs_info();
  53. #endif /* AUFS */
  54. #ifdef APPLEDOUBLE
  55. static void check_appledouble();
  56. static void appledouble_namings();
  57. static void wr_appledouble_info();
  58. #endif /* APPLEDOUBLE */
  59. #ifdef APPLESHARE
  60. static void mk_share_name();
  61. #endif /* APPLESHARE */
  62.  
  63. #ifndef BSD
  64. /* all those stupid differences! */
  65. #define bcopy(src,dest,length)    memcpy((dest),(src),(length))
  66. #define bzero(block,length)    memset((block),0,(length))
  67. #endif /* BSD */
  68.  
  69. #define INFO_FORK    1
  70. #define RSRC_FORK    2
  71. #define DATA_FORK    3
  72.  
  73. static char f_info[I_NAMELEN];
  74. static char f_data[I_NAMELEN*3];
  75. static char f_rsrc[I_NAMELEN];
  76. static char f_text[I_NAMELEN];
  77. static char f_unix[I_NAMELEN];
  78. static char f_bin[I_NAMELEN];
  79. static char f_folder[] = ".foldername";
  80. static char share_name[256];
  81. #ifdef APPLESHARE
  82. static char hex[] = "0123456789abcdef";
  83. #endif /* APPLESHARE */
  84. #ifdef AUFS
  85. static char infodir[] = ".finderinfo";
  86. static char rsrcdir[] = ".resource";
  87. #define INFOSZ    sizeof(infodir)
  88. #define RSRCSZ    sizeof(rsrcdir)
  89. static char f_info_aufs[I_NAMELEN*3+INFOSZ];
  90. static char f_rsrc_aufs[I_NAMELEN*3+RSRCSZ];
  91. #endif /* AUFS */
  92. #ifdef APPLEDOUBLE
  93. static char infodir[] = ".AppleDouble";
  94. #define INFOSZ    sizeof(infodir)
  95. static char f_info_appledouble[I_NAMELEN*3+INFOSZ];
  96. #endif /* APPLEDOUBLE */
  97.  
  98. static int mode = MACB;
  99. static int mode_restricted = 0;
  100. static int mode_s_restricted = 0;
  101. char *out_buffer, *out_ptr;
  102.  
  103. static char init_buffer[128];
  104. static char *buffer = &(init_buffer[0]);
  105. static char *rbuffer = NULL, *dbuffer = NULL;
  106. static char *ptr;
  107. static unsigned long rsz, dsz, totsize, maxsize;
  108.  
  109. void define_name(text)
  110. char *text;
  111. {
  112.     (void)sprintf(f_info, "%s.info", text);
  113.     (void)sprintf(f_rsrc, "%s.rsrc", text);
  114.     (void)sprintf(f_data, "%s.data", text);
  115.     (void)sprintf(f_text, "%s.text", text);
  116.     (void)sprintf(f_bin, "%s.bin", text);
  117.     (void)sprintf(f_unix, "%s", text);
  118. #ifdef APPLESHARE
  119. /* Do not do namestuffing here.  We want to base again on the information in
  120.    the info header, so this is delayed
  121. */
  122. #endif /* APPLESHARE */
  123. }
  124.  
  125. void start_info(info, rsize, dsize)
  126. char *info;
  127. unsigned long rsize, dsize;
  128. {
  129.     int rs, ds;
  130.  
  131.     rsz = rsize;
  132.     dsz = dsize;
  133.     rs = (((rsz + 127) >> 7) << 7);
  134.     ds = (((dsz + 127) >> 7) << 7);
  135.     totsize = rs + ds + 128;
  136.     if(buffer == &(init_buffer[0])) {
  137.     buffer = (char *)malloc((unsigned)totsize);
  138.     } else if(maxsize < totsize) {
  139.     buffer = (char *)realloc(buffer, (unsigned)totsize);
  140.     }
  141.     maxsize = totsize;
  142.     if(buffer == NULL) {
  143.     (void)fprintf(stderr, "Insufficient memory, aborting\n");
  144.     exit(1);
  145.     }
  146.     dbuffer = buffer + 128;
  147.     rbuffer = dbuffer + ds;
  148.     (void)bzero(buffer, (int)totsize);
  149.     ptr = buffer;
  150.     (void)bcopy(info, ptr, 128);
  151. #ifdef AUFS
  152. /* Now we do filenaming etc. */
  153.     if(mode == APSH) {
  154.     aufs_namings();
  155.     }
  156. #endif /* AUFS */
  157. #ifdef APPLEDOUBLE
  158. /* Now we do filenaming etc. */
  159.     if(mode == APSH) {
  160.     appledouble_namings();
  161.     }
  162. #endif /* APPLEDOUBLE */
  163. }
  164.  
  165. void start_rsrc()
  166. {
  167.     out_buffer = out_ptr = rbuffer;
  168. }
  169.  
  170. void start_data()
  171. {
  172.     out_buffer = out_ptr = dbuffer;
  173. }
  174.  
  175. void end_file()
  176. {
  177.     FILE *fp;
  178.     int i, c;
  179.  
  180.     buffer[I_FLAGOFF] &= (~INITED_MASK);
  181.     switch(mode) {
  182.     case FULL:
  183.     case FORK:
  184.     fp = fopen(f_info, "w");
  185.     if(fp == NULL) {
  186.         perror(f_info);
  187.         exit(1);
  188.     }
  189.     (void)fwrite(buffer, 1, 128, fp);
  190.     (void)fclose(fp);
  191.     if(rsz != 0 || mode == FULL) {
  192.         fp = fopen(f_rsrc, "w");
  193.         if(fp == NULL) {
  194.         perror(f_rsrc);
  195.         exit(1);
  196.         }
  197.         (void)fwrite(rbuffer, 1, (int)rsz, fp);
  198.         (void)fclose(fp);
  199.     }
  200.     if(dsz != 0 || mode == FULL) {
  201.         fp = fopen(f_data, "w");
  202.         if(fp == NULL) {
  203.         perror(f_data);
  204.         exit(1);
  205.         }
  206.         (void)fwrite(dbuffer, 1, (int)dsz, fp);
  207.         (void)fclose(fp);
  208.     }
  209.     break;
  210.     case RSRC:
  211.     fp = fopen(f_rsrc, "w");
  212.     if(fp == NULL) {
  213.         perror(f_rsrc);
  214.         exit(1);
  215.     }
  216.     (void)fwrite(rbuffer, 1, (int)rsz, fp);
  217.     (void)fclose(fp);
  218.     break;
  219.     case DATA:
  220.     fp = fopen(f_data, "w");
  221.     if(fp == NULL) {
  222.         perror(f_data);
  223.         exit(1);
  224.     }
  225.     (void)fwrite(dbuffer, 1, (int)dsz, fp);
  226.     (void)fclose(fp);
  227.     break;
  228.     case TEXT:
  229.     fp = fopen(f_text, "w");
  230.     if(fp == NULL) {
  231.         perror(f_data);
  232.         exit(1);
  233.     }
  234.     for(i = 0; i < dsz; i++) {
  235.         c = dbuffer[i];
  236.         if(c == '\012' || c == '\015') {
  237.         dbuffer[i] = '\027' -c;
  238.         }
  239.     }
  240.     (void)fwrite(dbuffer, 1, (int)dsz, fp);
  241.     (void)fclose(fp);
  242.     break;
  243.     case UNIX:
  244.     fp = fopen(f_unix, "w");
  245.     if(fp == NULL) {
  246.         perror(f_data);
  247.         exit(1);
  248.     }
  249.     for(i = 0; i < dsz; i++) {
  250.         c = dbuffer[i];
  251.         if(c == '\012' || c == '\015') {
  252.         dbuffer[i] = '\027' -c;
  253.         }
  254.     }
  255.     (void)fwrite(dbuffer, 1, (int)dsz, fp);
  256.     (void)fclose(fp);
  257.     break;
  258.     case MACB:
  259.     fp = fopen(f_bin, "w");
  260.     if(fp == NULL) {
  261.         perror(f_bin);
  262.         exit(1);
  263.     }
  264.     if(buffer[I_FLAGOFF + 1] & PROTCT_MASK) {
  265.         buffer[I_LOCKOFF] = 1;
  266.     }
  267.     buffer[I_FLAGOFF + 1] = 0;
  268.     buffer[I_LOCKOFF + 1] = 0;
  269.     (void)fwrite(buffer, 1, (int)totsize, fp);
  270.     (void)fclose(fp);
  271.     break;
  272.     case MACS:
  273. #ifdef SCAN
  274.     case MACI:
  275. #endif /* SCAN */
  276.     if(buffer[I_FLAGOFF + 1] & PROTCT_MASK) {
  277.         buffer[I_LOCKOFF] = 1;
  278.     }
  279.     buffer[I_FLAGOFF + 1] = 0;
  280.     buffer[I_LOCKOFF + 1] = 0;
  281.     (void)fwrite(buffer, 1, (int)totsize, stdout);
  282.     break;
  283. #ifdef AUFS
  284.     case APSH:
  285.     fp = fopen(f_info_aufs, "w");
  286.     if(fp == NULL) {
  287.         perror(f_info_aufs);
  288.         exit(1);
  289.     }
  290.     wr_aufs_info(fp);
  291.     (void) fclose(fp);
  292.     fp = fopen(f_rsrc_aufs, "w");
  293.     if(fp == NULL) {
  294.         perror(f_rsrc_aufs);
  295.         exit(1);
  296.     }
  297.     (void)fwrite(rbuffer, 1, (int)rsz, fp);
  298.     (void)fclose(fp);
  299.     fp = fopen(f_data, "w");
  300.     if(fp == NULL) {
  301.         perror(f_data);
  302.         exit(1);
  303.     }
  304.     (void)fwrite(dbuffer, 1, (int)dsz, fp);
  305.     (void)fclose(fp);
  306.     break;
  307. #endif /* AUFS */
  308. #ifdef APPLEDOUBLE
  309.     case APSH:
  310.     fp = fopen(f_info_appledouble, "w");
  311.     if(fp == NULL) {
  312.         perror(f_info_appledouble);
  313.         exit(1);
  314.     }
  315.     wr_appledouble_info(fp);
  316.     (void)fwrite(rbuffer, 1, (int)rsz, fp);
  317.     (void)fclose(fp);
  318.     fp = fopen(f_data, "w");
  319.     if(fp == NULL) {
  320.         perror(f_data);
  321.         exit(1);
  322.     }
  323.     (void)fwrite(dbuffer, 1, (int)dsz, fp);
  324.     (void)fclose(fp);
  325.     break;
  326. #endif /* APPLEDOUBLE */
  327.     }
  328. }
  329.  
  330. #ifdef SCAN
  331. void do_idf(name, kind)
  332. char *name;
  333. int kind;
  334. {
  335.     int n;
  336.  
  337.     if(mode != MACI) {
  338.     return;
  339.     }
  340.     n = strlen(name);
  341.     (void)bzero(buffer, INFOBYTES);
  342.     buffer[I_NAMEOFF + 1] = kind;
  343.     put4(buffer + I_DLENOFF, (unsigned long)n);
  344.     (void)fwrite(buffer, 1, INFOBYTES, stdout);
  345.     if(n != 0) {
  346.     (void)fwrite(name, 1, n, stdout);
  347.     n = (((n + 127) >> 7) << 7) - n;
  348.     while(n-- > 0) {
  349.         (void)fputc(0, stdout);
  350.     }
  351.     }
  352. }
  353. #endif /* SCAN */
  354.  
  355. void do_mkdir(name, header)
  356. char *name, *header;
  357. {
  358. struct stat sbuf;
  359. FILE *fp;
  360. #ifdef NOMKDIR
  361. char command[21]; /* Systems without mkdir system call but more than 14
  362.              char file names?  Ridiculous! */
  363. int sysreturn;
  364. #endif /* MKDIR */
  365. #ifdef APPLESHARE
  366. char dirinfo[I_NAMELEN*3+INFOSZ+10];
  367. #endif /* APPLESHARE */
  368.  
  369. #ifndef SCAN
  370.     if(mode == MACS) {
  371. #else /* SCAN */
  372.     if(mode == MACS || mode == MACI) {
  373. #endif /* SCAN */
  374.         header[I_NAMEOFF] |= 0x80;
  375.     (void)fwrite(header, 1, INFOBYTES, stdout);
  376.     header[I_NAMEOFF] &= 0x7f;
  377.     return;
  378.     }
  379. #ifdef APPLESHARE
  380.     if(mode == APSH) {
  381.     (void)bcopy(header, buffer, INFOBYTES);
  382.     mk_share_name();
  383.     } else {
  384.     (void)strcpy(share_name, name);
  385.     }
  386. #else /* APPLESHARE */
  387.     (void)strcpy(share_name, name);
  388. #endif /* APPLESHARE */
  389.     if(stat(share_name, &sbuf) == -1) {  /* directory doesn't exist */
  390. #ifndef NOMKDIR
  391.     if(mkdir(share_name, 0777) == -1) {
  392.         (void)fprintf(stderr, "Can't create subdirectory %s\n", share_name);
  393.         exit(1);
  394.     }
  395. #else /* NOMKDIR */
  396.     sprintf(command, "mkdir %s", share_name);
  397.     if((sysreturn = system(command)) != 0) {
  398.         (void)fprintf(stderr, "Can't create subdirectory %s\n", share_name);
  399.         exit(sysreturn);
  400.     }
  401. #endif /* NOMKDIR */
  402.     } else {        /* something exists with this name */
  403.     if((sbuf.st_mode & S_IFMT) != S_IFDIR) {
  404.         (void)fprintf(stderr, "Directory name %s already in use\n",
  405.         share_name);
  406.         exit(1);
  407.     }
  408.     }
  409.     (void)chdir(share_name);
  410. #ifdef APPLESHARE
  411. #ifdef AUFS
  412.     if(mode == APSH) {
  413.     if(stat(rsrcdir, &sbuf) == -1) {  /* directory doesn't exist */
  414.         if(mkdir(rsrcdir, 0777) == -1) {
  415.          (void)fprintf(stderr, "Can't create subdirectory %s\n",
  416.             rsrcdir);
  417.          exit(1);
  418.         }
  419.     } else {
  420.         if((sbuf.st_mode & S_IFMT) != S_IFDIR) {
  421.         (void)fprintf(stderr, "Directory name %s already in use\n",
  422.             rsrcdir);
  423.         exit(1);
  424.         }
  425.     }
  426.     if(stat(infodir, &sbuf) == -1) {  /* directory doesn't exist */
  427.         if(mkdir(infodir, 0777) == -1) {
  428.          (void)fprintf(stderr, "Can't create subdirectory %s\n",
  429.             infodir);
  430.          exit(1);
  431.         }
  432.     } else {
  433.         if((sbuf.st_mode & S_IFMT) != S_IFDIR) {
  434.         (void)fprintf(stderr, "Directory name %s already in use\n",
  435.             infodir);
  436.         exit(1);
  437.         }
  438.     }
  439.     dirinfo[0] = 0;
  440.     (void)strcat(dirinfo, "../");
  441.     (void)strcat(dirinfo, infodir);
  442.     (void)strcat(dirinfo, "/");
  443.     (void)strcat(dirinfo, share_name);
  444.     fp = fopen(dirinfo, "w");
  445.     if(fp == NULL) {
  446.         perror(dirinfo);
  447.         exit(1);
  448.     }
  449.     wr_aufs_info(fp);
  450.     (void)fclose(fp);
  451.     } else {
  452.     fp = fopen(f_folder, "w");
  453.     if(fp == NULL) {
  454.         perror(f_folder);
  455.         exit(1);
  456.     }
  457.         header[I_NAMEOFF] |= 0x80;
  458.     (void)fwrite(header, 1, INFOBYTES, fp);
  459.     header[I_NAMEOFF] &= 0x7f;
  460.     (void)fclose(fp);
  461.     }
  462. #endif /* AUFS */
  463. #ifdef APPLEDOUBLE
  464.     if(mode == APSH) {
  465.     if(stat(infodir, &sbuf) == -1) {  /* directory doesn't exist */
  466.         if(mkdir(infodir, 0777) == -1) {
  467.          (void)fprintf(stderr, "Can't create subdirectory %s\n",
  468.             infodir);
  469.          exit(1);
  470.         }
  471.     } else {
  472.         if((sbuf.st_mode & S_IFMT) != S_IFDIR) {
  473.         (void)fprintf(stderr, "Directory name %s already in use\n",
  474.             infodir);
  475.         exit(1);
  476.         }
  477.     }
  478.     dirinfo[0] = 0;
  479.     (void)strcat(dirinfo, infodir);
  480.     (void)strcat(dirinfo, "/.Parent");
  481.     fp = fopen(dirinfo, "w");
  482.     if(fp == NULL) {
  483.         perror(dirinfo);
  484.         exit(1);
  485.     }
  486.     rsz = 0;
  487.     wr_appledouble_info(fp);
  488.     (void)fclose(fp);
  489.     } else {
  490.     fp = fopen(f_folder, "w");
  491.     if(fp == NULL) {
  492.         perror(f_folder);
  493.         exit(1);
  494.     }
  495.     header[I_NAMEOFF] |= 0x80;
  496.     (void)fwrite(header, 1, INFOBYTES, fp);
  497.     header[I_NAMEOFF] &= 0x7f;
  498.     (void)fclose(fp);
  499.     }
  500. #endif /* APPLEDOUBLE */
  501. #else /* APPLESHARE */
  502.     fp = fopen(f_folder, "w");
  503.     if(fp == NULL) {
  504.     perror(f_folder);
  505.     exit(1);
  506.     }
  507.     header[I_NAMEOFF] |= 0x80;
  508.     (void)fwrite(header, 1, INFOBYTES, fp);
  509.     header[I_NAMEOFF] &= 0x7f;
  510.     (void)fclose(fp);
  511. #endif /* APPLESHARE */
  512. }
  513.  
  514. void enddir()
  515. {
  516. char header[INFOBYTES];
  517. int i;
  518.  
  519. #ifndef SCAN
  520.     if(mode == MACS) {
  521. #else /* SCAN */
  522.     if(mode == MACS || mode == MACI) {
  523. #endif /* SCAN */
  524.     for(i = 0; i < INFOBYTES; i++) {
  525.         header[i] = 0;
  526.     }
  527.     header[I_NAMEOFF] = 0x80;
  528.     (void)fwrite(header, 1, INFOBYTES, stdout);
  529.     } else {
  530.     (void)chdir("..");
  531.     }
  532. }
  533.  
  534. #ifdef APPLESHARE
  535. #ifdef AUFS
  536. static void check_aufs()
  537. {
  538.     /* check for .resource/ and .finderinfo/ */
  539.     struct stat stbuf;
  540.     int error = 0;
  541.  
  542.     if(stat(rsrcdir,&stbuf) < 0) {
  543.     error ++;
  544.     } else {
  545.     if((stbuf.st_mode & S_IFMT) != S_IFDIR) {
  546.           error ++;
  547.     }
  548.     }
  549.     if(stat(infodir,&stbuf) < 0) {
  550.     error ++;
  551.     } else {
  552.     if((stbuf.st_mode & S_IFMT) != S_IFDIR) {
  553.           error++;
  554.     }
  555.     }
  556.     if(error) {
  557.     (void)fprintf(stderr, "Not in an Aufs folder.\n");
  558.     exit(1);
  559.     }
  560. }
  561.  
  562. static void aufs_namings()
  563. {
  564.     mk_share_name();
  565.     (void)sprintf(f_info_aufs, "%s/%s", infodir, share_name);
  566.     (void)sprintf(f_rsrc_aufs, "%s/%s", rsrcdir, share_name);
  567.     (void)sprintf(f_data, "%s", share_name);
  568. }
  569.  
  570. static void wr_aufs_info(fp)
  571. FILE *fp;
  572. {
  573.     FileInfo theinfo;
  574.     int n;
  575.  
  576.     bzero((char *) &theinfo, sizeof theinfo);
  577.     theinfo.fi_magic1 = FI_MAGIC1;
  578.     theinfo.fi_version = FI_VERSION;
  579.     theinfo.fi_magic = FI_MAGIC;
  580.     theinfo.fi_bitmap = FI_BM_MACINTOSHFILENAME;
  581.  
  582.     /* AUFS stores Unix times. */
  583. #ifdef AUFSPLUS
  584.     theinfo.fi_datemagic = FI_MAGIC;
  585.     theinfo.fi_datevalid = FI_CDATE | FI_MDATE;
  586.     put4(theinfo.fi_ctime, get4(buffer + I_CTIMOFF) - TIMEDIFF);
  587.     put4(theinfo.fi_mtime, get4(buffer + I_MTIMOFF) - TIMEDIFF);
  588.     put4(theinfo.fi_utime, (unsigned long)time((time_t *)0));
  589. #endif /* AUFSPLUS */
  590.     bcopy(buffer + I_TYPEOFF, theinfo.fi_fndr, 4);
  591.     bcopy(buffer + I_AUTHOFF, theinfo.fi_fndr + 4, 4);
  592.     bcopy(buffer + I_FLAGOFF, theinfo.fi_fndr + 8, 2);
  593.     if((n = buffer[I_NAMEOFF] & 0xff) > F_NAMELEN) {
  594.     n = F_NAMELEN;
  595.     }
  596.     (void)strncpy((char *)theinfo.fi_macfilename, buffer + I_NAMEOFF + 1,n);
  597.     /* theinfo.fi_macfilename[n] = '\0'; */
  598.     (void)strcpy((char *)theinfo.fi_comnt,
  599.     "Converted by Unix utility to Aufs format");
  600.     theinfo.fi_comln = strlen((char *)theinfo.fi_comnt);
  601.     (void)fwrite((char *) &theinfo, 1, sizeof theinfo, fp);
  602. }
  603. #endif /* AUFS */
  604.  
  605. #ifdef APPLEDOUBLE
  606. static void check_appledouble()
  607. {
  608.     /* check for .AppleDouble/ */
  609.     struct stat stbuf;
  610.     int error = 0;
  611.  
  612.     if(stat(infodir,&stbuf) < 0) {
  613.     error ++;
  614.     } else {
  615.     if((stbuf.st_mode & S_IFMT) != S_IFDIR) {
  616.           error++;
  617.     }
  618.     }
  619.     if(error) {
  620.     (void)fprintf(stderr, "Not in an AppleDouble folder.\n");
  621.     exit(1);
  622.     }
  623. }
  624.  
  625. static void appledouble_namings()
  626. {
  627.     mk_share_name();
  628.     (void)sprintf(f_info_appledouble, "%s/%s", infodir, share_name);
  629.     (void)sprintf(f_data, "%s", share_name);
  630. }
  631.  
  632. static void wr_appledouble_info(fp)
  633. FILE *fp;
  634. {
  635.     FileInfo theinfo;
  636.     int n;
  637.  
  638.     bzero((char *) &theinfo, sizeof theinfo);
  639.     put4(theinfo.fi_magic, (unsigned long)FI_MAGIC);
  640.     put2(theinfo.fi_version, (unsigned long)FI_VERSION);
  641.     put4(theinfo.fi_fill5, (unsigned long)FI_FILL5);
  642.     put4(theinfo.fi_fill6, (unsigned long)FI_FILL6);
  643.     put4(theinfo.fi_hlen, (unsigned long)FI_HLEN);
  644.     put4(theinfo.fi_fill7, (unsigned long)FI_FILL7);
  645.     put4(theinfo.fi_namptr, (unsigned long)FI_NAMPTR);
  646.     put4(theinfo.fi_fill9, (unsigned long)FI_FILL9);
  647.     put4(theinfo.fi_commptr, (unsigned long)FI_COMMPTR);
  648.     put4(theinfo.fi_fill12, (unsigned long)FI_FILL12);
  649.     put4(theinfo.fi_timeptr, (unsigned long)FI_TIMEPTR);
  650.     put4(theinfo.fi_timesize, (unsigned long)FI_TIMESIZE);
  651.     put4(theinfo.fi_fill15, (unsigned long)FI_FILL15);
  652.     put4(theinfo.fi_infoptr, (unsigned long)FI_INFOPTR);
  653.     put4(theinfo.fi_infosize, (unsigned long)FI_INFOSIZE);
  654.  
  655.     bcopy(buffer + I_TYPEOFF, theinfo.fi_type, 4);
  656.     bcopy(buffer + I_AUTHOFF, theinfo.fi_auth, 4);
  657.     bcopy(buffer + I_FLAGOFF, theinfo.fi_finfo, 2);
  658.     /* AppleDouble stores Unix times. */
  659.     put4(theinfo.fi_ctime, get4(buffer + I_CTIMOFF) - TIMEDIFF);
  660.     put4(theinfo.fi_mtime, get4(buffer + I_MTIMOFF) - TIMEDIFF);
  661.     if((n = buffer[I_NAMEOFF] & 0xff) > F_NAMELEN) {
  662.     n = F_NAMELEN;
  663.     }
  664.     put4(theinfo.fi_namlen, (unsigned long)n);
  665.     (void)strncpy((char *)theinfo.fi_name, buffer + I_NAMEOFF + 1,n);
  666.     /* theinfo.fi_macfilename[n] = '\0'; */
  667.     (void)strcpy((char *)theinfo.fi_comment,
  668.     "Converted by Unix utility to AppleDouble format");
  669.     put4(theinfo.fi_commsize, (unsigned long)strlen(theinfo.fi_comment));
  670.     put4(theinfo.fi_rsrc, (unsigned long)rsz);
  671.     /*  Still TODO */
  672.     /*  char    fi_ctime[4];    /* Creation time (Unix time) */
  673.     /*  char    fi_mtime[4];    /* Modification time (Unix time) */
  674.     (void)fwrite((char *) &theinfo, 1, sizeof theinfo, fp);
  675. }
  676. #endif /* APPLEDOUBLE */
  677.  
  678. static void mk_share_name()
  679. {
  680.     int ch;
  681.     char *mp, *up;
  682.  
  683.     mp = buffer + 2;
  684.     up = &(share_name[0]);
  685.     while(ch = *mp++) {
  686.     if(isascii(ch) && ! iscntrl(ch) && isprint(ch) && ch != '/') {
  687.         *up++ = ch;
  688.     } else {
  689.         *up++ = ':';
  690.         *up++ = hex[(ch >> 4) & 0xf];
  691.         *up++ = hex[ch & 0xf];
  692.     }
  693.     }
  694.     *up = 0;
  695. }
  696. #endif /* APPLESHARE */
  697.  
  698. int wrfileopt(c)
  699. char c;
  700. {
  701.     switch(c) {
  702.     case 'b':
  703.     mode = MACB;
  704.     break;
  705.     case 'r':
  706.     if(mode_restricted) {
  707.         return 0;
  708.     }
  709.     mode = RSRC;
  710.     break;
  711.     case 'd':
  712.     if(mode_restricted) {
  713.         return 0;
  714.     }
  715.     mode = DATA;
  716.     break;
  717.     case 'u':
  718.     if(mode_restricted) {
  719.         return 0;
  720.     }
  721.     mode = TEXT;
  722.     break;
  723.     case 'U':
  724.     if(mode_restricted) {
  725.         return 0;
  726.     }
  727.     mode = TEXT;
  728.     break;
  729.     case 'f':
  730.     mode = FORK;
  731.     break;
  732.     case '3':
  733.     mode = FULL;
  734.     break;
  735.     case 's':
  736.     if(mode_s_restricted) {
  737.         return 0;
  738.     }
  739.     mode = MACS;
  740.     break;
  741. #ifdef SCAN
  742.     case 'S':
  743.     if(mode_s_restricted) {
  744.         return 0;
  745.     }
  746.     mode = MACI;
  747.     break;
  748. #endif /* SCAN */
  749.     case 'a':
  750. #ifdef APPLESHARE
  751. #ifdef AUFS
  752.     check_aufs();
  753.     mode = APSH;
  754.     break;
  755. #endif /* AUFS */
  756. #ifdef APPLEDOUBLE
  757.     check_appledouble();
  758.     mode = APSH;
  759.     break;
  760. #endif /* APPLEDOUBLE */
  761. #else /* APPLESHARE */
  762.     (void)fprintf(stderr, "Sorry, Apple-Unix sharing is not supported.\n");
  763.     (void)fprintf(stderr, "Recompile or omit -a option.\n");
  764.     exit(1);
  765. #endif /* APPLESHARE */
  766.     default:
  767.     return 0;
  768.     }
  769.     return 1;
  770. }
  771.  
  772. void give_wrfileopt()
  773. {
  774.     (void)fprintf(stderr, "File output options:\n");
  775.     (void)fprintf(stderr, "-b:\tMacBinary (default)\n");
  776.     if(!mode_s_restricted) {
  777.     (void)fprintf(stderr, "-s:\tMacBinary stream to standard output\n");
  778. #ifdef SCAN
  779.     (void)fprintf(stderr,
  780.         "-S:\tas -s but with indication of orignal Unix filename\n");
  781. #endif /* SCAN */
  782.     }
  783.     (void)fprintf(stderr, "-f:\tthree fork mode, skipping empty forks\n");
  784.     (void)fprintf(stderr, "-3:\tthe same, writing also empty forks\n");
  785.     if(!mode_restricted) {
  786.     (void)fprintf(stderr, "-r:\tresource forks only\n");
  787.     (void)fprintf(stderr, "-d:\tdata forks only\n");
  788.     (void)fprintf(stderr,
  789.         "-u:\tdata forks only with Mac -> Unix text file translation\n");
  790.     (void)fprintf(stderr,
  791.         "-U:\tas -u, but filename will not have an extension\n");
  792.     }
  793. #ifdef APPLESHARE
  794. #ifdef AUFS
  795.     (void)fprintf(stderr, "-a:\tAUFS format\n");
  796. #endif /* AUFS */
  797. #ifdef APPLEDOUBLE
  798.     (void)fprintf(stderr, "-a:\tAppleDouble format\n");
  799. #endif /* APPLEDOUBLE */
  800. #else /* APPLESHARE */
  801.     (void)fprintf(stderr, "-a:\tnot supported, needs recompilation\n");
  802. #endif /* APPLESHARE */
  803. }
  804.  
  805. void set_wrfileopt(restricted)
  806. {
  807.     mode_restricted = restricted;
  808. }
  809.  
  810. void set_s_wrfileopt(restricted)
  811. {
  812.     mode_s_restricted = restricted;
  813. }
  814.  
  815. char *get_wrfileopt()
  816. {
  817.     static char options[20];
  818.  
  819.     (void)strcpy(options, "b");
  820.     if(!mode_s_restricted) {
  821.     (void)strcat(options, "s");
  822. #ifdef SCAN
  823.     (void)strcat(options, "S");
  824. #endif /* SCAN */
  825.     }
  826.     (void)strcat(options, "f3");
  827.     if(!mode_restricted) {
  828.     (void)strcat(options, "rduU");
  829.     }
  830.     (void)strcat(options, "a");
  831.     return options;
  832. }
  833.  
  834. char *get_mina()
  835. {
  836. #ifdef APPLESHARE
  837. #ifdef AUFS
  838.     return ", AUFS supported";
  839. #endif /* AUFS */
  840. #ifdef APPLEDOUBLE
  841.     return ", AppleDouble supported";
  842. #endif /* APPLEDOUBLE */
  843. #else /* APPLESHARE */
  844.     return ", no Apple-Unix sharing supported";
  845. #endif /* APPLESHARE */
  846. }
  847.  
  848.