]> andersk Git - moira.git/blame - gen/tar.c
Command line printer manipulation client, and build goo.
[moira.git] / gen / tar.c
CommitLineData
39a48122 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
19RCSID("$Header$");
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));
22702973 74 strcpy(tf->th.name, (name[0] == '/' ? name + 1 : name));
39a48122 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}
This page took 0.190714 seconds and 5 git commands to generate.