source: trunk/third/moira/gen/tar.c @ 23740

Revision 23740, 3.8 KB checked in by broder, 16 years ago (diff)
In moira: * New CVS snapshot (Trac: #195) * Drop patches that have been incorporated upstream. * Update to build without krb4 on systems that no longer have it. This doesn't build yet on squeeze, which lacks a krb4 library, but I'm committing now before I start hacking away at a patch to fix that.
Line 
1/* $Id: tar.c,v 1.2 1999-07-12 16:27:56 danw Exp $
2 *
3 * Utility routines for writing tar files.
4 *
5 * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
6 * For copying and distribution information, please see the file
7 * <mit-copyright.h>.
8 */
9
10#include <mit-copyright.h>
11#include <moira.h>
12#include <moira_site.h>
13
14#include <stdio.h>
15#include <stdlib.h>
16
17#include "util.h"
18
19RCSID("$Header: /afs/athena.mit.edu/astaff/project/moiradev/repository/moira/gen/tar.c,v 1.2 1999-07-12 16:27:56 danw Exp $");
20
21static char tar_zeros[512];
22
23TARFILE *tarfile_open(char *file)
24{
25  TARFILE *tf;
26
27  tf = malloc(sizeof(TARFILE));
28  if (!tf)
29    {
30      perror("couldn't open tarfile");
31      exit(MR_OCONFIG);
32    }
33
34  tf->fp = fopen(file, "w");
35  if (!tf->fp)
36    {
37      perror("couldn't open tarfile");
38      exit(MR_OCONFIG);
39    }
40
41  return tf;
42}
43
44void tarfile_close(TARFILE *tf)
45{
46  long offset;
47  int blocks;
48
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.
53   */
54  blocks = (20 - ((offset / 512) + 2) % 20) + 2;
55
56  while (blocks--)
57    {
58      if (fwrite(tar_zeros, 512, 1, tf->fp) != 1)
59        {
60          perror("could not write last tarfile block");
61          exit(MR_OCONFIG);
62        }
63    }
64
65  fclose(tf->fp);
66  free(tf);
67}
68
69FILE *tarfile_start(TARFILE *tf, char *name, mode_t mode, uid_t uid, gid_t gid,
70                    char *user, char *group, time_t mtime)
71{
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);
84
85  tf->offset = ftell(tf->fp);
86
87  if (fwrite(&(tf->th), sizeof(tf->th), 1, tf->fp) != 1)
88    {
89      perror("could not write tarfile header");
90      exit(MR_OCONFIG);
91    }
92  return tf->fp;
93}
94
95void tarfile_end(TARFILE *tf)
96{
97  long offset = ftell(tf->fp);
98  unsigned long size;
99  int chksum = 0;
100  char *p;
101
102  size = offset - tf->offset;
103  if (size % 512)
104    {
105      if (fwrite(tar_zeros, 512 - (size % 512), 1, tf->fp) != 1)
106        goto err;
107    }
108  sprintf(tf->th.size, "%011lo", size - 512);
109
110  for (p = (char *)&(tf->th); p < (char *)(&(tf->th) + 1); p++)
111    chksum += (unsigned char)*p;
112  sprintf(tf->th.chksum, "%07lo", chksum);
113
114  if (fseek(tf->fp, tf->offset, SEEK_SET))
115    goto err;
116  if (fwrite(&(tf->th), sizeof(tf->th), 1, tf->fp) != 1)
117    goto err;
118  if (fseek(tf->fp, 0, SEEK_END))
119    goto err;
120
121  return;
122
123err:
124  perror("could not finish tarfile entry");
125  exit(MR_OCONFIG);
126}
127
128void tarfile_mkdir(TARFILE *tf, char *name, mode_t mode, uid_t uid, gid_t gid,
129                   char *user, char *group, time_t mtime)
130{
131  struct tarheader th;
132  char *p;
133  int chksum = 0;
134
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);
148
149  for (p = (char *)&th; p < (char *)(&th + 1); p++)
150    chksum += (unsigned char)*p;
151  sprintf(th.chksum, "%07lo", chksum);
152
153  if (fwrite(&th, sizeof(th), 1, tf->fp) != 1)
154    {
155      perror("could not write tarfile header");
156      exit(MR_OCONFIG);
157    }
158}
Note: See TracBrowser for help on using the repository browser.