writeRPM can now copy cpio archive from fd.
[platform/upstream/rpm.git] / build.c
1 #include "system.h"
2 #include "build/rpmbuild.h"
3 #include "build.h"
4 #include "intl.h"
5
6 int buildplatform(char *arg, int buildAmount, char *passPhrase,
7                  char *buildRoot, int fromTarball, int test, char *cookie);
8
9 int buildplatform(char *arg, int buildAmount, char *passPhrase,
10                  char *buildRoot, int fromTarball, int test, char *cookie)
11 {
12
13     FILE *f;
14     char * specfile;
15     int res = 0;
16     struct stat statbuf;
17     char * specDir;
18     char * tmpSpecFile;
19     char * cmd;
20     char * s;
21     int count, fd;
22     char buf[BUFSIZ];
23     Spec spec = NULL;
24
25     if (fromTarball) {
26         specDir = rpmGetVar(RPMVAR_SPECDIR);
27         tmpSpecFile = alloca(BUFSIZ);
28         sprintf(tmpSpecFile, "%s/rpm-spec-file-%d", specDir, (int) getpid());
29
30         cmd = alloca(strlen(arg) + 50 + strlen(tmpSpecFile));
31         sprintf(cmd, "gunzip < %s | tar xOvf - Specfile 2>&1 > %s", arg,
32                         tmpSpecFile);
33         if (!(f = popen(cmd, "r"))) {
34             fprintf(stderr, _("Failed to open tar pipe: %s\n"), 
35                         strerror(errno));
36             return 1;
37         }
38         if ((!fgets(buf, sizeof(buf) - 1, f)) || !strchr(buf, '/')) {
39             /* Try again */
40             pclose(f);
41
42             sprintf(cmd, "gunzip < %s | tar xOvf - \\*.spec 2>&1 > %s", arg,
43                     tmpSpecFile);
44             if (!(f = popen(cmd, "r"))) {
45                 fprintf(stderr, _("Failed to open tar pipe: %s\n"), 
46                         strerror(errno));
47                 return 1;
48             }
49             if (!fgets(buf, sizeof(buf) - 1, f)) {
50                 /* Give up */
51                 fprintf(stderr, _("Failed to read spec file from %s\n"), arg);
52                 unlink(tmpSpecFile);
53                 return 1;
54             }
55         }
56         pclose(f);
57
58         cmd = specfile = buf;
59         while (*cmd) {
60             if (*cmd == '/') specfile = cmd + 1;
61             cmd++;
62         }
63
64         cmd = specfile;
65
66         /* remove trailing \n */
67         specfile = cmd + strlen(cmd) - 1;
68         *specfile = '\0';
69
70         specfile = alloca(strlen(specDir) + strlen(cmd) + 5);
71         sprintf(specfile, "%s/%s", specDir, cmd);
72         
73         if (rename(tmpSpecFile, specfile)) {
74             fprintf(stderr, _("Failed to rename %s to %s: %s\n"),
75                     tmpSpecFile, specfile, strerror(errno));
76             unlink(tmpSpecFile);
77             return 1;
78         }
79
80         /* Make the directory which contains the tarball the source 
81            directory for this run */
82
83         if (*arg != '/') {
84             getcwd(buf, BUFSIZ);
85             strcat(buf, "/");
86             strcat(buf, arg);
87         } else 
88             strcpy(buf, arg);
89
90         cmd = buf + strlen(buf) - 1;
91         while (*cmd != '/') cmd--;
92         *cmd = '\0';
93
94         rpmSetVar(RPMVAR_SOURCEDIR, buf);
95     } else if (arg[0] == '/') {
96         specfile = arg;
97     } else {
98         specfile = alloca(BUFSIZ);
99         getcwd(specfile, BUFSIZ);
100         strcat(specfile, "/");
101         strcat(specfile, arg);
102     }
103
104     stat(specfile, &statbuf);
105     if (! S_ISREG(statbuf.st_mode)) {
106         fprintf(stderr, _("File is not a regular file: %s\n"), specfile);
107         return 1;
108     }
109     
110     if ((fd = open(specfile, O_RDONLY)) < 0) {
111         fprintf(stderr, _("Unable to open spec file: %s\n"), specfile);
112         return 1;
113     }
114     count = read(fd, buf, sizeof(buf) < 128 ? sizeof(buf) : 128);
115     close(fd);
116     s = buf;
117     while(count--) {
118         if (! (isprint(*s) || isspace(*s))) {
119             fprintf(stderr, _("File contains non-printable characters(%c): %s\n"), *s,
120                     specfile);
121             return 1;
122         }
123         s++;
124     }
125
126     if (parseSpec(&spec, specfile, buildRoot, 0, passPhrase, cookie)) {
127         return 1;
128     }
129
130     if (buildSpec(spec, buildAmount, test)) {
131         freeSpec(spec);
132         return 1;
133     }
134     
135     if (fromTarball) unlink(specfile);
136
137     freeSpec(spec);
138     
139     return res;
140 }
141
142 int build(char *arg, int buildAmount, char *passPhrase,
143                  char *buildRoot, int fromTarball, int test, char *cookie,
144                  char * rcfile, char * arch, char * os, 
145                  char *buildplatforms)
146 {
147     char * platform;
148     int rc;
149
150     /* parse up the build operators */
151
152     printf("building these platforms: %s\n", buildplatforms);
153
154     if (buildplatforms == NULL) {
155         rc =  buildplatform(arg, buildAmount, passPhrase, buildRoot,
156                 fromTarball, test, cookie);
157         return rc;
158     }
159
160     while((platform = strsep(&buildplatforms,",")) != NULL) {
161         printf("building %s\n", platform);
162
163         rpmSetVar(RPMVAR_BUILDPLATFORM,platform);
164         rpmReadConfigFiles(rcfile, arch, os, 1, platform);
165         rc = buildplatform(arg, buildAmount, passPhrase, buildRoot,
166             fromTarball, test, cookie);
167         if (rc)
168             return rc;
169     }
170
171     return 0;
172 }