diff options
author | Ian Jackson <ian@chiark.chu.cam.ac.uk> | 1996-04-04 01:58:40 +0100 |
---|---|---|
committer | Ian Jackson <ian@chiark.chu.cam.ac.uk> | 1996-04-04 01:58:40 +0100 |
commit | 1b80fb16c22db72457d7a456ffbf1f70a8dfc0a5 (patch) | |
tree | c0ee53eba4e71f4c246ee9e45fbd90e931bbd1f9 /dselect/methparse.cc | |
download | dpkg-1b80fb16c22db72457d7a456ffbf1f70a8dfc0a5.tar.gz |
dpkg (1.1.4); priority=MEDIUM
* Allow overwriting of conflicting packages being removed. (Bug#2614.)
* a.out control file says Pre-Depends: libc4 | libc. (Bug#2640.)
* ELF control file and libc dependencies changed to use finalised scheme.
* ELF control file and libc dependencies for i386 only. (Bug#2617.)
* Guidelines say use only released libraries and compilers.
* Install wishlist as /usr/doc/dpkg/WISHLIST.
* Remove spurious entries for Guidelines in info dir file.
* dpkg-deb --build checks permissions on control (DEBIAN) directory.
* Spaces in control file fields not copied by dpkg-split. (Bug#2633.)
* Spaces in split file part control data ignore. (Bug#2633.)
* Portability fixes, including patch from Richard Kettlewell.
* Fixed minor configure.in bug causing mangled GCC -W options.
-- Ian Jackson <ian@chiark.chu.cam.ac.uk> Thu, 4 Apr 1996 01:58:40 +0100
Diffstat (limited to 'dselect/methparse.cc')
-rw-r--r-- | dselect/methparse.cc | 289 |
1 files changed, 289 insertions, 0 deletions
diff --git a/dselect/methparse.cc b/dselect/methparse.cc new file mode 100644 index 000000000..02e51b41a --- /dev/null +++ b/dselect/methparse.cc @@ -0,0 +1,289 @@ +/* + * dselect - Debian GNU/Linux package maintenance user interface + * methparse.cc - access method list parsing + * + * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk> + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <signal.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <unistd.h> +#include <dirent.h> +#include <limits.h> +#include <ctype.h> +#include <assert.h> + +#include <ncurses.h> + +extern "C" { +#include "config.h" +#include "dpkg.h" +#include "dpkg-db.h" +} +#include "dselect.h" +#include "bindings.h" + +int noptions=0; +struct option *options=0, *coption=0; +struct method *methods=0; + +static void badmethod(const char *pathname, const char *why) __NORETURN; +static void badmethod(const char *pathname, const char *why) { + ohshit("syntax error in method options file `%.250s' -- %s", pathname, why); +} + +static void eofmethod(const char *pathname, FILE *f, const char *why) __NORETURN; +static void eofmethod(const char *pathname, FILE *f, const char *why) { + if (ferror(f)) ohshite("error reading options file `%.250s'",pathname); + badmethod(pathname,why); +} + +void readmethods(const char *pathbase, option **optionspp, int *nread) { + static const char *const methodprograms[]= { + METHODSETUPSCRIPT, METHODUPDATESCRIPT, METHODINSTALLSCRIPT, 0 + }; + const char *const *ccpp; + int methodlen, c, baselen; + char *p, *pathinmeth, *pathbuf, *pathmeth; + DIR *dir; + FILE *names, *descfile; + struct dirent *dent; + struct varbuf vb; + method *meth; + option *opt, **optinsert; + struct stat stab; + + baselen= strlen(pathbase); + pathbuf= new char[baselen+IMETHODMAXLEN+IOPTIONMAXLEN+sizeof(OPTIONSDESCPFX)+10]; + strcpy(pathbuf,pathbase); + strcpy(pathbuf+baselen,"/"); + pathmeth= pathbuf+baselen+1; + + dir= opendir(pathbuf); + if (!dir) { + if (errno == ENOENT) return; + ohshite("unable to read `%.250s' directory for reading methods",pathbuf); + } + + if (debug) fprintf(debug,"readmethods(`%s',...) directory open\n", pathbase); + + while ((dent= readdir(dir)) != 0) { + c= dent->d_name[0]; + if (debug) fprintf(debug,"readmethods(`%s',...) considering `%s' ...\n", + pathbase,dent->d_name); + if (c != '_' && !isalpha(c)) continue; + for (p= dent->d_name+1; (c= *p) != 0 && isalnum(c) && c != '_'; p++); + if (c) continue; + methodlen= strlen(dent->d_name); + if (methodlen > IMETHODMAXLEN) + ohshit("method `%.250s' has name that is too long (%d > %d characters)", + dent->d_name, methodlen, IMETHODMAXLEN); + strcpy(pathmeth, dent->d_name); + strcpy(pathmeth+methodlen, "/"); + pathinmeth= pathmeth+methodlen+1; + + for (ccpp= methodprograms; *ccpp; ccpp++) { + strcpy(pathinmeth,*ccpp); + if (access(pathbuf,R_OK|X_OK)) + ohshite("unable to access method script `%.250s'",pathbuf); + } + if (debug) fprintf(debug," readmethods(`%s',...) scripts ok\n", pathbase); + + strcpy(pathinmeth,METHODOPTIONSFILE); + names= fopen(pathbuf,"r"); + if (!names) ohshite("unable to read method options file `%.250s'",pathbuf); + + meth= new method; + meth->name= new char[strlen(dent->d_name)+1]; + strcpy(meth->name,dent->d_name); + meth->path= new char[baselen+1+methodlen+2+50]; + strncpy(meth->path,pathbuf,baselen+1+methodlen); + strcpy(meth->path+baselen+1+methodlen,"/"); + meth->pathinmeth= meth->path+baselen+1+methodlen+1; + meth->next= methods; + meth->back= 0; + if (methods) methods->back= meth; + methods= meth; + if (debug) fprintf(debug," readmethods(`%s',...) new method" + " name=`%s' path=`%s' pathinmeth=`%s'\n", + pathbase, meth->name, meth->path, meth->pathinmeth); + + while ((c= fgetc(names)) != EOF) { + if (isspace(c)) continue; + opt= new option; + opt->meth= meth; + vb.reset(); + do { + if (!isdigit(c)) badmethod(pathbuf,"non-digit where digit wanted"); + vb(c); + c= fgetc(names); + if (c == EOF) eofmethod(pathbuf,names,"EOF in index string"); + } while (!isspace(c)); + if (strlen(vb.string()) > OPTIONINDEXMAXLEN) + badmethod(pathbuf,"index string too long"); + strcpy(opt->index,vb.string()); + do { + if (c == '\n') badmethod(pathbuf,"newline before option name start"); + c= fgetc(names); + if (c == EOF) eofmethod(pathbuf,names,"EOF before option name start"); + } while (isspace(c)); + vb.reset(); + if (!isalpha(c) && c != '_') + badmethod(pathbuf,"nonalpha where option name start wanted"); + do { + if (!isalnum(c) && c != '_') badmethod(pathbuf,"non-alphanum in option name"); + vb(c); + c= fgetc(names); + if (c == EOF) eofmethod(pathbuf,names,"EOF in option name"); + } while (!isspace(c)); + opt->name= new char[strlen(vb.string())+1]; + strcpy(opt->name,vb.string()); + do { + if (c == '\n') badmethod(pathbuf,"newline before summary"); + c= fgetc(names); + if (c == EOF) eofmethod(pathbuf,names,"EOF before summary"); + } while (isspace(c)); + vb.reset(); + do { + vb(c); + c= fgetc(names); + if (c == EOF) eofmethod(pathbuf,names,"EOF in summary - missing newline"); + } while (c != '\n'); + opt->summary= new char[strlen(vb.string())+1]; + strcpy(opt->summary,vb.string()); + + strcpy(pathinmeth,OPTIONSDESCPFX); + strcpy(pathinmeth+sizeof(OPTIONSDESCPFX)-1,opt->name); + descfile= fopen(pathbuf,"r"); + if (!descfile) { + if (errno != ENOENT) + ohshite("unable to open option description file `%.250s'",pathbuf); + opt->description= 0; + } else { /* descfile != 0 */ + if (fstat(fileno(descfile),&stab)) + ohshite("unable to stat option description file `%.250s'",pathbuf); + opt->description= new char[stab.st_size+1]; errno=0; + if (fread(opt->description,1,stab.st_size+1,descfile) != stab.st_size) + ohshite("failed to read option description file `%.250s'",pathbuf); + opt->description[stab.st_size]= 0; + if (ferror(descfile)) + ohshite("error during read of option description file `%.250s'",pathbuf); + fclose(descfile); + } + strcpy(pathinmeth,METHODOPTIONSFILE); + + if (debug) fprintf(debug," readmethods(`%s',...) new option" + " index=`%s' name=`%s' summary=`%.20s'" + " strlen(description=%s)=%d" + " method name=`%s' path=`%s' pathinmeth=`%s'\n", + pathbase, + opt->index, opt->name, opt->summary, + opt->description ? "`...'" : "null", + opt->description ? strlen(opt->description) : -1, + opt->meth->name, opt->meth->path, opt->meth->pathinmeth); + for (optinsert= optionspp; + *optinsert && strcmp(opt->index,(*optinsert)->index) > 0; + optinsert= &(*optinsert)->next); + opt->next= *optinsert; + *optinsert= opt; + (*nread)++; + } + if (ferror(names)) + ohshite("error during read of method options file `%.250s'",pathbuf); + fclose(names); + } + closedir(dir); + if (debug) fprintf(debug,"readmethods(`%s',...) done\n", pathbase); + delete[] pathbuf; +} + +static char *methoptfile= 0; + +void getcurrentopt() { + char methoptbuf[IMETHODMAXLEN+1+IOPTIONMAXLEN+2]; + FILE *cmo; + int l; + int admindirlen; + char *p; + method *meth; + option *opt; + + if (!methoptfile) { + admindirlen= strlen(admindir); + methoptfile= new char[admindirlen + sizeof(CMETHOPTFILE) + 2]; + strcpy(methoptfile,admindir); + strcpy(methoptfile+admindirlen, "/" CMETHOPTFILE); + } + + coption= 0; + cmo= fopen(methoptfile,"r"); + if (!cmo) { + if (errno == ENOENT) return; + ohshite("unable to open current option file `%.250s'",methoptfile); + } + if (debug) fprintf(debug,"getcurrentopt() cmethopt open\n"); + if (!fgets(methoptbuf,sizeof(methoptbuf),cmo)) { fclose(cmo); return; } + if (fgetc(cmo) != EOF) { fclose(cmo); return; } + if (!feof(cmo)) { fclose(cmo); return; } + if (debug) fprintf(debug,"getcurrentopt() cmethopt eof\n"); + fclose(cmo); + if (debug) fprintf(debug,"getcurrentopt() cmethopt read\n"); + l= strlen(methoptbuf); if (!l || methoptbuf[l-1] != '\n') return; + methoptbuf[--l]= 0; + if (debug) fprintf(debug,"getcurrentopt() cmethopt len and newline\n"); + p= strchr(methoptbuf,' '); if (!p) return; + if (debug) fprintf(debug,"getcurrentopt() cmethopt space\n"); + *p++= 0; + if (debug) fprintf(debug,"getcurrentopt() cmethopt meth name `%s'\n", methoptbuf); + for (meth= methods; meth && strcmp(methoptbuf,meth->name); meth= meth->next); + if (!meth) return; + if (debug) fprintf(debug,"getcurrentopt() cmethopt meth found; opt `%s'\n",p); + for (opt= options; opt && (opt->meth != meth || strcmp(p,opt->name)); opt= opt->next); + if (!opt) return; + if (debug) fprintf(debug,"getcurrentopt() cmethopt opt found\n"); + coption= opt; +} + +void writecurrentopt() { + FILE *cmo; + int l; + static char *newfile=0; + + assert(methoptfile); + if (!newfile) { + l= strlen(methoptfile); + newfile= new char[l + sizeof(NEWDBEXT) + 1]; + strcpy(newfile,methoptfile); + strcpy(newfile+l, NEWDBEXT); + } + cmo= fopen(newfile,"w"); + if (!cmo) ohshite("unable to open new option file `%.250s'",newfile); + if (fprintf(cmo,"%s %s\n",coption->meth->name,coption->name) == EOF) { + fclose(cmo); + ohshite("unable to write new option to `%.250s'",newfile); + } + if (fclose(cmo)) + ohshite("unable to close new option file `%.250s'",newfile); + if (rename(newfile,methoptfile)) + ohshite("unable to install new option as `%.250s'",methoptfile); +} |