11/************************************************************************** 
2-  *   
2+  * 
33 * Copyright (c) 2004-19 Simon Peter 
4-  *   
4+  * 
55 * All Rights Reserved. 
6-  *   
6+  * 
77 * Permission is hereby granted, free of charge, to any person obtaining a copy 
88 * of this software and associated documentation files (the "Software"), to deal 
99 * in the Software without restriction, including without limitation the rights 
1010 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
1111 * copies of the Software, and to permit persons to whom the Software is 
1212 * furnished to do so, subject to the following conditions: 
13-  *   
13+  * 
1414 * The above copyright notice and this permission notice shall be included in 
1515 * all copies or substantial portions of the Software. 
16-  *   
16+  * 
1717 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
1818 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
1919 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
2020 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
2121 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
2222 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
2323 * THE SOFTWARE. 
24-  *   
24+  * 
2525 **************************************************************************/ 
2626
2727#ident  "AppImage by Simon Peter, http://appimage.org/"
@@ -65,7 +65,7 @@ extern char runtime[];
6565extern  unsigned int   runtime_len ;
6666#endif 
6767
68- enum  fARCH  {  
68+ enum  fARCH  {
6969    fARCH_i386 ,
7070    fARCH_x86_64 ,
7171    fARCH_arm ,
@@ -105,7 +105,7 @@ int sfs_ls(char* image) {
105105    sqfs_err  err  =  SQFS_OK ;
106106    sqfs_traverse  trv ;
107107    sqfs  fs ;
108-      
108+ 
109109    ssize_t  fs_offset  =  appimage_get_elf_size (image );
110110
111111    // error check 
@@ -114,7 +114,7 @@ int sfs_ls(char* image) {
114114
115115    if  ((err  =  sqfs_open_image (& fs , image , fs_offset )))
116116        die ("sqfs_open_image error" );
117-      
117+ 
118118    if  ((err  =  sqfs_traverse_open (& trv , & fs , sqfs_inode_root (& fs ))))
119119        die ("sqfs_traverse_open error" );
120120    while  (sqfs_traverse_next (& trv , & err )) {
@@ -125,12 +125,12 @@ int sfs_ls(char* image) {
125125    if  (err )
126126        die ("sqfs_traverse_next error" );
127127    sqfs_traverse_close (& trv );
128-      
128+ 
129129    sqfs_fd_close (fs .fd );
130130    return  0 ;
131131}
132132
133- /* Generate a squashfs filesystem using mksquashfs on the $PATH   
133+ /* Generate a squashfs filesystem using mksquashfs on the $PATH 
134134* execlp(), execvp(), and execvpe() search on the $PATH */ 
135135int  sfs_mksquashfs (char  * source , char  * destination , int  offset ) {
136136    pid_t  pid  =  fork ();
@@ -146,13 +146,13 @@ int sfs_mksquashfs(char *source, char *destination, int offset) {
146146            perror ("sfs_mksquashfs waitpid() failed" );
147147            return (-1 );
148148        }
149-          
149+ 
150150        int  retcode  =  WEXITSTATUS (status );
151151        if  (retcode ) {
152152            fprintf (stderr , "mksquashfs (pid %d) exited with code %d\n" , pid , retcode );
153153            return (-1 );
154154        }
155-          
155+ 
156156        return  0 ;
157157    } else  {
158158        // we are the child 
@@ -272,7 +272,7 @@ int validate_desktop_file(char *file) {
272272}
273273
274274/* Generate a squashfs filesystem 
275- * The following would work if we link to mksquashfs.o after we renamed   
275+ * The following would work if we link to mksquashfs.o after we renamed 
276276* main() to mksquashfs_main() in mksquashfs.c but we don't want to actually do 
277277* this because squashfs-tools is not under a permissive license 
278278* i *nt sfs_mksquashfs(char *source, char *destination) { 
@@ -291,19 +291,19 @@ int validate_desktop_file(char *file) {
291291static  void  replacestr (char  * line , const  char  * search , const  char  * replace )
292292{
293293    char  * sp  =  NULL ;
294-      
294+ 
295295    if  ((sp  =  strstr (line , search )) ==  NULL ) {
296296        return ;
297297    }
298298    int  search_len  =  strlen (search );
299299    int  replace_len  =  strlen (replace );
300300    int  tail_len  =  strlen (sp + search_len );
301-      
301+ 
302302    memmove (sp + replace_len ,sp + search_len ,tail_len + 1 );
303303    memcpy (sp , replace , replace_len );
304-      
304+ 
305305    /* Do it recursively again until no more work to do */ 
306-      
306+ 
307307    if  ((sp  =  strstr (line , search ))) {
308308        replacestr (line , search , replace );
309309    }
@@ -447,7 +447,7 @@ gchar* find_first_matching_file_nonrecursive(const gchar *real_path, const gchar
447447        }
448448        g_dir_close (dir );
449449    }
450-     else  {  
450+     else  {
451451        g_warning ("%s: %s" , real_path , g_strerror (errno ));
452452    }
453453    return  NULL ;
@@ -477,7 +477,7 @@ bool readFile(char* filename, int* size, char** buffer) {
477477    fread (indata , fsize , 1 , f );
478478    fclose (f );
479479    * size  =  (int )fsize ;
480-     * buffer  =  indata ;  
480+     * buffer  =  indata ;
481481    return  TRUE;
482482}
483483
542542main  (int  argc , char  * argv [])
543543{
544544
545-     /* Parse Travis CI environment variables.   
545+     /* Parse Travis CI environment variables. 
546546     * https://docs.travis-ci.com/user/environment-variables/#Default-Environment-Variables 
547547     * TRAVIS_COMMIT: The commit that the current build is testing. 
548548     * TRAVIS_REPO_SLUG: The slug (in form: owner_name/repo_name) of the repository currently being built. 
@@ -563,18 +563,18 @@ main (int argc, char *argv[])
563563    /* Parse GitLab CI environment variables. 
564564     * https://docs.gitlab.com/ee/ci/variables/#predefined-variables-environment-variables 
565565     * echo "${CI_PROJECT_URL}/-/jobs/artifacts/${CI_COMMIT_REF_NAME}/raw/QtQuickApp-x86_64.AppImage?job=${CI_JOB_NAME}" 
566-      */      
566+      */ 
567567    char *  CI_PROJECT_URL ;
568568    CI_PROJECT_URL  =  getenv ("CI_PROJECT_URL" );
569569    char *  CI_COMMIT_REF_NAME ;
570570    CI_COMMIT_REF_NAME  =  getenv ("CI_COMMIT_REF_NAME" ); // The branch or tag name for which project is built 
571571    char *  CI_JOB_NAME ;
572572    CI_JOB_NAME  =  getenv ("CI_JOB_NAME" ); // The name of the job as defined in .gitlab-ci.yml 
573-      
573+ 
574574    /* Parse OWD environment variable. 
575575     * If it is available then cd there. It is the original CWD prior to running AppRun */ 
576576    char *  owd_env  =  NULL ;
577-     owd_env  =  getenv ("OWD" );     
577+     owd_env  =  getenv ("OWD" );
578578    if (NULL != owd_env ){
579579        int  ret ;
580580        ret  =  chdir (owd_env );
@@ -583,13 +583,13 @@ main (int argc, char *argv[])
583583            exit (1 );
584584        }
585585    }
586-          
586+ 
587587    GError  * error  =  NULL ;
588588    GOptionContext  * context ;
589589
590590    // initialize help text of argument 
591591    sprintf (_exclude_file_desc , "Uses given file as exclude file for mksquashfs, in addition to %s." , APPIMAGEIGNORE );
592-      
592+ 
593593    context  =  g_option_context_new  ("SOURCE [DESTINATION] - Generate, extract, and inspect AppImages" );
594594    g_option_context_add_main_entries  (context , entries , NULL );
595595    // g_option_context_add_group (context, gtk_get_option_group (TRUE)); 
@@ -646,16 +646,16 @@ main (int argc, char *argv[])
646646        g_print ("WARNING: gpg2 or gpg command is missing, please install it if you want to create digital signatures\n" );
647647    if (! g_find_program_in_path  ("sha256sum" ) &&  ! g_find_program_in_path  ("shasum" ))
648648        g_print ("WARNING: sha256sum or shasum command is missing, please install it if you want to create digital signatures\n" );
649-      
649+ 
650650    if (!& remaining_args [0 ])
651651        die ("SOURCE is missing" );
652-      
652+ 
653653    /* If in list mode */ 
654654    if  (list ){
655655        sfs_ls (remaining_args [0 ]);
656656        exit (0 );
657657    }
658-      
658+ 
659659    /* If the first argument is a directory, then we assume that we should package it */ 
660660    if  (g_file_test (remaining_args [0 ], G_FILE_TEST_IS_DIR )) {
661661        /* Parse VERSION environment variable. 
@@ -709,7 +709,7 @@ main (int argc, char *argv[])
709709        char  * destination ;
710710        char  source [PATH_MAX ];
711711        realpath (remaining_args [0 ], source );
712-          
712+ 
713713        /* Check if *.desktop file is present in source AppDir */ 
714714        gchar  * desktop_file  =  find_first_matching_file_nonrecursive (source , "*.desktop" );
715715        if (desktop_file  ==  NULL ){
@@ -732,7 +732,7 @@ main (int argc, char *argv[])
732732            die (".desktop file cannot be parsed" );
733733        if  (!get_desktop_entry (kf , "Categories" ))
734734            die (".desktop file is missing a Categories= key" );
735-          
735+ 
736736        if (verbose ){
737737            fprintf  (stderr ,"Name: %s\n" , get_desktop_entry (kf , "Name" ));
738738            fprintf  (stderr ,"Icon: %s\n" , get_desktop_entry (kf , "Icon" ));
@@ -765,10 +765,10 @@ main (int argc, char *argv[])
765765        char  app_name_for_filename [PATH_MAX ];
766766        sprintf (app_name_for_filename , "%s" , get_desktop_entry (kf , "Name" ));
767767        replacestr (app_name_for_filename , " " , "_" );
768-          
768+ 
769769        if (verbose )
770770            fprintf  (stderr ,"App name for filename: %s\n" , app_name_for_filename );
771-          
771+ 
772772        if  (remaining_args [1 ]) {
773773            destination  =  remaining_args [1 ];
774774        } else  {
@@ -821,10 +821,10 @@ main (int argc, char *argv[])
821821            fprintf  (stderr , "%s\n" , example_path );
822822            exit (1 );
823823        }
824-         
824+ 
825825        /* Check if .DirIcon is present in source AppDir */ 
826826        gchar  * diricon_path  =  g_build_filename (source , ".DirIcon" , NULL );
827-          
827+ 
828828        if  (! g_file_test (diricon_path , G_FILE_TEST_EXISTS )){
829829            fprintf  (stderr , "Deleting pre-existing .DirIcon\n" );
830830            g_unlink (diricon_path );
@@ -835,20 +835,43 @@ main (int argc, char *argv[])
835835            if (res )
836836                die ("Could not symlink .DirIcon" );
837837        }
838-          
838+ 
839839        /* Check if AppStream upstream metadata is present in source AppDir */ 
840840        if (! no_appstream ){
841-             char  application_id [PATH_MAX ];
842-             sprintf  (application_id ,  "%s" , basename (desktop_file ));
843-             replacestr (application_id , ".desktop" , ".appdata.xml" );
844-             gchar  * appdata_path  =  g_build_filename (source , "/usr/share/metainfo/" , application_id , NULL );
845-             if  (! g_file_test (appdata_path , G_FILE_TEST_IS_REGULAR )){
846-                 fprintf  (stderr , "WARNING: AppStream upstream metadata is missing, please consider creating it\n" );
847-                 fprintf  (stderr , "         in usr/share/metainfo/%s\n" , application_id );
848-                 fprintf  (stderr , "         Please see https://www.freedesktop.org/software/appstream/docs/chap-Quickstart.html#sect-Quickstart-DesktopApps\n" );
849-                 fprintf  (stderr , "         for more information or use the generator at http://output.jsbin.com/qoqukof.\n" );
850-             } else  {
851-                 fprintf  (stderr , "AppStream upstream metadata found in usr/share/metainfo/%s\n" , application_id );
841+         	bool  appstream_found  =  false;
842+         	char  * appstream_filename ;
843+         	gchar  * * appstream_path ;
844+ 
845+         	char  metainfo_filename [PATH_MAX ];
846+         	sprintf (metainfo_filename , "%s" , basename (desktop_file ));
847+         	replacestr (metainfo_filename , ".desktop" , ".metainfo.xml" );
848+         	gchar  * metainfo_path  =  g_build_filename (source , "/usr/share/metainfo/" , metainfo_filename , NULL );
849+         	if  (!g_file_test (metainfo_path , G_FILE_TEST_IS_REGULAR )) {
850+         		char  appdata_filename [PATH_MAX ];
851+                 sprintf (appdata_filename , "%s" , basename (desktop_file ));
852+                 replacestr (appdata_filename , ".desktop" , ".appdata.xml" );
853+                 gchar  * appdata_path  =  g_build_filename (source , "/usr/share/metainfo/" , appdata_filename , NULL );
854+                 if  (!g_file_test (appdata_path , G_FILE_TEST_IS_REGULAR )) {
855+                 	fprintf (stderr , "WARNING: AppStream upstream metadata is missing, please consider creating it\n" );
856+                     fprintf (stderr , "         in usr/share/metainfo/%s\n" , metainfo_filename );
857+                     fprintf (stderr , "         Please see https://www.freedesktop.org/software/appstream/docs/chap-Quickstart.html#sect-Quickstart-DesktopApps\n" );
858+                     fprintf (stderr , "         for more information or use the generator at https://docs.appimage.org/packaging-guide/optional/appstream.html.\n" );
859+                 } else  {
860+                 	appstream_found  =  true;
861+                 	appstream_filename  =  & appdata_filename ;
862+                 	appstream_path  =  & appdata_path ;
863+                 	fprintf (stderr , "WARNING: The appstream upstream metadata file should be named %s.\n" , metainfo_filename );
864+                 	fprintf (stderr , "         .appdata.xml is a legacy file ending and shouldn't be used in new AppImages anymore.\n" );
865+                 	fprintf (stderr , "         See https://www.freedesktop.org/software/appstream/docs/sect-Metadata-Application.html.\n" );
866+                 }
867+         	} else  {
868+         		appstream_found  =  true;
869+         		appstream_filename  =  & metainfo_filename ;
870+         		appstream_path  =  & metainfo_path ;
871+         	}
872+ 
873+         	if  (appstream_found ) {
874+                 fprintf  (stderr , "AppStream upstream metadata found in usr/share/metainfo/%s\n" , * appstream_filename );
852875                /* Use ximion's appstreamcli to make sure that desktop file and appdata match together */ 
853876                if (g_find_program_in_path  ("appstreamcli" )) {
854877                    char  * args [] =  {
@@ -868,7 +891,7 @@ main (int argc, char *argv[])
868891                    char  * args [] =  {
869892                        "appstream-util" ,
870893                        "validate-relax" ,
871-                         appdata_path ,
894+                         * appstream_path ,
872895                        NULL 
873896                    };
874897                    g_print ("Trying to validate AppStream information with the appstream-util tool\n" );
@@ -879,7 +902,7 @@ main (int argc, char *argv[])
879902                }
880903            }
881904        }
882-          
905+ 
883906        /* Upstream mksquashfs can currently not start writing at an offset, 
884907        * so we need a patched one. https://github.com/plougher/squashfs-tools/pull/13 
885908        * should hopefully change that. */ 
@@ -904,11 +927,11 @@ main (int argc, char *argv[])
904927        }
905928        if  (verbose )
906929            printf ("Size of the embedded runtime: %d bytes\n" , size );
907-          
930+ 
908931        int  result  =  sfs_mksquashfs (source , destination , size );
909932        if (result  !=  0 )
910933            die ("sfs_mksquashfs error" );
911-          
934+ 
912935        fprintf  (stderr , "Embedding ELF...\n" );
913936        FILE  * fpdst  =  fopen (destination , "rb+" );
914937        if  (fpdst  ==  NULL ) {
@@ -926,7 +949,7 @@ main (int argc, char *argv[])
926949            printf ("Could not set executable bit, aborting\n" );
927950            exit (1 );
928951        }
929-          
952+ 
930953        if (bintray_user  !=  NULL ){
931954            if (bintray_repo  !=  NULL ){
932955                char  buf [1024 ];
@@ -935,7 +958,7 @@ main (int argc, char *argv[])
935958                printf ("%s\n" , updateinformation );
936959            }
937960        }
938-          
961+ 
939962        /* If the user has not provided update information but we know this is a Travis CI build, 
940963         * then fill in update information based on TRAVIS_REPO_SLUG */ 
941964        if (guess_update_information ){
@@ -953,7 +976,7 @@ main (int argc, char *argv[])
953976                    if (zsyncmake_path ){
954977                        char  buf [1024 ];
955978                        gchar  * * parts  =  g_strsplit  (travis_repo_slug , "/" , 2 );
956-                         /* https://github.com/AppImage/AppImageSpec/blob/master/draft.md#github-releases   
979+                         /* https://github.com/AppImage/AppImageSpec/blob/master/draft.md#github-releases 
957980                         * gh-releases-zsync|probono|AppImages|latest|Subsurface*-x86_64.AppImage.zsync */ 
958981                        gchar  * channel  =  "continuous" ;
959982                            if (travis_tag  !=  NULL ){
@@ -983,22 +1006,22 @@ main (int argc, char *argv[])
9831006                }
9841007            }
9851008        }
986-          
1009+ 
9871010        /* If updateinformation was provided, then we check and embed it */ 
9881011        if (updateinformation  !=  NULL ){
9891012            if (!g_str_has_prefix (updateinformation ,"zsync|" ))
9901013                if (!g_str_has_prefix (updateinformation ,"bintray-zsync|" ))
9911014                    if (!g_str_has_prefix (updateinformation ,"gh-releases-zsync|" ))
9921015                        if (!g_str_has_prefix (updateinformation ,"pling-v1-zsync|" ))
9931016                            die ("The provided updateinformation is not in a recognized format" );
994-                  
1017+ 
9951018            gchar  * * ui_type  =  g_strsplit_set (updateinformation , "|" , -1 );
996-                          
1019+ 
9971020            if (verbose )
9981021                printf ("updateinformation type: %s\n" , ui_type [0 ]);
9991022            /* TODO: Further checking of the updateinformation */ 
1000-              
1001-            
1023+ 
1024+ 
10021025            unsigned long  ui_offset  =  0 ;
10031026            unsigned long  ui_length  =  0 ;
10041027
0 commit comments