home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / macutils.lzh / MACUTILS / FILEIO / wrfile.c < prev    next >
Text File  |  1996-02-01  |  20KB  |  856 lines

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