"Fossies" - the Fresh Open Source Software Archive

Member "epm-4.5.1/deb.c" (18 Nov 2020, 15876 Bytes) of package /linux/privat/epm-4.5.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "deb.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.5_vs_4.5.1.

    1 /*
    2  * Debian package gateway for the ESP Package Manager (EPM).
    3  *
    4  * Copyright © 1999-2020 by Michael R Sweet
    5  * Copyright © 1999-2010 by Easy Software Products.
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2, or (at your option)
   10  * any later version.
   11  *
   12  * This program is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  * GNU General Public License for more details.
   16  */
   17 
   18 /*
   19  * Include necessary headers...
   20  */
   21 
   22 #include "epm.h"
   23 
   24 
   25 /*
   26  * Local functions...
   27  */
   28 
   29 static int  make_subpackage(const char *prodname, const char *directory,
   30                         const char *platname, dist_t *dist,
   31                         struct utsname *platform,
   32                 const char *subpackage);
   33 
   34 
   35 /*
   36  * 'make_deb()' - Make a Debian software distribution package.
   37  */
   38 
   39 int                 /* O - 0 = success, 1 = fail */
   40 make_deb(const char     *prodname,  /* I - Product short name */
   41          const char     *directory, /* I - Directory for distribution files */
   42          const char     *platname,  /* I - Platform name */
   43          dist_t         *dist,      /* I - Distribution information */
   44      struct utsname *platform)  /* I - Platform information */
   45 {
   46   int       i;          /* Looping var */
   47   tarf_t    *tarfile;       /* Distribution tar file */
   48   char      name[1024],     /* Full product name */
   49         filename[1024];     /* File to archive */
   50 
   51 
   52  /* Debian packages use "amd64" instead of "x86_64" for the architecture... */
   53   if (!strcmp(platname, "x86_64"))
   54     platname = "amd64";
   55 
   56   if (make_subpackage(prodname, directory, platname, dist, platform, NULL))
   57     return (1);
   58 
   59   for (i = 0; i < dist->num_subpackages; i ++)
   60     if (make_subpackage(prodname, directory, platname, dist, platform,
   61                         dist->subpackages[i]))
   62       return (1);
   63 
   64  /*
   65   * Build a compressed tar file to hold all of the subpackages...
   66   */
   67 
   68   if (dist->num_subpackages)
   69   {
   70    /*
   71     * Figure out the full name of the distribution...
   72     */
   73 
   74     if (dist->release[0])
   75       snprintf(name, sizeof(name), "%s-%s-%s", prodname, dist->version,
   76                dist->release);
   77     else
   78       snprintf(name, sizeof(name), "%s-%s", prodname, dist->version);
   79 
   80     if (platname[0])
   81     {
   82       strlcat(name, "-", sizeof(name));
   83       strlcat(name, platname, sizeof(name));
   84     }
   85 
   86    /*
   87     * Create a compressed tar file...
   88     */
   89 
   90     snprintf(filename, sizeof(filename), "%s/%s.deb.tgz", directory, name);
   91 
   92     if ((tarfile = tar_open(filename, 1)) == NULL)
   93       return (1);
   94 
   95    /*
   96     * Archive the main package and subpackages...
   97     */
   98 
   99     if (tar_package(tarfile, "deb", prodname, directory, platname, dist, NULL))
  100     {
  101       tar_close(tarfile);
  102       return (1);
  103     }
  104 
  105     for (i = 0; i < dist->num_subpackages; i ++)
  106     {
  107       if (tar_package(tarfile, "deb", prodname, directory, platname, dist,
  108                       dist->subpackages[i]))
  109       {
  110     tar_close(tarfile);
  111     return (1);
  112       }
  113     }
  114 
  115     tar_close(tarfile);
  116   }
  117 
  118  /*
  119   * Remove temporary files...
  120   */
  121 
  122   if (!KeepFiles && dist->num_subpackages)
  123   {
  124     if (Verbosity)
  125       puts("Removing temporary distribution files...");
  126 
  127    /*
  128     * Remove .deb files since they are now in a .tgz file...
  129     */
  130 
  131     unlink_package("deb", prodname, directory, platname, dist, NULL);
  132 
  133     for (i = 0; i < dist->num_subpackages; i ++)
  134       unlink_package("deb", prodname, directory, platname, dist,
  135                      dist->subpackages[i]);
  136   }
  137 
  138   return (0);
  139 }
  140 
  141 
  142 /*
  143  * 'make_subpackage()' - Make a subpackage...
  144  */
  145 
  146 static int              /* O - 0 = success, 1 = fail */
  147 make_subpackage(const char     *prodname,
  148                     /* I - Product short name */
  149                 const char     *directory,
  150                     /* I - Directory for distribution files */
  151                 const char     *platname,
  152                     /* I - Platform name */
  153                 dist_t         *dist,   /* I - Distribution information */
  154             struct utsname *platform,
  155                     /* I - Platform information */
  156         const char     *subpackage)
  157                     /* I - Subpackage */
  158 {
  159   int           i, j;       /* Looping vars */
  160   const char        *header;    /* Dependency header string */
  161   FILE          *fp;        /* Control file */
  162   char          prodfull[255],  /* Full name of product */
  163             name[1024], /* Full product name */
  164             filename[1024]; /* Destination filename */
  165   command_t     *c;     /* Current command */
  166   depend_t      *d;     /* Current dependency */
  167   file_t        *file;      /* Current distribution file */
  168   struct passwd     *pwd;       /* Pointer to user record */
  169   struct group      *grp;       /* Pointer to group record */
  170   static const char *depends[] =    /* Dependency names */
  171             {
  172               "Depends:",
  173               "Conflicts:",
  174               "Replaces:",
  175               "Provides:"
  176             };
  177 
  178 
  179  /*
  180   * Figure out the full name of the distribution...
  181   */
  182 
  183   if (subpackage)
  184     snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
  185   else
  186     strlcpy(prodfull, prodname, sizeof(prodfull));
  187 
  188  /*
  189   * Then the subdirectory name...
  190   */
  191 
  192   if (dist->release[0])
  193     snprintf(name, sizeof(name), "%s-%s-%s", prodfull, dist->version,
  194              dist->release);
  195   else
  196     snprintf(name, sizeof(name), "%s-%s", prodfull, dist->version);
  197 
  198   if (platname[0])
  199   {
  200     strlcat(name, "-", sizeof(name));
  201     strlcat(name, platname, sizeof(name));
  202   }
  203 
  204   if (Verbosity)
  205     printf("Creating Debian %s distribution...\n", name);
  206 
  207  /*
  208   * Write the control file for DPKG...
  209   */
  210 
  211   if (Verbosity)
  212     puts("Creating control file...");
  213 
  214   snprintf(filename, sizeof(filename), "%s/%s", directory, name);
  215   mkdir(filename, 0777);
  216   strlcat(filename, "/DEBIAN", sizeof(filename));
  217   mkdir(filename, 0777);
  218   chmod(filename, 0755);
  219 
  220   strlcat(filename, "/control", sizeof(filename));
  221 
  222   if ((fp = fopen(filename, "w")) == NULL)
  223   {
  224     fprintf(stderr, "epm: Unable to create control file \"%s\": %s\n", filename, strerror(errno));
  225     return (1);
  226   }
  227 
  228   fprintf(fp, "Package: %s\n", prodfull);
  229   if (dist->release[0])
  230     fprintf(fp, "Version: %s-%s\n", dist->version, dist->release);
  231   else
  232     fprintf(fp, "Version: %s\n", dist->version);
  233   fprintf(fp, "Maintainer: %s\n", dist->vendor);
  234 
  235  /*
  236   * The Architecture attribute needs to match the uname info
  237   * (which we change in get_platform to a common name)
  238   */
  239 
  240   if (!strcmp(platform->machine, "intel"))
  241     fputs("Architecture: i386\n", fp);
  242   if (!strcmp(platform->machine, "x86_64"))
  243     fputs("Architecture: amd64\n", fp);
  244   else if (!strcmp(platform->machine, "ppc"))
  245     fputs("Architecture: powerpc\n", fp);
  246   else
  247     fprintf(fp, "Architecture: %s\n", platform->machine);
  248 
  249   fprintf(fp, "Description: %s\n", dist->product);
  250   fprintf(fp, " Copyright: %s\n", dist->copyright);
  251   for (i = 0; i < dist->num_descriptions; i ++)
  252     if (dist->descriptions[i].subpackage == subpackage)
  253       fprintf(fp, " %s\n", dist->descriptions[i].description);
  254 
  255   for (j = DEPEND_REQUIRES; j <= DEPEND_PROVIDES; j ++)
  256   {
  257     for (i = dist->num_depends, d = dist->depends; i > 0; i --, d ++)
  258       if (d->type == j && d->subpackage == subpackage)
  259     break;
  260 
  261     if (i)
  262     {
  263       for (header = depends[j]; i > 0; i --, d ++, header = ",")
  264     if (d->type == j && d->subpackage == subpackage)
  265     {
  266       if (!strcmp(d->product, "_self"))
  267             fprintf(fp, "%s %s", header, prodname);
  268       else
  269             fprintf(fp, "%s %s", header, d->product);
  270 
  271       if (d->vernumber[0] == 0)
  272       {
  273         if (d->vernumber[1] < INT_MAX)
  274               fprintf(fp, " (<= %s)", d->version[1]);
  275       }
  276       else
  277       {
  278         if (d->vernumber[1] < INT_MAX)
  279           fprintf(fp, " (>= %s), %s (<= %s)", d->version[0], d->product, d->version[1]);
  280         else
  281           fprintf(fp, " (>= %s)", d->version[0]);
  282       }
  283     }
  284 
  285       putc('\n', fp);
  286     }
  287   }
  288 
  289   for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  290     if (c->type == COMMAND_LITERAL && c->subpackage == subpackage &&
  291         !strcmp(c->section, "control"))
  292       break;
  293 
  294   if (i > 0)
  295   {
  296     for (; i > 0; i --, c ++)
  297       if (c->type == COMMAND_LITERAL && c->subpackage == subpackage &&
  298       !strcmp(c->section, "control"))
  299     fprintf(fp, "%s\n", c->command);
  300   }
  301 
  302   fclose(fp);
  303 
  304  /*
  305   * Write the preinst file for DPKG...
  306   */
  307 
  308   for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  309     if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage)
  310       break;
  311 
  312   if (i)
  313   {
  314     if (Verbosity)
  315       puts("Creating preinst script...");
  316 
  317     snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/preinst", directory, name);
  318 
  319     if ((fp = fopen(filename, "w")) == NULL)
  320     {
  321       fprintf(stderr, "epm: Unable to create script file \"%s\": %s\n", filename, strerror(errno));
  322       return (1);
  323     }
  324 
  325     fchmod(fileno(fp), 0755);
  326 
  327     fputs("#!/bin/sh\n", fp);
  328     fputs("# " EPM_VERSION "\n", fp);
  329 
  330     for (; i > 0; i --, c ++)
  331       if (c->type == COMMAND_PRE_INSTALL && c->subpackage == subpackage)
  332         fprintf(fp, "%s\n", c->command);
  333 
  334     fclose(fp);
  335   }
  336 
  337  /*
  338   * Write the postinst file for DPKG...
  339   */
  340 
  341   for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  342     if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage)
  343       break;
  344 
  345   if (!i)
  346     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  347       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
  348         break;
  349 
  350   if (i)
  351   {
  352     if (Verbosity)
  353       puts("Creating postinst script...");
  354 
  355     snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/postinst", directory, name);
  356 
  357     if ((fp = fopen(filename, "w")) == NULL)
  358     {
  359       fprintf(stderr, "epm: Unable to create script file \"%s\": %s\n", filename, strerror(errno));
  360       return (1);
  361     }
  362 
  363     fchmod(fileno(fp), 0755);
  364 
  365     fputs("#!/bin/sh\n", fp);
  366     fputs("# " EPM_VERSION "\n", fp);
  367 
  368     for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  369       if (c->type == COMMAND_POST_INSTALL && c->subpackage == subpackage)
  370         fprintf(fp, "%s\n", c->command);
  371 
  372     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  373       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
  374       {
  375        /*
  376         * Debian's update-rc.d has changed over the years; current practice is
  377         * to let update-rc.d choose the runlevels and ordering...
  378         */
  379 
  380         fprintf(fp, "update-rc.d %s defaults\n", file->dst);
  381         fprintf(fp, "/etc/init.d/%s start\n", file->dst);
  382       }
  383 
  384     fclose(fp);
  385   }
  386 
  387  /*
  388   * Write the prerm file for DPKG...
  389   */
  390 
  391   for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  392     if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage)
  393       break;
  394 
  395   if (!i)
  396     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  397       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
  398         break;
  399 
  400   if (i)
  401   {
  402     if (Verbosity)
  403       puts("Creating prerm script...");
  404 
  405     snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/prerm", directory, name);
  406 
  407     if ((fp = fopen(filename, "w")) == NULL)
  408     {
  409       fprintf(stderr, "epm: Unable to create script file \"%s\": %s\n", filename, strerror(errno));
  410       return (1);
  411     }
  412 
  413     fchmod(fileno(fp), 0755);
  414 
  415     fputs("#!/bin/sh\n", fp);
  416     fputs("# " EPM_VERSION "\n", fp);
  417 
  418     for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  419       if (c->type == COMMAND_PRE_REMOVE && c->subpackage == subpackage)
  420         fprintf(fp, "%s\n", c->command);
  421 
  422     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  423       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
  424         fprintf(fp, "/etc/init.d/%s stop\n", file->dst);
  425 
  426     fclose(fp);
  427   }
  428 
  429  /*
  430   * Write the postrm file for DPKG...
  431   */
  432 
  433   for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  434     if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage)
  435       break;
  436 
  437   if (!i)
  438     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  439       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
  440         break;
  441 
  442   if (i)
  443   {
  444     if (Verbosity)
  445       puts("Creating postrm script...");
  446 
  447     snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/postrm", directory, name);
  448 
  449     if ((fp = fopen(filename, "w")) == NULL)
  450     {
  451       fprintf(stderr, "epm: Unable to create script file \"%s\": %s\n", filename, strerror(errno));
  452       return (1);
  453     }
  454 
  455     fchmod(fileno(fp), 0755);
  456 
  457     fputs("#!/bin/sh\n", fp);
  458     fputs("# " EPM_VERSION "\n", fp);
  459 
  460     for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  461       if (c->type == COMMAND_POST_REMOVE && c->subpackage == subpackage)
  462     fprintf(fp, "%s\n", c->command);
  463 
  464     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  465       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
  466       {
  467         fputs("if [ purge = \"$1\" ]; then\n", fp);
  468         fprintf(fp, "   update-rc.d %s remove\n", file->dst);
  469         fputs("fi\n", fp);
  470       }
  471 
  472     fclose(fp);
  473   }
  474 
  475  /*
  476   * Write the conffiles file for DPKG...
  477   */
  478 
  479   if (Verbosity)
  480     puts("Creating conffiles...");
  481 
  482   snprintf(filename, sizeof(filename), "%s/%s/DEBIAN/conffiles", directory, name);
  483 
  484   if ((fp = fopen(filename, "w")) == NULL)
  485   {
  486     fprintf(stderr, "epm: Unable to create script file \"%s\": %s\n", filename, strerror(errno));
  487     return (1);
  488   }
  489 
  490   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  491     if (tolower(file->type) == 'c' && file->subpackage == subpackage)
  492       fprintf(fp, "%s\n", file->dst);
  493     else if (tolower(file->type) == 'i' && file->subpackage == subpackage)
  494       fprintf(fp, "/etc/init.d/%s\n", file->dst);
  495 
  496   fclose(fp);
  497 
  498  /*
  499   * Copy the files over...
  500   */
  501 
  502   if (Verbosity)
  503     puts("Copying temporary distribution files...");
  504 
  505   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  506   {
  507     if (file->subpackage != subpackage)
  508       continue;
  509 
  510    /*
  511     * Find the username and groupname IDs...
  512     */
  513 
  514     pwd = getpwnam(file->user);
  515     grp = getgrnam(file->group);
  516 
  517     endpwent();
  518     endgrent();
  519 
  520    /*
  521     * Copy the file or make the directory or make the symlink as needed...
  522     */
  523 
  524     switch (tolower(file->type))
  525     {
  526       case 'c' :
  527       case 'f' :
  528           snprintf(filename, sizeof(filename), "%s/%s%s", directory, name,
  529                file->dst);
  530 
  531       if (Verbosity > 1)
  532         printf("%s -> %s...\n", file->src, filename);
  533 
  534       if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0,
  535             grp ? grp->gr_gid : 0))
  536         return (1);
  537           break;
  538       case 'i' :
  539           snprintf(filename, sizeof(filename), "%s/%s/etc/init.d/%s",
  540                directory, name, file->dst);
  541 
  542       if (Verbosity > 1)
  543         printf("%s -> %s...\n", file->src, filename);
  544 
  545       if (copy_file(filename, file->src, file->mode, pwd ? pwd->pw_uid : 0,
  546             grp ? grp->gr_gid : 0))
  547         return (1);
  548           break;
  549       case 'd' :
  550           snprintf(filename, sizeof(filename), "%s/%s%s", directory, name,
  551                file->dst);
  552 
  553       if (Verbosity > 1)
  554         printf("Directory %s...\n", filename);
  555 
  556           make_directory(filename, file->mode, pwd ? pwd->pw_uid : 0,
  557              grp ? grp->gr_gid : 0);
  558           break;
  559       case 'l' :
  560           snprintf(filename, sizeof(filename), "%s/%s%s", directory, name,
  561                file->dst);
  562 
  563       if (Verbosity > 1)
  564         printf("%s -> %s...\n", file->src, filename);
  565 
  566           make_link(filename, file->src);
  567           break;
  568     }
  569   }
  570 
  571  /*
  572   * Build the distribution from the spec file...
  573   */
  574 
  575   if (Verbosity)
  576     printf("Building Debian %s binary distribution...\n", name);
  577 
  578   if (run_command(directory, "dpkg --build %s", name))
  579     return (1);
  580 
  581  /*
  582   * Remove temporary files...
  583   */
  584 
  585   if (!KeepFiles)
  586   {
  587     if (Verbosity)
  588       printf("Removing temporary %s distribution files...\n", name);
  589 
  590     snprintf(filename, sizeof(filename), "%s/%s", directory, name);
  591     unlink_directory(filename);
  592   }
  593 
  594   return (0);
  595 }