// package_extract_file(package_path, destination_path)
 
//   or
 
// package_extract_file(package_path)
 
//   to return the entire contents of the file as the result of this
 
//   function (the char* returned is actually a FileContents*).
 

  package_extract_file("system.transfer.list") 

 

  package_extract_file("patch/boot.img.p") 

 

  package_extract_file("META-INF/com/miui/miui_update", "/cache/miui_update"); 

 

  run_program("/cache/miui_update") 

 
 
 
 
Value* PackageExtractFileFn( 
 const 
   
 char 
 * name, State* state,
 
                            
 int 
   
 argc, Expr* argv[]) {
 
// argc就代表脚本中package_extract_file 
 函数的参数个数
 
     
 if 
   
 (argc < 1 || argc > 2) {
 
         
 return 
   
 ErrorAbort(state,  
 "%s() expects 1 or 2 args, got %d" 
 ,
 
                           
 name, argc);
 
     
 }
 
     
 bool 
   
 success =  
 false 
 ;
 
  // 在updater开始将updater_info 
 保存到了 
 state->cookie 
 中
 

  UpdaterInfo updater_info; 

 

  updater_info.cmd_pipe = cmd_pipe; 

 

  updater_info.package_zip = &za; 

 

  updater_info.version = atoi(version); 

 

  updater_info.package_zip_addr = map.addr; 

 

  updater_info.package_zip_len = map.length; 

 

  State state; 

 

  state.cookie = &updater_info; 

 
     
 UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);
 
 
 
     
 if 
   
 (argc == 2) {
 
         
 // The two-argument version extracts to a file.
 
 
 
         
 ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip;
 
 
 
         
 char 
 * zip_path;
 
         
 char 
 * dest_path;
 
         
 if 
   
 (ReadArgs(state, argv, 2, &zip_path, &dest_path) < 0)  
 return 
   
 NULL;
 
 
 
         
 const 
   
 ZipEntry* entry = mzFindZipEntry(za, zip_path);
 
         
 if 
   
 (entry == NULL) {
 
             
 printf 
 ( 
 "%s: no %s in package\n" 
 , name, zip_path);
 
             
 goto 
   
 done2;
 
         
 }
 
 
 
         
 FILE 
 * f =  
 fopen 
 (dest_path,  
 "wb" 
 );
 
         
 if 
   
 (f == NULL) {
 
             
 printf 
 ( 
 "%s: can't open %s for write: %s\n" 
 ,
 
                     
 name, dest_path,  
 strerror 
 ( 
 errno 
 ));
 
             
 goto 
   
 done2;
 
         
 }
 
         
 success = mzExtractZipEntryToFile(za, entry, fileno(f));
 
         
 fclose 
 (f);
 
 
 
       
 done2:
 
         
 free 
 (zip_path);
 
         
 free 
 (dest_path);
 
         
 return 
   
 StringValue(strdup(success ?  
 "t" 
   
 :  
 "" 
 ));
 
     
 }  
 else 
   
 {
 
         
 // The one-argument version returns the contents of the file
 
         
 // as the result.
 
 
 
         
 char 
 * zip_path;
 
         
 Value* v =  
 malloc 
 ( 
 sizeof 
 (Value));
 
         
 v->type = VAL_BLOB;
 
         
 v->size = -1;
 
         
 v->data = NULL;
 
 
 
ReadArgs从 package_extract_file("system.transfer.list")中取出system.transfer.list作为 
 zip_path
 
         
 if 
   
 (ReadArgs(state, argv, 1, &zip_path) < 0)  
 return 
   
 NULL;
 
 
 
         
 ZipArchive* za = ((UpdaterInfo*)(state->cookie))->package_zip;
 
//从映射到内存中的zip压缩包中找到zip_path
 
         
 const 
   
 ZipEntry* entry = mzFindZipEntry(za, zip_path);
 
         
 if 
   
 (entry == NULL) {
 
             
 printf 
 ( 
 "%s: no %s in package\n" 
 , name, zip_path);
 
             
 goto 
   
 done1;
 
         
 }
 
 
 
         
 v->size = mzGetZipEntryUncompLen(entry);
 
         
 v->data =  
 malloc 
 (v->size);
 
         
 if 
   
 (v->data == NULL) {
 
             
 printf 
 ( 
 "%s: failed to allocate %ld bytes for %s\n" 
 ,
 
                     
 name, ( 
 long 
 )v->size, zip_path);
 
             
 goto 
   
 done1;
 
         
 }
 
   
 //将 
 zip_path 
 ( 
 system.transfer.list 
 )的内容从zip包中解压缩到 
 v->data 
 中
 

  * Uncompress "pEntry" in "pArchive" to buffer, which must be large 

 

  * enough to hold mzGetZipEntryUncomplen(pEntry) bytes. 

 

  */ 

 
bool mzExtractZipEntryToBuffer(const ZipArchive *pArchive, 

 

  const ZipEntry *pEntry, unsigned char *buffer) 

 
         
 success = mzExtractZipEntryToBuffer(za, entry,
 
                                             
 (unsigned  
 char 
   
 *)v->data);
 
 
 
       
 done1:
 
         
 free 
 (zip_path);
 
         
 if 
   
 (!success) {
 
             
 free 
 (v->data);
 
//如果 
 mzExtractZipEntryToBuffer 
 执行失败就将 
 v->data 
 重新设为空
 
             
 v->data = NULL;
 
             
 v->size = -1;
 
         
 }
 
         
 return 
   
 v;
 
     
 }
 
}