Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.installer / org.gvsig.desktop.selfextract.darwin / selfextract.c @ 44164

History | View | Annotate | Download (5.43 KB)

1 42893 jjdelcerro
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
#include <sys/types.h>
6
#include <sys/stat.h>
7
#include <fcntl.h>
8
#include <unistd.h>
9
#include "libtar.h"
10
#include <errno.h>
11
#include <dirent.h>
12
13
14
int remove_directory(const char *path) {
15
  DIR *d = opendir(path);
16
  size_t path_len = strlen(path);
17
  int r = -1;
18
19
  if (d != NULL ) {
20
    struct dirent *p;
21
    r = 0;
22
    while (!r && (p=readdir(d))) {
23
      int r2 = -1;
24
      char *buf;
25
      size_t len;
26
27
      /* Skip the names "." and ".." as we don't want to recurse on them. */
28
      if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) {
29
          continue;
30
      }
31
      len = path_len + strlen(p->d_name) + 2;
32
      buf = malloc(len);
33
      if (buf) {
34
        struct stat statbuf;
35
        snprintf(buf, len, "%s/%s", path, p->d_name);
36
        if (!stat(buf, &statbuf)) {
37
          if (S_ISDIR(statbuf.st_mode)) {
38
              r2 = remove_directory(buf);
39
          } else {
40
              r2 = unlink(buf);
41
          }
42
        }
43
        free(buf);
44
      }
45
      r = r2;
46
    }
47
    closedir(d);
48
  }
49
  if (!r) {
50
    r = rmdir(path);
51
  }
52
  return r;
53
}
54
55
56
char *getMark() {
57
  static char buffer[100];
58
59
  strcpy(buffer, ";!@self");
60
  strcat(buffer,"extract@!\n");
61
  return buffer;
62
}
63
64
int findMark(int fd) {
65
  static char buffer[1024*50];
66
67
  int x=lseek(fd,0,SEEK_SET);
68
  if( x<0 ) {
69
    printf("seek 0 error\n");
70
    return -1;
71
  }
72
  x=read(fd,buffer,1024*50);
73
  if( x<0 ) {
74
    printf("read error\n");
75
    return -1;
76
  }
77
  char *mark = getMark();
78
  int markSize = strlen(mark);
79
  char *p;
80
  for( p=buffer ; p<buffer+x; p++ ) {
81
    if( strncmp(p,mark,markSize)==0 ) {
82
      int n = p-buffer + markSize;
83
      printf("found %d\n", n);
84
      return n;
85
    }
86
  }
87
  printf("not found\n");
88
  return -1;
89
}
90
91
void extract(char *source) {
92
  static char path[1024];
93
  static char folder[1024];
94
  TAR *tar;
95
  int start,x;
96
97
98
  x = tar_open(&tar, source, 0, O_RDONLY, 0, 0);
99
  if( x <0 ) {
100
    fprintf(stderr,"Can 't extract from '%s', don't create tar object.\n", source);
101
    perror(NULL);
102
    exit(1);
103
  }
104
105
  int fdi = tar_fd(tar);
106
  start = findMark(fdi);
107
  if( start <0 ) {
108
    fprintf(stderr,"Can 't extract from '%s', don't find position of tar start.\n", source);
109
    perror(NULL);
110
    exit(3);
111
  }
112
  x = lseek(fdi,start,SEEK_SET);
113
  if( x <0 ) {
114
    fprintf(stderr,"Can 't extract from '%s', don't seek at position of tar start.\n", source);
115
    perror(NULL);
116
    exit(4);
117
  }
118
119
  sprintf(folder,"/tmp/selfextract-%d", getpid());
120
  printf("Extracting to %s...\n", folder);
121
  x = tar_extract_all(tar, folder);
122
  if( x <0 ) {
123
    fprintf(stderr,"Can 't extract from '%s', output folder '%s'.\n", source, folder);
124
    perror(NULL);
125
    exit(5);
126
  }
127
  tar_close(tar);
128
129
  sprintf(path,"%s/autorun.sh", folder);
130
  if( access(path,R_OK)<0 ) {
131
    fprintf(stderr,"Can 't extract from '%s', don't access to '%s'.\n", source, path);
132
    exit(6);
133
  }
134
  if( chdir(folder)<0 ) {
135
    fprintf(stderr,"Can 't extract from '%s', don't change current folder to '%s'.\n", source, folder);
136
    exit(7);
137
  }
138
  printf("Executing autorun.sh...\n");
139
  x = system(path);
140
  if( x <0 ) {
141
    fprintf(stderr,"Can 't extract from '%s', execute '%s' fail.\n", source, path);
142
    perror(NULL);
143
    exit(8);
144
  }
145
  printf("Removing %s...\n", folder);
146
  remove_directory(folder);
147
  printf("Finish\n");
148
  exit(0);
149
}
150
151
void create(char *source,char *target, char *tarfile) {
152
  static char buffer[1024];
153
  int size;
154
  int n,x;
155
156
  int fdo = creat(target,S_IWUSR|S_IXUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH);
157
  if( fdo <0 ) {
158
    fprintf(stderr,"Can't create '%s'.\n", target);
159
    perror(NULL);
160
    exit(20);
161
  }
162
  int fdi = open(source,O_RDONLY);
163
  if( fdo <0 ) {
164
    fprintf(stderr,"Can't create '%s', don't open header file '%s'.\n", target, source);
165
    perror(NULL);
166
    exit(21);
167
  }
168
169
  while( (n=read(fdi,buffer,1024)) != 0 ) {
170
    if( n<0 ) {
171
      fprintf(stderr,"Can't create '%s', don't read file '%s'.\n", target, source);
172
      perror(NULL);
173
      exit(24);
174
    }
175
    x=write(fdo,buffer,n);
176
    if( x!=n ) {
177
      fprintf(stderr,"Can't create '%s', don't add '%s' to end of file.\n", target, source);
178
      perror(NULL);
179
      exit(25);
180
    }
181
  }
182
  close(fdi);
183
184
  char *mark = getMark();
185
  x=write(fdo,mark,strlen(mark));
186
  if( x!=strlen(mark) ) {
187
    fprintf(stderr,"Can't create '%s', magic to end of file.\n", target);
188
    perror(NULL);
189
    exit(26);
190
  }
191
192
  fdi = open(tarfile,O_RDONLY);
193
  if( fdi<0 ) {
194
    fprintf(stderr,"Can't create '%s', don't open file '%s'.\n", target, tarfile);
195
    perror(NULL);
196
    exit(27);
197
  }
198
  while( (n=read(fdi,buffer,1024)) != 0 ) {
199
    if( n<0 ) {
200
      fprintf(stderr,"Can't create '%s', don't read file '%s'.\n", target, tarfile);
201
      perror(NULL);
202
      exit(28);
203
    }
204
    x=write(fdo,buffer,n);
205
    if( x!=n ) {
206
      fprintf(stderr,"Can't create '%s', don't add '%s' to end of file.\n", target, tarfile);
207
      perror(NULL);
208
      exit(29);
209
    }
210
  }
211
  close(fdi);
212
213
  close(fdo);
214
  exit(0);
215
}
216
217
int main(int argc, char*argv[]) {
218
219
  if( argc==2 && ( strcmp(argv[1], "--help")==0 || strcmp(argv[1], "--h")==0 || strcmp(argv[1], "-?")==0 ) ) {
220
    fprintf(stderr,"Usage:\n%s --create target tarfile\n    Create a selfextracting target file with the tarfile indicated.\n%s --help|-h|-?\n    Show this usage\n%s\n    Extract in /tmp/selfextract-PID the tar file and execute the autorun.sh file\n", argv[0], argv[0], argv[0]);
221
    exit(-1);
222
  }
223
  if( argc==4 && strcmp(argv[1], "--create")==0 ) {
224
    create(argv[0], argv[2],argv[3]);
225
    return 0;
226
  }
227
  extract(argv[0]);
228
}