home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / disk-man / mtools-3.000 / mtools-3 / mtools-3.0 / mlabel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-08  |  3.9 KB  |  192 lines

  1. /*
  2.  * mlabel.c
  3.  * Make an MSDOS volume label
  4.  */
  5.  
  6. #include "sysincludes.h"
  7. #include "msdos.h"
  8. #include "streamcache.h"
  9. #include "vfat.h"
  10. #include "mtools.h"
  11. #include "nameclash.h"
  12.  
  13. char *label_name(char *filename, int verbose, 
  14.          int *mangled, char *ans)
  15. {
  16.     int len;
  17.     int i;
  18.     int have_lower, have_upper;
  19.  
  20.     strcpy(ans,"           ");
  21.     len = strlen(filename);
  22.     if(len > 11){
  23.         *mangled = 1;
  24.         len = 11;
  25.     } else
  26.         *mangled = 0;
  27.     strncpy(ans, filename, len);
  28.     have_lower = have_upper = 0;
  29.     for(i=0; i<11; i++){
  30.         if(islower(ans[i]))
  31.             have_lower = 1;
  32.         if(isupper(ans[i]))
  33.             have_upper = 1;
  34.         ans[i] = toupper(ans[i]);
  35.  
  36.         if(strchr("^+=/[]:,?*\\<>|\".", ans[i])){
  37.             *mangled = 1;
  38.             ans[i] = '~';
  39.         }
  40.     }
  41.     if (have_lower && have_upper)
  42.         *mangled = 1;
  43.     return ans;
  44. }
  45.  
  46. struct directory *labelit(char *dosname,
  47.               char *longname,
  48.               void *arg0,
  49.               struct directory *dir)
  50. {
  51.     long now;
  52.  
  53.     /* find out current time */
  54.     time(&now);
  55.     mk_entry(dosname, 0x8, 0, 0, now, dir);
  56.     return dir;
  57. }
  58.  
  59.  
  60. void mlabel(int argc, char **argv, int type)
  61. {
  62.     Stream_t *Fs;
  63.     int entry, verbose, oops, clear, interactive, show, open_mode;
  64.     struct directory dir;
  65.     int result=0;
  66.     char longname[VBUFSIZE],filename[VBUFSIZE];
  67.     char shortname[13];
  68.     ClashHandling_t ch;
  69.     struct StreamCache_t sc;
  70.     Stream_t *RootDir;
  71.     int c;
  72.     int mangled;
  73.     
  74.     init_clash_handling(&ch);
  75.     ch.name_converter = label_name;
  76.     ch.ignore_entry = -2;
  77.  
  78.     verbose = 0;
  79.     oops = 0;
  80.     clear = 0;
  81.     show = 0;
  82.  
  83.     while ((c = getopt(argc, argv, "vcs")) != EOF) {
  84.         switch (c) {
  85.             case 'v':
  86.                 verbose = 1;
  87.                 break;
  88.             case '?':
  89.                 oops = 1;
  90.                 break;
  91.             case 'c':
  92.                 clear = 1;
  93.                 break;
  94.             case 's':
  95.                 show = 1;
  96.                 break;
  97.             }
  98.     }
  99.  
  100.     if (oops || argc - optind != 1 ||
  101.         !argv[optind][0] || argv[optind][1] != ':') {
  102.         fprintf(stderr, "Mtools version %s, dated %s\n",
  103.             mversion, mdate);
  104.         fprintf(stderr, "Usage: %s [-vscV] drive:\n", argv[0]);
  105.         cleanup_and_exit(1);
  106.     }
  107.  
  108.     init_sc(&sc);
  109.     get_name(argv[optind], filename, sc.mcwd);
  110.     interactive = !filename[0] && !show && !clear;
  111.     if (filename[0] || clear || interactive)
  112.         open_mode = O_RDWR;
  113.     else
  114.         open_mode = O_RDONLY;
  115.  
  116.     RootDir = open_subdir(&sc, argv[optind], open_mode, &Fs);
  117.     if(!RootDir)
  118.         cleanup_and_exit(1);
  119.     if(!Fs && open_mode == O_RDWR && !clear && !filename[0] &&
  120.        ( errno == EACCES || errno == EPERM) ) {
  121.         show = 1;
  122.         interactive = 0;
  123.         RootDir = open_subdir(&sc, argv[optind], O_RDONLY, &Fs);
  124.     }        
  125.     if(!RootDir)
  126.         cleanup_and_exit(1);
  127.     if(!Fs){
  128.         fprintf(stderr, "%s: Cannot initialize drive\n", argv[0]);
  129.         cleanup_and_exit(1);
  130.     }
  131.  
  132.     entry = 0;
  133.     vfat_lookup(RootDir, Fs, &dir, &entry, 0, 0, ACCEPT_LABEL | MATCH_ANY,
  134.             NULL, shortname, longname, NULL);
  135.     
  136.     if(show || interactive){
  137.         if(entry == -1)
  138.             printf(" Volume has no label\n");
  139.         else if (*longname)
  140.             printf(" Volume label is %s (abbr=%s)\n",
  141.                    longname, shortname);
  142.         else
  143.             printf(" Volume label is %s\n", shortname);
  144.  
  145.     }
  146.  
  147.     /* ask for new label */
  148.     if(interactive){
  149.         fprintf(stderr,"Enter the new volume label : ");
  150.         fgets(filename, VBUFSIZE, stdin);
  151.         if(filename[0])
  152.             filename[strlen(filename)-1] = '\0';
  153.     }
  154.  
  155.     if(!show && entry != -1){
  156.         /* if we have a label, wipe it out before putting new one */
  157.         if(interactive && filename[0] == '\0')
  158.             if (ask_confirmation("Delete volume label (y/n): ",0,0))
  159.                 cleanup_and_exit(0);        
  160.         dir.name[0] = DELMARK;
  161.         dir.attr = 0; /* for old mlabel */
  162.         dir_write(RootDir, entry-1, &dir);
  163.     }
  164.  
  165.     if (!show && filename[0] != '\0') {
  166.         ch.ignore_entry = 1;
  167.         result = mwrite_one(RootDir,Fs,argv[0],filename,0,
  168.                     labelit,NULL,&ch);
  169.     }
  170.  
  171.     if(!show){
  172.         struct bootsector boot;
  173.         
  174.         if(!filename[0])
  175.             strncpy(shortname, "NO NAME    ",11);
  176.         else
  177.             label_name(filename, verbose, &mangled, shortname);
  178.  
  179.         if(force_read(Fs, (char *) &boot, 0, sizeof(boot)) == 
  180.            sizeof(boot) &&
  181.            boot.descr >= 0xf0 &&
  182.            boot.dos4 == 0x29){
  183.             strncpy(boot.label, shortname, 11);
  184.             force_write(Fs, (char *)&boot, 0, sizeof(boot));
  185.         }
  186.     }
  187.  
  188.     FREE(&RootDir);
  189.     finish_sc(&sc);
  190.     cleanup_and_exit(result);
  191. }
  192.