]> andersk Git - moira.git/blob - gen/tar.c
Command line printer manipulation client, and build goo.
[moira.git] / gen / tar.c
1 /* $Id$
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
19 RCSID("$Header$");
20
21 static char tar_zeros[512];
22
23 TARFILE *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
44 void 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
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)
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
95 void 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
123 err:
124   perror("could not finish tarfile entry");
125   exit(MR_OCONFIG);
126 }
127
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)
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 }
This page took 0.265559 seconds and 5 git commands to generate.