Mercurial > illumos > illumos-gate
changeset 10130:0c523179270e
5074117 installf problem with character and block special devices.
author | phaniram rampura krishnamurthy - Sun Microsystems - Bangalore India <Phaniram.Krishnamurthy@Sun.COM> |
---|---|
date | Mon, 20 Jul 2009 12:16:38 +0530 |
parents | 089f053ced24 |
children | 7fe254ca5fe8 |
files | usr/src/cmd/svr4pkg/libinst/pkgdbmerg.c usr/src/lib/libpkg/common/isdir.c usr/src/lib/libpkg/common/mapfile-vers usr/src/lib/libpkg/common/pkglib.h usr/src/lib/libpkg/common/verify.c |
diffstat | 5 files changed, 166 insertions(+), 88 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/svr4pkg/libinst/pkgdbmerg.c Sun Jul 19 20:52:08 2009 -0700 +++ b/usr/src/cmd/svr4pkg/libinst/pkgdbmerg.c Mon Jul 20 12:16:38 2009 +0530 @@ -99,7 +99,7 @@ static int do_like_ent(VFP_T *vfpo, struct cfextra *el_ent, struct cfent *cf_ent, int ctrl); static int do_new_ent(VFP_T *vfpo, struct cfextra *el_ent, int ctrl); -static int typechg(struct cfent *el_ent, struct cfent *cf_ent, +static int typechg(struct cfent *el_ent, char *curftype, struct mergstat *mstat); static void set_change(struct cfextra *el_ent); @@ -549,6 +549,40 @@ * about this later. Note that noconflict means NO conflict * at the file level. Even rogue files count. */ + char myftype = '?'; + int n = 0; + + /* Get the existing file type on disk */ + eval_ftype(el_ent->server_path, el_ent->cf_ent.ftype, &myftype); + + /* Do the right thing if types are different */ + n = typechg(&(el_ent->cf_ent), &myftype, &(el_ent->mstat)); + switch (n) { + case TYPE_OK: + break; + + /* This is an allowable change. */ + case TYPE_WARNING: + el_ent->mstat.contchg = 1; + break; + + /* Not allowed, but leaving it as is is OK. */ + case TYPE_IGNORED: + break; + + /* Future analysis will reveal if this is OK. */ + case TYPE_REPLACE: + el_ent->mstat.replace = 1; + break; + + /* Kill it before it does any damage. */ + case TYPE_FATAL: + logerr(gettext(MSG_TYPE_ERR)); + quit(99); + + default: + break; + } el_ent->mstat.shared = 1; el_ent->mstat.rogue = 1; set_change(el_ent); @@ -725,20 +759,20 @@ * TYPE_FATAL something awful happened */ static int -typechg(struct cfent *el_ent, struct cfent *cf_ent, struct mergstat *mstat) +typechg(struct cfent *el_ent, char *curftype, struct mergstat *mstat) { int i, etype, itype, retcode; /* If they are identical, return OK */ - if (cf_ent->ftype == el_ent->ftype) + if (*curftype == el_ent->ftype) return (TYPE_OK); /* * If package database entry is ambiguous, set it to the new entity's * ftype */ - if (cf_ent->ftype == BADFTYPE) { - cf_ent->ftype = el_ent->ftype; + if (*curftype == BADFTYPE) { + *curftype = el_ent->ftype; return (TYPE_OK); /* do nothing; not really different */ } @@ -751,7 +785,7 @@ * exclusive directory, this is very dangerous. We will continue, but * we will deny the conversion. */ - if (el_ent->ftype == 'x' && cf_ent->ftype == 'd') { + if (el_ent->ftype == 'x' && *curftype == 'd') { logerr(gettext(WRN_TOEXCL), el_ent->path); return (TYPE_IGNORED); } @@ -768,7 +802,7 @@ /* Set itype to that in the package database. */ for (i = 0; types[i]; ++i) { - if (strchr(types[i], cf_ent->ftype)) { + if (strchr(types[i], *curftype)) { itype = i+1; break; } @@ -792,36 +826,36 @@ /* allow change, but warn user of possible problems */ switch (itype) { - case 1: - logerr(gettext(WRN_NOTFILE), el_ent->path); - break; + case 1: + logerr(gettext(WRN_NOTFILE), el_ent->path); + break; - case 2: - logerr(gettext(WRN_NOTSYMLN), el_ent->path); - break; + case 2: + logerr(gettext(WRN_NOTSYMLN), el_ent->path); + break; - case 3: - logerr(gettext(WRN_NOTLINK), el_ent->path); - break; + case 3: + logerr(gettext(WRN_NOTLINK), el_ent->path); + break; - case 4: - logerr(gettext(WRN_NOTDIR), el_ent->path); - break; + case 4: + logerr(gettext(WRN_NOTDIR), el_ent->path); + break; - case 5: - logerr(gettext(WRN_NOTCHAR), el_ent->path); - break; + case 5: + logerr(gettext(WRN_NOTCHAR), el_ent->path); + break; - case 6: - logerr(gettext(WRN_NOTBLOCK), el_ent->path); - break; + case 6: + logerr(gettext(WRN_NOTBLOCK), el_ent->path); + break; - case 7: - logerr(gettext(WRN_NOTPIPE), el_ent->path); - break; + case 7: + logerr(gettext(WRN_NOTPIPE), el_ent->path); + break; - default: - break; + default: + break; } return (retcode); } @@ -867,7 +901,8 @@ * can't figure it 'til later (d -> s) or fatal (a hook for later). */ if (cf_ent->ftype != el_ent->cf_ent.ftype) { - n = typechg(&(el_ent->cf_ent), cf_ent, &(el_ent->mstat)); + n = typechg(&(el_ent->cf_ent), &(cf_ent->ftype), + &(el_ent->mstat)); switch (n) { case TYPE_OK:
--- a/usr/src/lib/libpkg/common/isdir.c Sun Jul 19 20:52:08 2009 -0700 +++ b/usr/src/lib/libpkg/common/isdir.c Mon Jul 20 12:16:38 2009 +0530 @@ -20,7 +20,7 @@ */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -40,6 +40,7 @@ #include <string.h> #include "pkglocale.h" #include "pkglibmsgs.h" +#include "pkglib.h" /* * Defines for cpio/compression checks. @@ -77,6 +78,7 @@ int isdir(char *path); int isfile(char *dir, char *file); int iscpio(char *path, int *iscomp); +int eval_ftype(char *path, char ftype, char *myftype); /* * Name: isdir @@ -389,3 +391,83 @@ (void) fclose(fp); } + +/* + * Name: eval_ftype + * Description: Evaluate the target's file type + * Arguments: path - Path on filesystem + * ftype - Type to be changed to + * myftype - Address into which current + * type of target will be stored + * Returns: int + * 0 - Success + * VE_EXIST - Path does not exist + * VE_FTYPE - Path file type is not recognized, + * is not supported, + * or is not what is expected + */ +int +eval_ftype(char *path, char ftype, char *myftype) +{ + struct stat status; + int retcode = 0; + int statError = 0; + + /* If we are to process symlinks the old way then we follow the link */ + if (nonABI_symlinks()) { + if ((ftype == 's') ? lstat(path, &status) : + stat(path, &status)) { + (void) reperr(pkg_gt(ERR_EXIST)); + retcode = VE_EXIST; + *myftype = '?'; + statError++; + } + /* If not then we inspect the target of the link */ + } else { + if (lstat(path, &status) == -1) { + reperr(pkg_gt(ERR_EXIST)); + retcode = VE_EXIST; + *myftype = '?'; + statError++; + } + } + if (!statError) { + /* determining actual type of existing object */ + switch (status.st_mode & S_IFMT) { + case S_IFLNK: + *myftype = 's'; + break; + + case S_IFIFO: + *myftype = 'p'; + break; + + case S_IFCHR: + *myftype = 'c'; + break; + + case S_IFDIR: + *myftype = 'd'; + break; + + case S_IFBLK: + *myftype = 'b'; + break; + + case S_IFREG: + case 0: + *myftype = 'f'; + break; + + case S_IFDOOR: + *myftype = 'D'; + break; + + default: + *myftype = '?'; + return (VE_FTYPE); + } + retcode = 0; + } + return (retcode); +}
--- a/usr/src/lib/libpkg/common/mapfile-vers Sun Jul 19 20:52:08 2009 -0700 +++ b/usr/src/lib/libpkg/common/mapfile-vers Mon Jul 20 12:16:38 2009 +0530 @@ -89,6 +89,7 @@ epclose; epopen; esystem; + eval_ftype; find_ca_certs; find_cl_certs; find_key_cert_pair;
--- a/usr/src/lib/libpkg/common/pkglib.h Sun Jul 19 20:52:08 2009 -0700 +++ b/usr/src/lib/libpkg/common/pkglib.h Mon Jul 20 12:16:38 2009 +0530 @@ -499,10 +499,12 @@ extern void ds_putinfo(char *buf); extern void ds_skiptoend(char *device); extern void ecleanup(void); +extern int eval_ftype(char *path, char ftype, char *myftype); /*PRINTFLIKE1*/ extern void logerr(char *fmt, ...); extern int mappath(int flag, char *path); extern int mapvar(int flag, char *varname); +extern void reperr(char *fmt, ...); /*PRINTFLIKE1*/ extern void progerr(char *fmt, ...); extern void pkgerr(PKG_ERR *); @@ -626,6 +628,7 @@ extern int isPathRemote(); extern int iscpio(); extern int isdir(); +extern int eval_ftype(); extern int isfile(); extern int pkgexecl(); extern int pkgexecv(); @@ -653,6 +656,7 @@ extern void ds_skiptoend(); extern void ecleanup(); extern void logerr(); +extern void reperr(); extern int mappath(); extern int mapvar(); extern void progerr();
--- a/usr/src/lib/libpkg/common/verify.c Sun Jul 19 20:52:08 2009 -0700 +++ b/usr/src/lib/libpkg/common/verify.c Mon Jul 20 12:16:38 2009 +0530 @@ -85,7 +85,7 @@ } CHECKSUM_T; /*PRINTFLIKE1*/ -static void +void reperr(char *fmt, ...) { char *pt; @@ -392,7 +392,6 @@ int uid, gid; int dochown; int retcode; - int statError = 0; int targ_is_dir = 0; /* replacing a directory */ char myftype; char buf[PATH_MAX]; @@ -491,62 +490,19 @@ retcode = 0; - /* If we are to process symlinks the old way then we follow the link */ - if (nonABI_symlinks()) { - if ((*ftype == 's') ? lstat(path, &status) : - stat(path, &status)) { - reperr(pkg_gt(ERR_EXIST)); - retcode = VE_EXIST; - myftype = '?'; - statError++; - } - /* If not then we inspect the target of the link */ - } else { - if ((n = lstat(path, &status)) == -1) { - reperr(pkg_gt(ERR_EXIST)); - retcode = VE_EXIST; - myftype = '?'; - statError++; - } - } - if (!statError) { - /* determining actual type of existing object */ - switch (status.st_mode & S_IFMT) { - case S_IFLNK: - myftype = 's'; - break; + /* Evaluate the file type of existing object */ + retcode = eval_ftype(path, *ftype, &myftype); - case S_IFIFO: - myftype = 'p'; - break; - - case S_IFCHR: - myftype = 'c'; - break; - - case S_IFDIR: - myftype = 'd'; - targ_is_dir = 1; - break; + /* + * If path file type is not recognized, is not supported or + * is not what is expected, return + */ + if (retcode == VE_FTYPE) + return (retcode); - case S_IFBLK: - myftype = 'b'; - break; - - case S_IFREG: - case 0: - myftype = 'f'; - break; - - case S_IFDOOR: - myftype = 'D'; - break; - - default: - reperr(pkg_gt(ERR_UNKNOWN)); - return (VE_FTYPE); - } - } + /* If existing type is Directory, then set flag */ + if (myftype == 'd') + targ_is_dir = 1; if (setval) { /*