]>
git.ipfire.org Git - ipfire-2.x.git/blob - src/misc-progs/installpackage.c
1 /* This file is part of the IPCop Firewall.
3 * This program is distributed under the terms of the GNU General Public
4 * Licence. See the file COPYING for details.
6 * Copyright (C) 2004-05-31 Robert Kerr <rkerr@go.to>
8 * Loosely based on the smoothwall helper program by the same name,
9 * portions are (c) Lawrence Manning, 2001
11 * $Id: installpackage.c,v 1.3.2.6 2005/08/22 20:51:38 eoberlander Exp $
31 #define ERR_PACKLIST 6
32 #define ERR_INSTALLED 7
35 #define ERR_MISSING_PREVIOUS 10
38 /* The lines in the package information file and the patches/installed list
39 * are often longer than STRING_SIZE so we use a larger buffer */
40 #define BUFFER_SIZE 4096
43 FILE *infofile
= NULL
;
44 char command
[STRING_SIZE
], tmpdir
[] = "/var/log/pat_install_XXXXXX";
45 void exithandler(void)
50 flock(fileno(infofile
), LOCK_UN
);
54 chdir("/var/patches"); /* get out of it before erasing */
55 snprintf(command
, STRING_SIZE
- 1, "/bin/rm -rf %s", tmpdir
);
56 if(safe_system(command
))
57 perror("Couldn't remove temp dir");
60 int main(int argc
, char *argv
[])
62 char buffer
[BUFFER_SIZE
];
69 /* Sanitize arguments */
72 fprintf(stderr
, "Missing arg\n");
75 if (strspn(argv
[1], NUMBERS
) != strlen(argv
[1]))
77 fprintf(stderr
, "Bad arg\n");
83 perror("Unable to create secure temp dir");
87 /* now exithandler will have something to erase */
90 /* verify and extract package */
91 memset(command
, 0, STRING_SIZE
);
92 snprintf(command
, STRING_SIZE
-1, "/usr/bin/gpg --batch --homedir /root/.gnupg -o %s/patch.tar.gz --decrypt /var/patches/patch-%s.tar.gz.gpg", tmpdir
, argv
[1]);
93 ret
= safe_system(command
) >> 8;
94 if(ret
==1) /* 1=> gpg-key error */
96 fprintf(stderr
, "Invalid package: signature check failed\n");
99 if(ret
==2) /* 2=> gpg pub key not found */
101 fprintf(stderr
, "Public signature not found (who signed package?) !\n");
104 if(ret
) /* retry extraction on other partition */
107 strcpy (tmpdir
,"/var/patches/install_XXXXXX");
110 perror("Unable to create secure temp dir");
111 _exit(ERR_TMPDIR
); /* no need exit handler */
113 memset(command
, 0, STRING_SIZE
);
114 snprintf(command
, STRING_SIZE
-1, "/usr/bin/gpg --batch --homedir /root/.gnupg -o %s/patch.tar.gz --decrypt /var/patches/patch-%s.tar.gz.gpg", tmpdir
, argv
[1]);
115 ret
= safe_system(command
);
118 fprintf(stderr
, "Not enough disk space or gpg error %d !\n",ret
);
122 /* no more needed gpg-package & make room */
123 snprintf(command
, STRING_SIZE
-1, "/var/patches/patch-%s.tar.gz.gpg", argv
[1]);
126 /* unzip the package */
128 if(safe_system("/bin/tar xzf patch.tar.gz"))
130 fprintf(stderr
, "Invalid package: untar failed\n");
133 /* And read 'information' to check validity */
134 snprintf(buffer
, STRING_SIZE
-1, "%s/information", tmpdir
);
135 if(!(infofile
= fopen(buffer
,"r")))
138 fprintf(stderr
, "Invalid package: contains no information file\n");
140 perror("Unable to open package information file");
143 if(!fgets(buffer
, BUFFER_SIZE
, infofile
))
145 perror("Couldn't read package information");
149 if(buffer
[strlen(buffer
)-1] == '\n')
150 buffer
[strlen(buffer
)-1] = '\0';
151 if(!strchr(buffer
,'|'))
153 fprintf(stderr
, "Invalid package: malformed information string.\n");
156 info
= strdup(buffer
);
158 /* check if package is already installed */
159 if(!(infofile
= fopen(CONFIG_ROOT
"/patches/installed","r+")))
161 perror("Unable to open installed package list");
164 /* get exclusive lock to prevent a mess if 2 copies run at once, and set
165 * close-on-exec flag so the FD doesn't leak to the setup script */
166 flock(fileno(infofile
), LOCK_EX
);
167 fcntl(fileno(infofile
), F_SETFD
, FD_CLOEXEC
);
169 while(fgets(buffer
, BUFFER_SIZE
, infofile
))
171 if(!strncmp(buffer
, info
, strlen(info
)))
173 fprintf(stderr
,"This package is already installed\n");
178 /* install package */
179 openlog("installpackage", LOG_PID
, LOG_USER
);
180 snprintf(command
, STRING_SIZE
- 1, "%s/setup", tmpdir
);
181 /* FIXME: popen suffers from the same environment problems as system() */
182 if (!(p
= popen(command
, "r")))
184 fprintf(stderr
,"popen() failed\n");
188 setvbuf(p
, NULL
, _IOLBF
, 255);
189 while (fgets(buffer
, STRING_SIZE
, p
))
191 syslog(LOG_INFO
, "%s", buffer
);
198 fprintf(stderr
, "setup script returned exit code %d\n", ret
>>8);
202 /* write to package db */
203 if(strncmp(info
, "000|", 4))
205 time_t curtime
= time(NULL
);
206 strftime(buffer
, STRING_SIZE
, "%Y-%m-%d", gmtime(&curtime
));
207 fprintf(infofile
, "%s|%s\n", info
, buffer
);
208 flock(fileno(infofile
), LOCK_UN
);
210 } else { /* Full system upgrade to new version */
211 flock(fileno(infofile
), LOCK_UN
);
213 unlink(CONFIG_ROOT
"/patches/available");
214 unlink(CONFIG_ROOT
"/patches/installed");