# 2.11BSD#431 - /usr/src/local/mtools/mread.c

##### Functions

    dir_flush         X
    disk_flush        X
    main              X

##### Variables

    clus_size         X
    dir_entries       X
    dir_len           X
    dir_start         X
    fat_error         X
    fd                X
    mcwd              X

##### Macros

    LOWERCASE         X

       1: /*
       2:  * Read (copy) an MSDOS file to Unix
       3:  *
       4:  * Emmet P. Gray			US Army, HQ III Corps & Fort Hood
       5:  * ...!uunet!uiucuxc!fthood!egray	Attn: AFZF-DE-ENV
       6:  * fthood!egray@uxc.cso.uiuc.edu	Directorate of Engineering & Housing
       7:  * 					Environmental Management Office
       8:  * 					Fort Hood, TX 76544-5057
       9:  */
      10:
      11: #define LOWERCASE
      12:
      13: #include <stdio.h>
      14: #include <ctype.h>
      15: #include <sys/types.h>
      16: #include <sys/stat.h>
      17: #ifdef BSD
      18: #include <sys/time.h>
      19: #else /* BSD */
      20: #include <time.h>
      21: #endif /* BSD */
      22: #include "msdos.h"
      23: #include "patchlevel.h"
      24:
      25: int fd = -1;                /* the file descriptor for the device */
      26: int dir_start;              /* starting sector for directory */
      27: int dir_len;                /* length of directory (in sectors) */
      28: int dir_entries;            /* number of directory entries */
      29: int clus_size;              /* cluster size (in sectors) */
      30: char *mcwd;             /* the Current Working Directory */
      31: int fat_error;              /* FAT error detected? */
      32:
      33: static void set_mtime();
      34: static FILE *open_file();
      35: static long conv_stamp();
      36:
      37: main(argc, argv)
      38: int argc;
      39: char *argv[];
      40: {
      41:     FILE *fp;
      42:     extern int optind;
      43:     extern char *optarg;
      44:     int i, ismatch, entry, single, c, oops, preserve, nowarn, textmode;
      45:     unsigned int fat;
      46:     long size, mtime;
      47:     char *filename, *newfile, *get_name(), *unix_name(), *pathname;
      48:     char *get_path(), *target, tmp[MAX_PATH], *strcat(), *strcpy(), drive;
      49:     char get_drive(), last_drive, *fix_mcwd(), *s;
      50:     void exit();
      51:     struct directory *dir, *dir_read();
      52:     struct stat stbuf;
      53:
      54:                     /* get command line options */
      55:     oops = 0;
      56:     preserve = 0;
      57:     nowarn = 0;
      58:     textmode = 0;
      59:     while ((c = getopt(argc, argv, "tnmv")) != EOF) {
      60:         switch (c) {
      61:             case 't':
      62:                 textmode = 1;
      63:                 break;
      64:             case 'n':
      65:                 nowarn = 1;
      66:                 break;
      67:             case 'm':
      68:                 preserve = 1;
      69:                 break;
      70:             case 'v':   /* dummy option for mcopy */
      71:                 break;
      72:             default:
      73:                 oops = 1;
      74:                 break;
      75:         }
      76:     }
      77:
      78:     if (oops || (argc - optind) < 2) {
      79:         fprintf(stderr, "Mtools version %s, dated %s\n", VERSION, DATE);
      80:         fprintf(stderr, "Usage: %s [-tnm] msdosfile unixfile\n", argv[0]);
      81:         fprintf(stderr, "       %s [-tnm] msdosfile [msdosfiles...] unixdirectory\n", argv[0]);
      82:         exit(1);
      83:     }
      84:     last_drive = 'x';
      85:     mcwd = fix_mcwd();
      86:                     /* only 1 file to copy... */
      87:     single = 1;
      88:     target = argv[argc - 1];
      89:                     /* ...unless last arg is a directory */
      90:     if (!stat(target, &stbuf)) {
      91:         if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
      92:             single = 0;
      93:     }
      94:                     /* too many arguments */
      95:     if (single && (argc - optind) != 2) {
      96:         fprintf(stderr, "%s: Too many arguments or destination directory omitted\n", argv[0]);
      97:         exit(1);
      98:     }
      99:
     100:     for (i = optind; i < argc - 1; i++) {
     101:         drive = get_drive(argv[i]);
     102:         if (drive != last_drive) {
     103:             if (init(drive, 0)) {
     104:                 fprintf(stderr, "%s: Cannot initialize '%c:'\n", argv[0], drive);
     105:                 continue;
     106:             }
     107:             last_drive = drive;
     108:         }
     109:         filename = get_name(argv[i]);
     110:         pathname = get_path(argv[i]);
     111:         if (subdir(drive, pathname))
     112:             continue;
     113:
     114:         ismatch = 0;
     115:         for (entry = 0; entry < dir_entries; entry++) {
     116:             dir = dir_read(entry);
     117:                     /* if empty */
     118:             if (dir->name[0] == 0x0)
     119:                 break;
     120:                     /* if erased */
     121:             if (dir->name[0] == 0xe5)
     122:                 continue;
     123:                     /* if dir or volume label */
     124:             if ((dir->attr & 0x10) || (dir->attr & 0x08))
     125:                 continue;
     126:
     127:             newfile = unix_name(dir->name, dir->ext);
     128:
     129:                     /* if single file */
     130:             if (single) {
     131:                 if (!strcmp(newfile, filename)) {
     132:                     fat = dir->start[1] * 0x100 + dir->start[0];
     133:                     size = dir->size[3] * 0x1000000L + dir->size[2] * 0x10000L + dir->size[1] * 0x100 + dir->size[0];
     134:                     if (preserve)
     135:                         mtime = conv_stamp(dir->time, dir->date);
     136:                     else
     137:                         mtime = 0L;
     138:                     if ((fp = open_file(target, nowarn))) {
     139:                         if (file_read(fp, fat, textmode, 0, size)) {
     140:                             fclose(fp);
     141:                             break;
     142:                         }
     143:                         fclose(fp);
     144:                         set_mtime(target, mtime);
     145:                     }
     146:                     ismatch = 1;
     147:                     break;
     148:                 }
     149:             }
     150:                     /* if multiple files */
     151:             else {
     152:                 if (match(newfile, filename)) {
     153:                     fat = dir->start[1] * 0x100 + dir->start[0];
     154:                     size = dir->size[3] * 0x1000000L + dir->size[2] * 0x10000L + dir->size[1] * 0x100 + dir->size[0];
     155:                     if (preserve)
     156:                         mtime = conv_stamp(dir->time, dir->date);
     157:                     else
     158:                         mtime = 0L;
     159:                     printf("Copying %s\n", newfile);
     160: #ifdef LOWERCASE
     161:                     s = newfile;
     162:                     while (*s) {
     163:                         if (isupper(*s))
     164:                             *s = tolower(*s);
     165:                         s++;
     166:                     }
     167: #endif /* LOWERCASE */
     168:                     strcpy(tmp, target);
     169:                     strcat(tmp, "/");
     170:                     strcat(tmp, newfile);
     171:                     if ((fp = open_file(tmp, nowarn))) {
     172:                         if (file_read(fp, fat, textmode, 0, size)) {
     173:                             fclose(fp);
     174:                             break;
     175:                         }
     176:                         fclose(fp);
     177:                         set_mtime(tmp, mtime);
     178:                     }
     179:                     ismatch = 1;
     180:                 }
     181:             }
     182:         }
     183:         if (fat_error)
     184:             break;
     185:
     186:         if (!ismatch)
     187:             fprintf(stderr, "%s: File \"%s\" not found\n", argv[0], filename);
     188:     }
     189:     close(fd);
     190:     exit(0);
     191: }
     192:
     193: /*
     194:  * Open the named Unix file for write.
     195:  */
     196:
     197: static FILE *
     198: open_file(target, nowarn)
     199: char *target;
     200: int nowarn;
     201: {
     202:     static FILE *fp;
     203:     char ans[10];
     204:     struct stat stbuf;
     205:
     206:     if (!nowarn) {
     207:         if (!access(target, 0)) {
     208:             /* CONSTCOND */
     209:             while (1) {
     210:                 printf("File \"%s\" exists, overwrite (y/n) ? ", target);
     211:                 gets(ans);
     212:                 if (ans[0] == 'n' || ans[0] == 'N')
     213:                     return(NULL);
     214:                 if (ans[0] == 'y' || ans[0] == 'Y')
     215:                     break;
     216:             }
     217:                     /* sanity checking */
     218:             if (!stat(target, &stbuf)) {
     219:                 if ((stbuf.st_mode & S_IFREG) != S_IFREG) {
     220:                     fprintf(stderr, "\"%s\" is not a regular file\n", target);
     221:                     return(NULL);
     222:                 }
     223:             }
     224:         }
     225:     }
     226:
     227:     if (!(fp = fopen(target, "w"))) {
     228:         fprintf(stderr, "Can't open \"%s\" for write\n", target);
     229:         return(NULL);
     230:     }
     231:     return(fp);
     232: }
     233:
     234: /*
     235:  * Convert an MSDOS time & date stamp to the Unix time() format
     236:  */
     237:
     238: static long
     239: conv_stamp(time_field, date_field)
     240: unsigned char *time_field, *date_field;
     241: {
     242: #ifdef BSD
     243:     struct timeval tv;
     244:     struct timezone tz;
     245: #else /* BSD */
     246:     extern long timezone;
     247:     void tzset();
     248: #endif /* BSD */
     249:     struct tm *tmbuf, *localtime();
     250:     int year, mon, mday, hour, min, sec, old_leaps;
     251:     long answer, sec_year, sec_mon, sec_mday, sec_hour, sec_min, sec_leap;
     252:     long tzone, dst;
     253:     static int month[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304,
     254:     334};
     255:                     /* dissect the parts */
     256:     year = (date_field[1] >> 1) + 1980;
     257:     mon = (((date_field[1] & 0x1) << 3) + (date_field[0] >> 5));
     258:     mday = date_field[0] & 0x1f;
     259:     hour = time_field[1] >> 3;
     260:     min = (((time_field[1] & 0x7) << 3) + (time_field[0] >> 5));
     261:     sec = (time_field[0] & 0x1f) * 2;
     262:                     /* how many previous leap years */
     263:     old_leaps = (year - 1972) / 4L;
     264:     sec_leap = old_leaps * 24L * 60L * 60L;
     265:                     /* back off 1 day if before 29 Feb */
     266:     if (!(year % 4) && mon < 3)
     267:         sec_leap -= 24L * 60L * 60L;
     268:     sec_year = (year - 1970) * 365L * 24L * 60L * 60L;
     269:     sec_mon = month[mon - 1] * 24L * 60L * 60L;
     270:     sec_mday = mday * 24L * 60L * 60L;
     271:     sec_hour = hour * 60L * 60L;
     272:     sec_min = min * 60L;
     273:                     /* correct for Time Zone */
     274: #ifdef BSD
     275:     gettimeofday(&tv, &tz);
     276:     tzone = tz.tz_minuteswest * 60L;
     277: #else /* BSD */
     278:     tzset();
     279:     tzone = timezone;
     280: #endif /* BSD */
     281:
     282:     answer = sec_leap + sec_year + sec_mon + sec_mday + sec_hour + sec_min + sec + tzone;
     283:                     /* correct for Daylight Saving Time */
     284:     tmbuf = localtime(&answer);
     285:     dst = (tmbuf->tm_isdst) ? (-60L * 60L) : 0L;
     286:     answer += dst;
     287:
     288:     return(answer);
     289: }
     290:
     291: /*
     292:  * Preserve the file modification times after the fclose()
     293:  */
     294:
     295: static void
     296: set_mtime(target, mtime)
     297: char *target;
     298: long mtime;
     299: {
     300: #ifdef BSD
     301:     struct timeval tv[2];
     302:
     303:     if (mtime != 0L) {
     304:         tv[0].tv_sec = mtime;
     305:         tv[0].tv_usec = 0;
     306:         tv[1].tv_sec = mtime;
     307:         tv[1].tv_usec = 0;
     308:         utimes(target, tv);
     309:     }
     310: #else /* BSD */
     311:     struct {
     312:         time_t actime;
     313:         time_t modtime;
     314:     } utbuf;
     315:
     316:     if (mtime != 0L) {
     317:         utbuf.actime = mtime;
     318:         utbuf.modtime = mtime;
     319:         utime(target, &utbuf);
     320:     }
     321: #endif /* BSD */
     322:     return;
     323: }
     324:
     325: /*
     326:  * stubs for read-only programs
     327:  */
     328:
     329: void
     330: disk_flush()
     331: {
     332:     extern int disk_dirty;
     333:
     334:     disk_dirty = 0;
     335:     return;
     336: }
     337:
     338: void
     339: dir_flush()
     340: {
     341:     extern int dir_dirty;
     342:
     343:     dir_dirty = 0;
     344:     return;
     345: }

#### Defined functions

conv_stamp defined in line 238; used 3 times

- in line 35, 135, 156

dir_flush defined in line 338; never used
disk_flush defined in line 329; never used
main defined in line 37; never used
open_file defined in line 197; used 3 times

- in line 34, 138, 171

set_mtime defined in line 295; used 3 times

- in line 33, 144, 177

#### Defined variables

clus_size defined in line 29; never used
dir_entries defined in line 28; used 1 times

- in line 115

dir_len defined in line 27; never used
dir_start defined in line 26; never used
fat_error defined in line 31; used 1 times

- in line 183

fd defined in line 25; used 1 times

- in line 189

mcwd defined in line 30; used 1 times

- in line 85

#### Defined macros

LOWERCASE defined in line 11; used 1 times

- in line 160

Last modified: 1992-06-24 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1031 |