Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414)
Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can
arrange to use the same source file name in sfimage, without having to export over the original
Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need
for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.
/*
* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
/*
* This file is part of zsh, the Z shell.
*
* Copyright (c) 1996-1997 Andrew Main
* All rights reserved.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and to distribute modified versions of this software for any
* purpose, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* In no event shall Andrew Main or the Zsh Development Group be liable
* to any party for direct, indirect, special, incidental, or consequential
* damages arising out of the use of this software and its documentation,
* even if Andrew Main and the Zsh Development Group have been advised of
* the possibility of such damage.
*
* Andrew Main and the Zsh Development Group specifically disclaim any
* warranties, including, but not limited to, the implied warranties of
* merchantability and fitness for a particular purpose. The software
* provided hereunder is on an "as is" basis, and Andrew Main and the
* Zsh Development Group have no obligation to provide maintenance,
* support, updates, enhancements, or modifications.
*
*/
#include "files.mdh"
#ifdef __SYMBIAN32__
#ifdef __WINSCW__
#pragma warn_unusedarg off
#endif//__WINSCW__
#endif//__SYMBIAN32__
typedef int (*MoveFunc) _((char const *, char const *));
typedef int (*RecurseFunc) _((char *, char *, struct stat const *, void *));
#ifndef STDC_HEADERS
extern int link _((const char *, const char *));
extern int symlink _((const char *, const char *));
extern int rename _((const char *, const char *));
#endif
struct recursivecmd;
#include "files.pro"
/**/
static int
ask(void)
{
int a = getchar(), c;
for(c = a; c != EOF && c != '\n'; )
c = getchar();
return a == 'y' || a == 'Y';
}
/* sync builtin */
/**/
static int
bin_sync(UNUSED(char *nam), UNUSED(char **args), UNUSED(Options ops), UNUSED(int func))
{
sync();
return 0;
}
/* mkdir builtin */
/**/
int
bin_mkdir(char *nam, char **args, Options ops, UNUSED(int func))
{
mode_t oumask = umask(0);
mode_t mode = 0777 & ~oumask;
int err = 0;
umask(oumask);
if(OPT_ISSET(ops,'m')) {
char *str = OPT_ARG(ops,'m'), *ptr;
mode = zstrtol(str, &ptr, 8);
if(!*str || *ptr) {
zwarnnam(nam, "invalid mode `%s'", str, 0);
return 1;
}
}
for(; *args; args++) {
char *ptr = strchr(*args, 0);
while(ptr > *args + (**args == '\\') && *--ptr == '\\')
*ptr = 0;
if(OPT_ISSET(ops,'p')) {
char *ptr = *args;
for(;;) {
while(*ptr == '\\')
ptr++;
while(*ptr && *ptr != '\\')
ptr++;
if(!*ptr) {
err |= domkdir(nam, *args, mode, 1);
break;
} else {
int e;
*ptr = 0;
e = domkdir(nam, *args, mode | 0300, 1);
if(e) {
err = 1;
break;
}
*ptr = '\\';
}
}
} else
err |= domkdir(nam, *args, mode, 0);
}
return err;
}
/**/
static int
domkdir(char *nam, char *path, mode_t mode, int p)
{
int err;
mode_t oumask;
char const *rpath = unmeta(path);
if(p) {
struct stat st;
if(!lstat(rpath, &st) && S_ISDIR(st.st_mode))
return 0;
}
oumask = umask(0);
err = mkdir(path, mode) ? errno : 0;
umask(oumask);
if(!err)
return 0;
zwarnnam(nam, "cannot make directory `%s': %e", path, err);
return 1;
}
/* rmdir builtin */
/**/
int
bin_rmdir(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
int err = 0;
for(; *args; args++) {
char *rpath = unmeta(*args);
if(!rpath) {
zwarnnam(nam, "%s: %e", *args, ENAMETOOLONG);
err = 1;
} else if(rmdir(rpath)) {
zwarnnam(nam, "cannot remove directory `%s': %e", *args, errno);
err = 1;
}
}
return err;
}
/* ln and mv builtins */
//#define BIN_LN 0
//#define BIN_MV 1
#define MV_NODIRS (1<<0)
#define MV_FORCE (1<<1)
#define MV_INTER (1<<2)
#define MV_ASKNW (1<<3)
#define MV_ATOMIC (1<<4)
/* bin_ln actually does three related jobs: hard linking, symbolic *
* linking, and renaming. If called as mv it renames, otherwise *
* it looks at the -s option. If hard linking, it will refuse to *
* attempt linking to a directory unless the -d option is given. */
/**/
int
bin_ln(char *nam, char **args, Options ops, int func)
{
MoveFunc move;
int flags, err = 0;
char **a, *ptr, *rp, *buf;
struct stat st;
size_t blen;
if(func == BIN_MV) {
move = (MoveFunc) rename;
flags = OPT_ISSET(ops,'f') ? 0 : MV_ASKNW;
flags |= MV_ATOMIC;
} else {
flags = OPT_ISSET(ops,'f') ? MV_FORCE : 0;
#ifdef HAVE_LSTAT
if(OPT_ISSET(ops,'s'))
move = (MoveFunc) symlink;
else
#endif
{
move = (MoveFunc) link;
if(!OPT_ISSET(ops,'d'))
flags |= MV_NODIRS;
}
}
if(OPT_ISSET(ops,'i') && !OPT_ISSET(ops,'f'))
flags |= MV_INTER;
for(a = args; a[1]; a++) ;
if(a != args) {
rp = unmeta(*a);
if(rp && !stat(rp, &st) && S_ISDIR(st.st_mode))
goto havedir;
}
if(a > args+1) {
zwarnnam(nam, "last of many arguments must be a directory", NULL, 0);
return 1;
}
if(!args[1]) {
ptr = strrchr(args[0], '\\');
if(ptr)
args[1] = ptr+1;
else
args[1] = args[0];
}
return domove(nam, move, args[0], args[1], flags);
havedir:
buf = ztrdup(*a);
*a = NULL;
buf = appstr(buf, "\\");
blen = strlen(buf);
for(; *args; args++) {
ptr = strrchr(*args, '\\');
if(ptr)
ptr++;
else
ptr = *args;
buf[blen] = 0;
buf = appstr(buf, ptr);
err |= domove(nam, move, *args, buf, flags);
}
zsfree(buf);
return err;
}
/**/
static int
domove(char *nam, MoveFunc move, char *p, char *q, int flags)
{
struct stat st;
char *pbuf, *qbuf;
pbuf = ztrdup(unmeta(p));
qbuf = unmeta(q);
if(flags & MV_NODIRS) {
errno = EISDIR;
if(lstat(pbuf, &st) || S_ISDIR(st.st_mode)) {
zwarnnam(nam, "%s: %e", p, errno);
zsfree(pbuf);
return 1;
}
}
if(!lstat(qbuf, &st)) {
int doit = flags & MV_FORCE;
struct stat file_stat;
if(S_ISDIR(st.st_mode)) {
zwarnnam(nam, "%s: cannot overwrite directory", q, 0);
zsfree(pbuf);
return 1;
}else if(lstat(pbuf, &file_stat)){
zwarnnam(nam, "%e: %s", q, errno);
zsfree(pbuf);
return 1;
}else if(flags & MV_INTER) {
nicezputs(nam, stderr);
fputs(": replace `", stderr);
nicezputs(q, stderr);
fputs("'? ", stderr);
fflush(stderr);
if(!ask()) {
zsfree(pbuf);
return 0;
}
doit = 1;
} else if((flags & MV_ASKNW) &&
!S_ISLNK(st.st_mode) &&
access(qbuf, W_OK)) {
nicezputs(nam, stderr);
fputs(": replace `", stderr);
nicezputs(q, stderr);
fprintf(stderr, "', overriding mode %04o? ",
mode_to_octal(st.st_mode));
fflush(stderr);
if(!ask()) {
zsfree(pbuf);
return 0;
}
doit = 1;
}
if(doit && !(flags & MV_ATOMIC))
unlink(qbuf);
}
if(move(pbuf, qbuf)) {
zwarnnam(nam, "%s: %e", p, errno);
zsfree(pbuf);
return 1;
}
zsfree(pbuf);
return 0;
}
/* general recursion */
struct recursivecmd {
char *nam;
int opt_noerr;
int opt_recurse;
int opt_safe;
RecurseFunc dirpre_func;
RecurseFunc dirpost_func;
RecurseFunc leaf_func;
void *magic;
};
/**/
static int
recursivecmd(char *nam, int opt_noerr, int opt_recurse, int opt_safe,
char **args, RecurseFunc dirpre_func, RecurseFunc dirpost_func,
RecurseFunc leaf_func, void *magic)
{
int err = 0, len;
char *rp, *s;
struct dirsav ds;
struct recursivecmd reccmd;
reccmd.nam = nam;
reccmd.opt_noerr = opt_noerr;
reccmd.opt_recurse = opt_recurse;
reccmd.opt_safe = opt_safe;
reccmd.dirpre_func = dirpre_func;
reccmd.dirpost_func = dirpost_func;
reccmd.leaf_func = leaf_func;
reccmd.magic = magic;
ds.ino = ds.dev = 0;
ds.dirname = NULL;
ds.dirfd = ds.level = -1;
if (opt_recurse || opt_safe) {
if ((ds.dirfd = open(".", O_RDONLY|O_NOCTTY)) < 0 &&
zgetdir(&ds) && *ds.dirname != '\\')
ds.dirfd = open("..", O_RDONLY|O_NOCTTY);
}
for(; !errflag && !(err & 2) && *args; args++) {
rp = ztrdup(*args);
unmetafy(rp, &len);
if (opt_safe) {
s = strrchr(rp, '\\');
if (s && !s[1]) {
while (*s == '\\' && s > rp)
*s-- = '\0';
while (*s != '\\' && s > rp)
s--;
}
if (s && s[1]) {
int e;
*s = '\0';
e = lchdir(s > rp ? rp : "\\", &ds, 1);
err |= -e;
if (!e) {
struct dirsav d;
d.ino = d.dev = 0;
d.dirname = NULL;
d.dirfd = d.level = -1;
err |= recursivecmd_doone(&reccmd, *args, s + 1, &d, 0);
zsfree(d.dirname);
if (restoredir(&ds))
err |= 2;
} else if(!opt_noerr)
zwarnnam(nam, "%s: %e", *args, errno);
} else
err |= recursivecmd_doone(&reccmd, *args, rp, &ds, 0);
} else
err |= recursivecmd_doone(&reccmd, *args, rp, &ds, 1);
zfree(rp, len + 1);
}
if ((err & 2) && ds.dirfd >= 0 && restoredir(&ds) && zchdir(pwd)) {
zsfree(pwd);
pwd = ztrdup("\\");
chdir(pwd);
}
if (ds.dirfd >= 0)
close(ds.dirfd);
zsfree(ds.dirname);
return !!err;
}
/* rm builtin */
struct rmmagic {
char *nam;
int opt_force;
int opt_interact;
int opt_unlinkdir;
};
/**/
static int
recursivecmd_doone(struct recursivecmd const *reccmd,
char *arg, char *rp, struct dirsav *ds, int first)
{
struct stat st, *sp = NULL;
struct rmmagic *rmm = reccmd->magic;
if( (reccmd->opt_recurse || rmm->opt_unlinkdir) && !lstat(rp, &st)) {
if(S_ISDIR(st.st_mode))
return recursivecmd_dorec(reccmd, arg, rp, &st, ds, first);
sp = &st;
}
return reccmd->leaf_func(arg, rp, sp, reccmd->magic);
}
/**/
static int
recursivecmd_dorec(struct recursivecmd const *reccmd,
char *arg, char *rp, struct stat const *sp, struct dirsav *ds, int first)
{
char *fn;
DIR *d;
int err, err1;
struct dirsav dsav;
char *files = NULL;
int fileslen = 0;
err1 = reccmd->dirpre_func(arg, rp, sp, reccmd->magic);
if(err1 & 2)
return 2;
err = -lchdir(rp, ds, !first);
if (err) {
if(!reccmd->opt_noerr)
zwarnnam(reccmd->nam, "%s: %e", arg, errno);
return err;
}
err = err1;
dsav.ino = dsav.dev = 0;
dsav.dirname = NULL;
dsav.dirfd = dsav.level = -1;
d = opendir(".");
if(!d) {
if(!reccmd->opt_noerr)
zwarnnam(reccmd->nam, "%s: %e", arg, errno);
err = 1;
} else {
int arglen = strlen(arg) + 1;
while (!errflag && (fn = zreaddir(d, 1))) {
int l = strlen(fn) + 1;
files = hrealloc(files, fileslen, fileslen + l);
strcpy(files + fileslen, fn);
fileslen += l;
}
closedir(d);
for (fn = files; !errflag && !(err & 2) && fn < files + fileslen;) {
int l = strlen(fn) + 1;
int is_dir=0;
VARARR(char, narg, arglen + l);
strcpy(narg,arg);
narg[arglen-1] = '\\';
strcpy(narg + arglen, fn);
unmetafy(fn, NULL);
#ifdef __SYMBIAN32__
{
struct stat sta;
if(stat(fn, &sta)==0 && S_ISDIR(sta.st_mode))
is_dir=1;
}
#endif
err |= recursivecmd_doone(reccmd, narg, fn, &dsav, 0);
if(is_dir)
ds=&dsav;
fn += l;
}
hrealloc(files, fileslen, 0);
}
zsfree(dsav.dirname);
if (err & 2)
return 2;
if (restoredir(ds)) {
if(!reccmd->opt_noerr)
zwarnnam(reccmd->nam, "failed to return to previous directory: %e",
NULL, errno);
return 2;
}
return err | reccmd->dirpost_func(arg, rp, sp, reccmd->magic);
}
/**/
static int
recurse_donothing(UNUSED(char *arg), UNUSED(char *rp), UNUSED(struct stat const *sp), UNUSED(void *magic))
{
return 0;
}
/**/
static int
rm_leaf(char *arg, char *rp, struct stat const *sp, void *magic)
{
struct rmmagic *rmm = magic;
struct stat st;
if(!rmm->opt_unlinkdir || !rmm->opt_force) {
if(!sp) {
if(!lstat(rp, &st))
sp = &st;
}
if(sp) {
if(!rmm->opt_unlinkdir && S_ISDIR(sp->st_mode)) {
#ifndef __SYMBIAN32__
if(rmm->opt_force)
return 0;
#endif
zwarnnam(rmm->nam, "%s: %e", arg, EISDIR);
return 1;
}
if(rmm->opt_interact) {
nicezputs(rmm->nam, stderr);
fputs(": remove `", stderr);
nicezputs(arg, stderr);
fputs("'? ", stderr);
fflush(stderr);
if(!ask())
return 0;
} else if(!rmm->opt_force &&
!S_ISLNK(sp->st_mode) &&
access(rp, W_OK)) {
nicezputs(rmm->nam, stderr);
fputs(": remove `", stderr);
nicezputs(arg, stderr);
fprintf(stderr, "', overriding mode %04o? ",
mode_to_octal(sp->st_mode));
fflush(stderr);
if(!ask())
return 0;
}
}
}
if(unlink(rp) && !rmm->opt_force) {
zwarnnam(rmm->nam, "%s: %e", arg, errno);
return 1;
}
return 0;
}
/**/
static int
rm_dirpost(char *arg, char *rp, UNUSED(struct stat const *sp), void *magic)
{
struct rmmagic *rmm = magic;
if(rmm->opt_interact) {
nicezputs(rmm->nam, stderr);
fputs(": remove `", stderr);
nicezputs(arg, stderr);
fputs("'? ", stderr);
fflush(stderr);
if(!ask())
return 0;
}
if(rmdir(rp) && !rmm->opt_force) {
zwarnnam(rmm->nam, "%s: %e", arg, errno);
return 1;
}
return 0;
}
/**/
int
bin_rm(char *nam, char **args, Options ops, UNUSED(int func))
{
struct rmmagic rmm;
int err;
rmm.nam = nam;
rmm.opt_force = OPT_ISSET(ops,'f');
rmm.opt_interact = OPT_ISSET(ops,'i') && !OPT_ISSET(ops,'f');
rmm.opt_unlinkdir = OPT_ISSET(ops,'d');
err = recursivecmd(nam, OPT_ISSET(ops,'f'),
OPT_ISSET(ops,'r') && !OPT_ISSET(ops,'d'),
OPT_ISSET(ops,'s'),
args, recurse_donothing, rm_dirpost, rm_leaf, &rmm);
return OPT_ISSET(ops,'f') ? 0 : err;
}
/* chown builtin */
struct chownmagic {
char *nam;
uid_t uid;
gid_t gid;
};
/**/
static int
chown_dochown(char *arg, char *rp, UNUSED(struct stat const *sp), void *magic)
{
struct chownmagic *chm = magic;
if(lchown(rp, chm->uid, chm->gid)) {
zwarnnam(chm->nam, "%s: %e", arg, errno);
return 1;
}
return 0;
}
/**/
static unsigned long getnumeric(char *p, int *errp)
{
unsigned long ret;
if(*p < '0' || *p > '9') {
*errp = 1;
return 0;
}
ret = strtoul(p, &p, 10);
*errp = !!*p;
return ret;
}
//enum { BIN_CHOWN, BIN_CHGRP };
/**/
int
bin_chown(char *nam, char **args, Options ops, int func)
{
struct chownmagic chm;
char *uspec = ztrdup(*args), *p = uspec;
char *end;
chm.nam = nam;
if(func == BIN_CHGRP) {
chm.uid = (uid_t)-1;
goto dogroup;
}
end = strchr(uspec, ':');
if(!end)
end = strchr(uspec, '.');
if(end == uspec) {
chm.uid = (uid_t)-1;
p++;
goto dogroup;
} else {
struct passwd *pwd;
if(end)
*end = 0;
pwd = getpwnam(p);
if(pwd)
chm.uid = pwd->pw_uid;
else {
int err;
chm.uid = getnumeric(p, &err);
if(err) {
zwarnnam(nam, "%s: no such user", p, 0);
free(uspec);
return 1;
}
}
if(end) {
p = end+1;
if(!*p) {
if(!pwd && !(pwd = getpwuid(chm.uid))) {
zwarnnam(nam, "%s: no such user", uspec, 0);
free(uspec);
return 1;
}
chm.gid = pwd->pw_gid;
} else if(p[0] == ':' && !p[1]) {
chm.gid = (gid_t)-1;
} else {
struct group *grp;
dogroup:
grp = getgrnam(p);
if(grp)
chm.gid = grp->gr_gid;
else {
int err;
chm.gid = getnumeric(p, &err);
if(err) {
zwarnnam(nam, "%s: no such group", p, 0);
free(uspec);
return 1;
}
}
}
} else
chm.gid = (gid_t)-1;
}
free(uspec);
return recursivecmd(nam, 0, OPT_ISSET(ops,'R'), OPT_ISSET(ops,'s'),
args + 1, chown_dochown, recurse_donothing, chown_dochown, &chm);
}
/* module paraphernalia */
#ifdef HAVE_LSTAT
# define LN_OPTS "dfis"
#else
# define LN_OPTS "dfi"
#endif
static struct builtin bintab[] = {
BUILTIN("chgrp", 0, bin_chown, 2, -1, BIN_CHGRP, "Rs", NULL),
BUILTIN("chown", 0, bin_chown, 2, -1, BIN_CHOWN, "Rs", NULL),
BUILTIN("ln", 0, bin_ln, 1, -1, BIN_LN, LN_OPTS, NULL),
// BUILTIN("mkdir", 0, bin_mkdir, 1, -1, 0, "pm:", NULL),
BUILTIN("mv", 0, bin_ln, 2, -1, BIN_MV, "fi", NULL),
BUILTIN("rm", 0, bin_rm, 1, -1, 0, "dfirs", NULL),
BUILTIN("rmdir", 0, bin_rmdir, 1, -1, 0, NULL, NULL),
BUILTIN("sync", 0, bin_sync, 0, 0, 0, NULL, NULL),
};
/**/
int
setup_(UNUSED(Module m))
{
return 0;
}
/**/
int
boot_(Module m)
{
return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
}
/**/
int
cleanup_(Module m)
{
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
return 0;
}
/**/
int
finish_(UNUSED(Module m))
{
return 0;
}