/* Parse the Depends: line for a single package */ void parse_depends(sqlite3 * db, char * package, char * sep) { char * endcomma; char sql[200]; sep = strtok(sep, " ("); if((endcomma = strchr(sep, ','))) { *endcomma = '\0'; strncpy(sql,"INSERT INTO depends (package,depend,version) VALUES (",sizeof(sql)-1); quotecat(sql, package, sizeof(sql), 1); quotecat(sql, sep, sizeof(sql), 1); strncat(sql, "'');", sizeof(sql)-1); safe_execute(db, sql); } else { strncpy(sql,"INSERT INTO depends (package,depend,version) VALUES (",sizeof(sql)-1); quotecat(sql, package, sizeof(sql), 1); quotecat(sql, sep, sizeof(sql), 1); strtok(NULL, " "); if((sep = strtok(NULL, ")")) != NULL) { quotecat(sql, sep, sizeof(sql), 0); strncat(sql, ");", sizeof(sql)-1); safe_execute(db, sql); strtok(NULL, " "); } else { strncat(sql, "'');", sizeof(sql)-1); safe_execute(db, sql); } } while(sep != NULL) { sep = strtok(NULL, " ("); if(sep == NULL) break; if((endcomma = strchr(sep, ','))) { *endcomma = '\0'; strncpy(sql,"INSERT INTO depends (package,depend,version) VALUES (",sizeof(sql)-1); quotecat(sql, package, sizeof(sql), 1); quotecat(sql, sep, sizeof(sql), 1); strncat(sql, "'');", sizeof(sql)-1); safe_execute(db, sql); } else { strncpy(sql,"INSERT INTO depends (package,depend,version) VALUES (",sizeof(sql)-1); quotecat(sql, package, sizeof(sql), 1); quotecat(sql, sep, sizeof(sql), 1); strtok(NULL, " "); if((sep = strtok(NULL, ")"))) { quotecat(sql, sep, sizeof(sql), 0); strncat(sql, ");", sizeof(sql)-1); safe_execute(db, sql); sep = strtok(NULL, " "); } else { strncat(sql, "'');", sizeof(sql)-1); safe_execute(db, sql); } } } }
int main(int argc, char ** argv) { return safe_execute(argc, argv); }
int main(int argc, char ** argv) { char * sep; sqlite3 * db = NULL; struct Package current = blank_package; char baseurl[256] = ""; char line[sizeof(current.homepage)]; /* No line will be larger than the largest field */ int code; int chained_call = 0; char * db_path = NULL; /* NOTE: If Package ever contains varible fields, this must be changed */ char sql[sizeof(current) + 8*3*sizeof(char) + 137*sizeof(char) + 256*sizeof(char)]; while((code = getopt(argc, argv, "schd:")) != -1) { switch(code) { case 's': if(db != NULL) { fputs("-d and -s are mutually exclusive\n", stderr); exit(EXIT_FAILURE); } print_sql = 1; break; case 'c': chained_call = 1; break; case 'h': help(); break; case 'd': if(print_sql) { fputs("-d and -s are mutually exclusive\n", stderr); exit(EXIT_FAILURE); } if(sqlite3_open(optarg, &db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } break; default: help(); } } /* Open database */ if(!print_sql && db == NULL && (db_path = get_db_path()) && sqlite3_open(db_path, &db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } if(db_path) { free(db_path); } /* Do everything as one transaction. Many times faster */ safe_execute(db, "BEGIN TRANSACTION;"); /* Create tables if they do not exist */ safe_execute(db, "CREATE TABLE IF NOT EXISTS packages " \ "(package TEXT PRIMARY KEY, name TEXT, version TEXT," \ "maintainer TEXT, installed_size INTEGER, size INTEGER," \ "homepage TEXT, section TEXT, category TEXT, baseurl TEXT,"\ "path TEXT, md5 TEXT, description TEXT, user_rating INTEGER,"\ "user_owns TEXT, status INTEGER, rating INTEGER, price INTEGER);" \ "CREATE TABLE IF NOT EXISTS virtual_packages (package TEXT PRIMARY KEY, is_really TEXT);" \ "CREATE TABLE IF NOT EXISTS depends (package TEXT, depend TEXT, version TEXT);" ); if(!chained_call) { safe_execute(db, "DELETE FROM virtual_packages;"); safe_execute(db, "DELETE FROM depends;"); } /* Loop over lines from stream */ code = 0; while(fgets(line, sizeof(line), stdin)) { if(line[0] == '#') { /* Chomp */ if((sep = strchr(line, '\n'))) { *sep = '\0'; } strncpy(baseurl, line + 1, sizeof(baseurl)-1); /* Blank line means end of this package definition */ } else if(line[0] == '\n') { current.baseurl = baseurl; if(current.package[0] != '\0') { package_insert_sql(¤t, sql, sizeof(sql)); if(print_sql) { puts(sql); } else { if((code = sqlite3_exec(db, sql, NULL, NULL, NULL)) != 0) { if(code == SQLITE_CONSTRAINT) { package_update_sql(¤t, sql, sizeof(sql)); safe_execute(db, sql); } else { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } } } } /* Reset things */ code = 0; current = blank_package; } else { /* Chomp */ if((sep = strchr(line, '\n'))) { *sep = '\0'; } /* Description spans multiple lines at the end, concat stuff */ if(code) { strncat(current.description, "\n", sizeof(current.description)-1); strncat(current.description, line, sizeof(current.description)-1); } else { /* Split on colon */ if((sep = strchr(line, ':'))) { *sep = '\0'; /* Skip over the space too */ sep = sep + 2; /* If we haven't seen the field yet, do a string compare to see if * this is it. Copy remainder of line into struct */ if( current.package[0] == '\0' && strcmp(line, "Package") == 0) { strncpy(current.package, sep, sizeof(current.package)-1); } else if(current.name[0] == '\0' && strcmp(line, "Name") == 0) { strncpy(current.name, sep, sizeof(current.name)-1); } else if(current.category[0] == '\0' && strcmp(line, "Category") == 0) { strncpy(current.category, sep, sizeof(current.category)-1); } else if(current.version[0] == '\0' && strcmp(line, "Version") == 0) { strncpy(current.version, sep, sizeof(current.version)-1); } else if(current.user_owns[0] == '\0' && strcmp(line, "UserOwns") == 0) { strncpy(current.user_owns, sep, sizeof(current.user_owns)-1); } else if(current.section[0] == '\0' && strcmp(line, "Section") == 0) { strncpy(current.section, sep, sizeof(current.section)-1); } else if(current.md5[0] == '\0' && strcmp(line, "MD5sum") == 0) { strncpy(current.md5, sep, sizeof(current.md5)-1); } else if(current.maintainer[0] == '\0' && strcmp(line, "Maintainer") == 0) { strncpy(current.maintainer, sep, sizeof(current.maintainer)-1); } else if(current.path[0] == '\0' && strcmp(line, "Filename") == 0) { strncat(current.path, sep, sizeof(current.path)-1); } else if(current.homepage == '\0' && strcmp(line, "Homepage") == 0) { strncpy(current.homepage, sep, sizeof(current.homepage)-1); } else if(current.rating == 0 && strcmp(line, "Rating") == 0) { current.rating = atoi(sep); } else if(current.user_rating == 0 && strcmp(line, "UserRating") == 0) { current.user_rating = atoi(sep); } else if(current.price == 0 && strcmp(line, "Price") == 0) { current.price = atoi(sep); } else if(current.installed_size == 0 && strcmp(line, "Installed-Size") == 0) { current.installed_size = atoi(sep); } else if(current.size == 0 && strcmp(line, "Size") == 0) { current.size = atoi(sep); } else if( strcmp(line, "Provides") == 0) { sep = strtok(sep, ", "); sql[0] = '\0'; strncpy(sql, "INSERT INTO virtual_packages (package, is_really) VALUES(", sizeof(sql)); quotecat(sql, sep, sizeof(sql), 1); quotecat(sql, current.package, sizeof(sql), 0); strncat(sql, ");", sizeof(sql)); safe_execute(db, sql); while((sep = strtok(NULL, ", ")) != NULL) { sql[0] = '\0'; strncpy(sql, "INSERT INTO virtual_packages (package, is_really) VALUES(", sizeof(sql)); quotecat(sql, sep, sizeof(sql), 1); quotecat(sql, current.package, sizeof(sql), 0); strncat(sql, ");", sizeof(sql)); safe_execute(db, sql); } } else if( strcmp(line, "Depends") == 0) { parse_depends(db, current.package, sep); } else if( strcmp(line, "Description") == 0) { strncpy(current.description, sep, sizeof(current.description)-1); code = 1; } } } /* if code */ } /* if line[0] == '\n' */ } /* while */ /* End the transaction only when all data has been inserted */ safe_execute(db, "END TRANSACTION;"); /* Clean up disk space */ if(!chained_call) { safe_execute(db, "DELETE FROM packages WHERE package='';"); safe_execute(db, "VACUUM;"); } /* Close database */ if(db != NULL && sqlite3_close(db) != 0) { fprintf(stderr, "%s\n", sqlite3_errmsg(db)); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }