]> pd.if.org Git - zpackage/blob - lib/zpm.c
add better error reporting for invalid import file types
[zpackage] / lib / zpm.c
1 #define _POSIX_C_SOURCE 200809L
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <sys/mman.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 #include <errno.h>
12
13 #include "zpm.h"
14
15 #include "sha256.h"
16
17 #if 0
18 struct zpm {
19         sqlite3 *db;
20         char *path; /* path to package file */
21         char *version;
22         int release;
23         char *pkgname;
24         time_t installed; /* install time, 0 for not installed */
25 };
26
27 struct zpm_file {
28         char *path;
29         int mode;
30         uint32_t filetype;
31         char *tags;
32         char *owner;
33         char *group;
34         char *hash; /* could be fixed length */
35         time_t mtime;
36         struct zpm_file *next; /* so you can make a linked list */
37 };
38
39 /* NULL?  Create? */
40 /* associate with a package ? if only one?  first? */
41 int zpm_open(struct zpm *pkg, char *path);
42 int zpm_pkgname(char *base, char *version, int release); /* construct a package file name */
43
44 /* flags for preserving mode, owner, etc */
45 /* puts hash of import in hash */
46 /* path can be a hash, with an "INTERNAL" flag, i.e. internally import */
47 #define ZPM_MODE 0x1
48 #define ZPM_OWNER 0x2
49 #define ZPM_MTIME 0x4
50 #define ZPM_INTERNAL 0x8
51 #define ZPM_NOBLOB 0x10
52 /* don't run scripts on install */
53 #define ZPM_NOSCRIPTS 0x10
54 /* don't associate the file with a package, just do a raw insert */
55 /* otherwise, associate it with the current package */
56 #define ZPM_NOPACKAGE 0x20
57
58 int zpm_import(struct zpm *zp, char *path, uint32_t flags, uint8_t *hash);
59
60 /* link and unlink hashes to packages */
61 int zpm_link(struct zpm *pkg, char *path, char *hash, struct zpm_file *fileinfo);
62 int zpm_unlink(struct zpm *pkg, char *path);
63
64 /* tag a file.  relative to "current package" */
65 int zpm_tag(struct zpm *zp, char *path, char *tags);
66 /* should this be broken up into separage functions ? */
67 int zpm_md(struct zpm *zp, char *path, int mode, char *owner, char *group, time_t mtime);
68
69 /* export hash to dest */
70 int zpm_extract(struct zpm *pkg, char *hash, char *path, int mode);
71
72 /* export path to dest */
73 int zpm_export(struct zpm *zp, char *path, uint32_t flags, char *dest);
74
75 int zpm_close(struct zpm *zp);
76
77 /* attach a signature to a package */
78 int zpm_sign(struct zpm *z, size_t s, void *signature);
79
80 /* set the package info to the nth package, -1 to return count? */
81 /* further import/exports and such will be relative to this package */
82 int zpm_package(struct zpm *zp, int n);
83
84 /* get file information */
85 int zpm_stat(struct zpm *z, struct zpm_file *f, int n);
86
87 /* will also set the package context to the new package */
88 int zpm_newpkg(struct zpm *z, char *base, char *version, int release);
89
90 /* transactions */
91 int zpm_begin(struct zpm *z);
92 int zpm_commit(struct zpm *z);
93 int zpm_rollback(struct zpm *z);
94
95 /* higher level operations */
96
97 /* install or uninstall the package */
98 /* flag for keeping the blobs in local */
99 /* what about tag filtering */
100 int zpm_install(struct zpm *z, struct zpm *local, uint32_t flags);
101 int zpm_uninstall(struct zpm *local);
102
103 /* slurp up the actual blobs */
104 /* what about versioning them if they change */
105 int zpm_preserve(struct zpm *local);
106
107 /* check file integrity */
108 int zpm_checkinstall(struct zpm *local);
109
110 int zpm_merge(struct zpm *z, struct zpm *src, uint32_t flags);
111
112 void uncompresslzma(void *buf, size_t bufsize, FILE *out);
113 #define SQLERROR(x) fprintf(stderr, "%s %d: %s\n", __func__, __LINE__, (x))
114 #endif
115
116 static char *dupstr(char *s) {
117         size_t n;
118         char *d;
119
120         n = strlen(s);
121         d = malloc(n+1);
122         if (d) {
123                 d = strcpy(d, s);
124         }
125         return d;
126 }
127
128 #if 0
129 int zpm_newpkg(struct zpm *z, char *base, char *version, int release) {
130         char *sql = "insert or ignore into packages (package,version,release) values (?,?,?)";
131         int rc;
132         sqlite3_stmt *ifile;
133
134         rc = sqlite3_prepare(db, sql, -1, &ifile,0);
135         if (rc != SQLITE_OK) {
136                 SQLERROR(sqlite3_errmsg(db));
137                 return 0;
138         }
139         rc = sqlite3_bind_text(ifile, 1, base, strlen(base), SQLITE_STATIC);
140         if (rc != SQLITE_OK) {
141                 SQLERROR(sqlite3_errmsg(db));
142                 fprintf(stderr, "cant bind package name\n");
143                 zpm_rollback(pkg);
144                 return 0;
145         }
146         sqlite3_bind_text(ifile, 2, version, strlen(version), SQLITE_STATIC);
147         sqlite3_bind_int(ifile, 3, release)
148
149         rc = sqlite3_step(ifile);
150
151         if (rc != SQLITE_DONE) {
152                 SQLERROR(sqlite3_errmsg(db));
153                 sqlite3_finalize(ifile);
154                 return 0;
155         }
156         sqlite3_finalize(ifile);
157         z->pkg = dupstr(base);
158         z->version = dupstr(version);
159         z->release = release;
160 }
161 #endif
162
163 int zpm_begin(struct zpm *z) {
164         char *errstr = 0;
165         sqlite3_exec(z->db, "begin;", NULL, NULL, &errstr);
166         if (errstr) {
167                 fprintf(stderr, "sqlite begin error: %s\n", errstr);
168                 sqlite3_free(errstr);
169                 return 0;
170         }
171         return 1;
172 }
173
174 int zpm_commit(struct zpm *z) {
175         char *errstr = 0;
176         sqlite3_exec(z->db, "commit;", NULL, NULL, &errstr);
177         if (errstr) {
178                 fprintf(stderr, "sqlite commit error: %s\n", errstr);
179                 sqlite3_free(errstr);
180                 return 0;
181         }
182         return 1;
183 }
184
185 int zpm_rollback(struct zpm *z) {
186         char *errstr = 0;
187         sqlite3_exec(z->db, "rollback;", NULL, NULL, &errstr);
188         if (errstr) {
189                 fprintf(stderr, "sqlite rollback error: %s\n", errstr);
190                 sqlite3_free(errstr);
191                 return 0;
192         }
193         return 1;
194 }
195
196 int zpm_db_set_pragma(struct zpm *db, int pragma, int value) {
197         int rc;
198         char *sql;
199         sqlite3_stmt *s;
200
201         switch (pragma) {
202                 case 1: sql = "pragma application_id = ?;"; break;
203                 case 2: sql = "pragma user_version = ?;"; break;
204                 default: return -1; break;
205         }
206
207         rc = sqlite3_prepare_v2(db->db, sql, -1, &s, 0);
208
209         if (rc != SQLITE_OK) {
210                 SQLERROR(sqlite3_errmsg(db->db));
211                 return -1;
212         }
213
214         sqlite3_bind_int(s, 1, value);
215         if (rc != SQLITE_OK) {
216                 SQLERROR(sqlite3_errmsg(db->db));
217                 fprintf(stderr, "cant bind pragma value\n");
218                 sqlite3_finalize(s);
219                 return -1;
220         }
221         rc = sqlite3_step(s);
222         if (rc != SQLITE_DONE) {
223                 SQLERROR(sqlite3_errmsg(db->db));
224                 fprintf(stderr, "cant set pragma\n");
225                 sqlite3_finalize(s);
226                 return -1;
227         }
228
229         sqlite3_finalize(s);
230         return value;
231 }
232
233 int zpm_db_pragma(struct zpm *db, int pragma) {
234         int rc;
235         int value = -1;
236         char *sql = 0;
237         sqlite3_stmt *s;
238
239         switch (pragma) {
240                 case 1: sql = "pragma application_id;"; break;
241                 case 2: sql = "pragma user_version;"; break;
242                 default: return -1; break;
243         }
244
245         rc = sqlite3_prepare_v2(db->db, sql, -1, &s, 0);
246
247         if (rc != SQLITE_OK) {
248                 SQLERROR(sqlite3_errmsg(db->db));
249                 fprintf(stderr, "%s, errnum = %d\n", sqlite3_errmsg(db->db), rc);
250                 /* TODO just abort? */
251                 return -1;
252         }
253
254         rc = sqlite3_step(s);
255         if (rc == SQLITE_ROW) {
256                 value = sqlite3_column_int(s, 0);
257         }
258
259         sqlite3_finalize(s);
260         return value;
261 }
262
263 static
264 #include "newdb.c"
265
266 int zpm_db_initialize(struct zpm *pkg) {
267         //fprintf(stderr, "initializing zpm database\n");
268         switch (sqlite3_exec(pkg->db, createdb, (int (*)(void *,int,char **,char **))0, NULL, NULL)) {
269                 case SQLITE_OK: break;
270                 default:
271                         SQLERROR(sqlite3_errmsg(pkg->db));
272                         return 0;
273                         break;
274         }
275         return 1;
276 }
277
278 /* NULL?  Create? */
279 int zpm_open(struct zpm *pkg, char *path) {
280         int rc;
281         char *errstr = 0;
282         sqlite3 *db = 0;
283         int appid, dbver;
284
285         pkg->db = 0;
286         pkg->path = 0;
287         pkg->version = 0;
288         pkg->release = 0;
289         pkg->pkgname = 0;
290         pkg->installed = 0;
291
292         rc = sqlite3_open(path, &db);
293         if (rc) {
294                 SQLERROR(sqlite3_errmsg(db));
295                 sqlite3_close(db);
296                 return 0;
297         }
298         pkg->db   = db;
299         pkg->path = dupstr(path);
300
301         appid = zpm_db_pragma(pkg, 1);
302         dbver = zpm_db_pragma(pkg, 2);
303
304         //fprintf(stderr, "db appid = %x, dbver = %d\n", appid, dbver);
305         switch (appid) {
306                 case 0: if (!zpm_db_initialize(pkg)) {
307                                 sqlite3_close(db);
308                                 return 1;
309                         };
310                         break;
311                 case 0x5a504442: break;
312                 default:
313                         fprintf(stderr, "unknown database type\n");
314                         sqlite3_close(db);
315                         return 0;
316                         break;
317         }
318         if (dbver > 1) {
319                 fprintf(stderr, "version %d zpm db detected, this program only works with version 1 databases\n", dbver);
320                         sqlite3_close(db);
321                         return 0;
322         }
323
324         sqlite3_exec(pkg->db, "pragma foreign_keys = ON;", NULL, NULL, &errstr);
325         if (errstr) {
326                 fprintf(stderr, "sqlite foreign key error: %s\n", errstr);
327                 sqlite3_free(errstr);
328                 sqlite3_close(db);
329                 return 0;
330         }
331
332
333         /* TODO if this is a new database, create structures */
334
335         /* get a package. what if more than one? what if none? */
336         return 1;
337 }
338
339 int zpm_close(struct zpm *pkg) {
340         if (pkg) {
341                 sqlite3_close(pkg->db);
342                 free(pkg->path);
343         }
344         /* TODO free any malloced names and such */
345         return 1;
346 }
347
348 /* set package struct variables, database, environment, then command line */
349 int zpm_readopts(struct zpm *pkg, int ac, char **av) {
350         char *ev;
351
352         if (!pkg) {
353                 return -1;
354         }
355
356         ev = getenv("ZPMPACKAGE");
357         if (ev) {
358                 pkg->pkgname = dupstr(ev);
359         }
360         ev = getenv("ZPMPKGREL");
361         if (ev) {
362                 pkg->release = strtol(ev, 0, 0);
363         }
364         ev = getenv("ZPMPKGVER");
365         if (ev) {
366                 pkg->version = dupstr(ev);
367         }
368
369         /* now, parse the options, return optind so the caller can adjust if needed */
370
371         return 1;
372 }
373
374 int zpm_extract(struct zpm *pkg, char *hash, char *path, int mode) {
375         int rc;
376
377         int blobsize;
378         //int64_t size;
379         void *xzdata;
380         int type;
381         FILE *out;
382         sqlite3_stmt *ifile;
383
384         /* TODO check null */
385         sqlite3 *db = pkg->db;
386
387         rc = sqlite3_prepare(db, "select size, content from files where hash = ?", -1, &ifile,0);
388         if (rc != SQLITE_OK) {
389                 SQLERROR(sqlite3_errmsg(db));
390                 return 0;
391         }
392
393         /* hash, filename */
394
395         sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
396
397         rc = sqlite3_step(ifile);
398
399         if (rc == SQLITE_DONE) {
400                 /* didn't find a row */
401                 sqlite3_finalize(ifile);
402                 sqlite3_close(db);
403                 fprintf(stderr, "no such hash\n");
404                 return 0;
405         }
406         /* either way we're done with this now */
407
408         if (rc != SQLITE_ROW) {
409                 SQLERROR(sqlite3_errmsg(db));
410                 sqlite3_finalize(ifile);
411                 sqlite3_close(db);
412                 return 0;
413         }
414
415         type = sqlite3_column_type(ifile, 0);
416         if (type == SQLITE_NULL) {
417                 fprintf(stderr, "no file size\n");
418                 sqlite3_finalize(ifile);
419                 sqlite3_close(db);
420                 return 0;
421         }
422         type = sqlite3_column_type(ifile, 1);
423         if (type == SQLITE_NULL) {
424                 fprintf(stderr, "no file data\n");
425                 sqlite3_finalize(ifile);
426                 sqlite3_close(db);
427                 return 0;
428         }
429         //size = sqlite3_column_int64(ifile, 0);
430         xzdata = (void *)sqlite3_column_blob(ifile, 1);
431         blobsize = sqlite3_column_bytes(ifile, 1);
432
433         out = fopen(path, "w");
434         if (!out) {
435                 fprintf(stderr, "can't open output file %s\n", path);
436                 sqlite3_finalize(ifile);
437                 sqlite3_close(db);
438                 return 5;
439         }
440         //fwrite(xzdata, blobsize, 1, stdout);
441
442         //fprintf(stderr, "uncompressing %d bytes at %p, expect %lld\n", blobsize, xzdata, (long long int)size);
443         uncompresslzma(xzdata, blobsize, out);
444         fclose(out);
445
446         sqlite3_finalize(ifile);
447
448         return 0;
449         
450 }
451
452 /* flags 0, close mmap, flags 1, return mmap fd */
453 int zpm_hash(char *path, char *hash, uint32_t flags) {
454         int fd;
455         void *content;
456         struct stat sbuf;
457         hash_state md;
458         int j;
459         unsigned char tmp[32];
460
461         /* mmap the file */
462         fd = open(path, O_RDONLY);
463         if (fd == -1) {
464                 fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno));
465                 return 0;
466         }
467         if (fstat(fd, &sbuf) == -1) {
468                 fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno));
469                 return 0;
470         }
471         /* not a regular file? */
472         if (!S_ISREG(sbuf.st_mode)) {
473                 /* TODO this is ok, just stored differently */
474                 fprintf(stderr, "%s non-regular files unsupported %s\n", __FUNCTION__, path);
475                 return 0;
476         }
477
478         content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0);
479         close(fd);
480         if (!content) {
481                 fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno));
482                 return 0;
483         }
484
485         /* get hash */
486         sha256_init(&md);
487         sha256_process(&md, content, sbuf.st_size);
488         sha256_done(&md, tmp);
489         for (j=0;j<32;j++) {
490                 sprintf(hash+j*2, "%02x", (unsigned)tmp[j]);
491         }
492         hash[64] = 0;
493         munmap(content, sbuf.st_size);
494         return 1;
495 }
496
497 #if 1
498 int zpm_import(struct zpm *pkg, char *path, uint32_t flags, char *hash) {
499         int fd;
500         void *content;
501         struct stat sbuf;
502         unsigned char tmp[32];
503         hash_state md;
504         sqlite3_stmt *ifile;
505         int haverow = 0,havedata = 0;
506         int j,rc,type;
507         char hashbuf[65];
508
509         /* xz compress it */
510         size_t outlen = 0;
511         void *outbuf;
512
513         if (!pkg || !pkg->db || !path) {
514                 return 0;
515         }
516
517         /* use local if caller didn't pass in room */
518         if (!hash) {
519                 hash = hashbuf;
520         }
521
522         /* mmap the file */
523         fd = open(path, O_RDONLY);
524         if (fd == -1) {
525                 pkg->error = errno;
526                 fprintf(stderr, "%s can't open %s: %s\n", __FUNCTION__, path,strerror(errno));
527                 return 0;
528         }
529         if (fstat(fd, &sbuf) == -1) {
530                 pkg->error = errno;
531                 fprintf(stderr, "%s can't fstat %s: %s\n", __FUNCTION__, path,strerror(errno));
532                 return 0;
533         }
534         /* not a regular file? */
535         if (!S_ISREG(sbuf.st_mode)) {
536                 char *ftype;
537                 switch (sbuf.st_mode & S_IFMT) {
538                         case S_IFSOCK: ftype = "socket"; break;
539                         case S_IFLNK : ftype = "symlink"; break;
540                         case S_IFBLK : ftype = "block device"; break;
541                         case S_IFDIR : ftype = "directory"; break;
542                         case S_IFCHR : ftype = "character device"; break;
543                         case S_IFIFO : ftype = "fifo"; break;
544                         default: ftype = "unknown file type"; break;
545                 }
546                 /* TODO this is ok, just stored differently */
547                 fprintf(stderr, "%s can't import %s file: %s\n", __FUNCTION__, ftype, path);
548                 pkg->error = EINVAL;
549                 return 0;
550         }
551
552         content = mmap(0, sbuf.st_size, PROT_READ,MAP_PRIVATE, fd, 0);
553         if (!content) {
554                 pkg->error = errno;
555                 fprintf(stderr, "%s can't mmap %s: %s\n", __FUNCTION__, path,strerror(errno));
556                 return 0;
557         }
558
559         /* get hash */
560         sha256_init(&md);
561         sha256_process(&md, content, sbuf.st_size);
562         sha256_done(&md, tmp);
563         for (j=0;j<32;j++) {
564                 sprintf(hash+j*2, "%02x", (unsigned)tmp[j]);
565         }
566         hash[64] = 0;
567         //fprintf(stderr, "file %s: %s\n", path, hash);
568
569         /* prepare and bind */
570         /* TODO check null */
571         sqlite3 *db = pkg->db;
572
573         rc = sqlite3_prepare_v2(db, "select size, content is not null from files where hash = ?", -1, &ifile,0);
574         if (rc != SQLITE_OK) {
575                 SQLERROR(sqlite3_errmsg(db));
576                 return 0;
577         }
578
579         /* hash, filename */
580
581         sqlite3_bind_text(ifile, 1, hash, 64, SQLITE_STATIC);
582
583         rc = sqlite3_step(ifile);
584
585         if (rc != SQLITE_DONE) {
586                 if (rc != SQLITE_ROW) {
587                         /* didn't find a row */
588                         SQLERROR(sqlite3_errmsg(db));
589                         zpm_rollback(pkg);
590                         return 0;
591                 }
592                 haverow = 1;
593 //              fprintf(stderr, "have row for hash\n");
594                 type = sqlite3_column_type(ifile, 0);
595                 if (type == SQLITE_NULL) {
596                         /* TODO assert, this shouldn't be possible? */
597                         fprintf(stderr, "no file size\n");
598                         sqlite3_finalize(ifile);
599                         return 0;
600                 }
601                 type = sqlite3_column_type(ifile, 1);
602                 if (type == SQLITE_NULL) {
603                         /* TODO assert, this shouldn't be possible? */
604                         fprintf(stderr, "no file data\n");
605                         sqlite3_finalize(ifile);
606                         return 0;
607                         /* which is fine, just need to update the row then */
608                 }
609                 havedata = sqlite3_column_int(ifile, 1);
610         }
611
612         sqlite3_finalize(ifile);
613
614         if (!havedata) {
615                 /* compress */
616                 outbuf = compresslzma(content, sbuf.st_size, &outlen);
617                 if (!outbuf) {
618                         fprintf(stderr, "compresslzma failed\n");
619                         return 0;
620                 }
621                 //fprintf(stderr, "compressed to %zu\n", outlen);
622                 /* don't need the original file now */
623                 munmap(content, sbuf.st_size);
624                 close(fd);
625
626                 /* start a transaction */
627                 // do that outside of here 
628                 //zpm_begin(pkg);
629
630                 /* insert */
631                 if (haverow) {
632                         //fprintf(stderr, "adding file data\n");
633                         rc = sqlite3_prepare(db, "update files set size = ?, content = ? where hash = ?", -1, &ifile,0);
634                 } else {
635                         //fprintf(stderr, "creating new data row\n");
636                         rc = sqlite3_prepare(db, "insert into files (size, content, hash) values (?,?,?)", -1, &ifile,0);
637                 }
638                 if (rc != SQLITE_OK) {
639                         SQLERROR(sqlite3_errmsg(db));
640                         fprintf(stderr, "cant prepare data\n");
641                         zpm_rollback(pkg);
642                         return 0;
643                 }
644
645                 sqlite3_bind_int64(ifile, 1, (sqlite3_int64)sbuf.st_size);
646                 if (rc != SQLITE_OK) {
647                         SQLERROR(sqlite3_errmsg(db));
648                         fprintf(stderr, "cant bind size\n");
649                         zpm_rollback(pkg);
650                         return 0;
651                 }
652                 sqlite3_bind_blob64(ifile, 2, outbuf, (sqlite3_int64)outlen, SQLITE_STATIC);
653                 if (rc != SQLITE_OK) {
654                         SQLERROR(sqlite3_errmsg(db));
655                         fprintf(stderr, "cant bind content\n");
656                         zpm_rollback(pkg);
657                         return 0;
658                 }
659                 sqlite3_bind_text(ifile, 3, hash, 64, SQLITE_STATIC);
660                 if (rc != SQLITE_OK) {
661                         SQLERROR(sqlite3_errmsg(db));
662                         fprintf(stderr, "cant bind hash\n");
663                         zpm_rollback(pkg);
664                         return 0;
665                 }
666                 rc = sqlite3_step(ifile);
667                 if (rc != SQLITE_DONE) {
668                         SQLERROR(sqlite3_errmsg(db));
669                         sqlite3_finalize(ifile);
670                         zpm_rollback(pkg);
671                         return 0;
672                 }
673                 sqlite3_finalize(ifile);
674
675                 /* commit */
676                 //zpm_commit(pkg);
677
678         } else {
679                 /* don't need the original file now */
680                 munmap(content, sbuf.st_size);
681                 close(fd);
682         }
683
684
685         /* if package and not nopackage flag, add to package */
686         if (pkg->pkgname && (!ZPM_NOPACKAGE)) {
687                 /* TODO */
688         }
689
690         /* return */
691         return 1;
692 }
693 #endif
694
695 #if 0
696 int main(int ac, char **av){
697         sqlite3 *db = 0;
698         int rc;
699
700         int blobsize;
701         int64_t size;
702         void *xzdata;
703         int type;
704         FILE *out;
705         sqlite3_stmt *ifile;
706
707         char *hash;
708         char *filename;
709
710         if (ac < 3) {
711                 fprintf(stderr, "usage: db hash file\n");
712                 return 1;
713         }
714
715         rc = sqlite3_open(av[1], &db);
716         if (rc) {
717                 SQLERROR(sqlite3_errmsg(db));
718                 sqlite3_close(db);
719                 return 1;
720         }
721
722 }
723 #endif
724
725 #if 0
726 Packages are sqlite databases
727
728 get application id and userver
729
730 Primitive operations:
731
732 add path to repo
733 associate path with package
734 associate blob with path?
735 add blob to repo
736 * extract blob to a path
737 compare blob to filesystem path
738 create package with info
739
740 Extra primitives:
741
742 record elf information about blob
743 compress blob
744 uncompress blob
745 sign a package?  What are we verifying?
746 #endif