3 * Utility routines for writing tar files.
5 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
10 #include <mit-copyright.h>
12 #include <moira_site.h>
21 static char tar_zeros[512];
23 TARFILE *tarfile_open(char *file)
27 tf = malloc(sizeof(TARFILE));
30 perror("couldn't open tarfile");
34 tf->fp = fopen(file, "w");
37 perror("couldn't open tarfile");
44 void tarfile_close(TARFILE *tf)
49 offset = ftell(tf->fp);
50 /* The tar file must have two empty 512-byte blocks at the end, and
51 * then must be padded to a multiple of 20 512-byte blocks. This
52 * calculates how many blocks to add.
54 blocks = (20 - ((offset / 512) + 2) % 20) + 2;
58 if (fwrite(tar_zeros, 512, 1, tf->fp) != 1)
60 perror("could not write last tarfile block");
69 FILE *tarfile_start(TARFILE *tf, char *name, mode_t mode, uid_t uid, gid_t gid,
70 char *user, char *group, time_t mtime)
72 memset(&(tf->th), 0, sizeof(tf->th));
73 memset(tf->th.chksum, ' ', sizeof(tf->th.chksum));
74 strcpy(tf->th.name, (name[0] == '/' ? name + 1 : name));
75 sprintf(tf->th.mode, "%07lo", (unsigned long)mode);
76 sprintf(tf->th.uid, "%07lo", (unsigned long)uid);
77 sprintf(tf->th.gid, "%07lo", (unsigned long)gid);
78 sprintf(tf->th.mtime, "%011lo", (unsigned long)mtime);
79 tf->th.typeflag[0] = '0';
80 sprintf(tf->th.magic, "ustar");
81 sprintf(tf->th.version, "00");
82 sprintf(tf->th.uname, "%.32s", user);
83 sprintf(tf->th.gname, "%.32s", group);
85 tf->offset = ftell(tf->fp);
87 if (fwrite(&(tf->th), sizeof(tf->th), 1, tf->fp) != 1)
89 perror("could not write tarfile header");
95 void tarfile_end(TARFILE *tf)
97 long offset = ftell(tf->fp);
102 size = offset - tf->offset;
105 if (fwrite(tar_zeros, 512 - (size % 512), 1, tf->fp) != 1)
108 sprintf(tf->th.size, "%011lo", size - 512);
110 for (p = (char *)&(tf->th); p < (char *)(&(tf->th) + 1); p++)
111 chksum += (unsigned char)*p;
112 sprintf(tf->th.chksum, "%07lo", chksum);
114 if (fseek(tf->fp, tf->offset, SEEK_SET))
116 if (fwrite(&(tf->th), sizeof(tf->th), 1, tf->fp) != 1)
118 if (fseek(tf->fp, 0, SEEK_END))
124 perror("could not finish tarfile entry");
128 void tarfile_mkdir(TARFILE *tf, char *name, mode_t mode, uid_t uid, gid_t gid,
129 char *user, char *group, time_t mtime)
135 memset(&th, 0, sizeof(th));
136 memset(th.chksum, ' ', sizeof(th.chksum));
137 strcpy(th.name, name);
138 sprintf(th.mode, "%07lo", (unsigned long)mode);
139 sprintf(th.uid, "%07lo", (unsigned long)uid);
140 sprintf(th.gid, "%07lo", (unsigned long)gid);
141 sprintf(th.size, "%011lo", (unsigned long)0);
142 sprintf(th.mtime, "%011lo", (unsigned long)mtime);
143 th.typeflag[0] = '5';
144 sprintf(th.magic, "ustar");
145 sprintf(th.version, "00");
146 sprintf(th.uname, "%.32s", user);
147 sprintf(th.gname, "%.32s", group);
149 for (p = (char *)&th; p < (char *)(&th + 1); p++)
150 chksum += (unsigned char)*p;
151 sprintf(th.chksum, "%07lo", chksum);
153 if (fwrite(&th, sizeof(th), 1, tf->fp) != 1)
155 perror("could not write tarfile header");