struct taginfo *cgit_parse_tag(struct tag *tag) { void *data; enum object_type type; unsigned long size; const char *p; struct taginfo *ret = NULL; data = read_sha1_file(tag->object.oid.hash, &type, &size); if (!data || type != OBJ_TAG) goto cleanup; ret = xcalloc(1, sizeof(struct taginfo)); for (p = data; !end_of_header(p); p = next_header_line(p)) { if (skip_prefix(p, "tagger ", &p)) { parse_user(p, &ret->tagger, &ret->tagger_email, &ret->tagger_date, &ret->tagger_tz); } } while (p && *p == '\n') p++; if (p && *p) ret->msg = xstrdup(p); cleanup: free(data); return ret; }
int req_auth(int sockfd, struct message_s *msg) { char *payload = payload_malloc(sockfd, msg, true); struct user guest; if (!parse_user(payload, &guest)) return -1; int res = -1; for (int i=0; i < USER_MAX; i++) { if (!user_list[i].id) { /* reach the end */ res = -1; break; } if (strcmp(user_list[i].id, guest.id) == 0 && (strcmp(user_list[i].passwd, guest.passwd) == 0)) { /* match */ printf("%s logged in\n", guest.id); res = 0; break; } } free(payload); write_head(sockfd, TYPE_AUTH_REP, (res == 0 ? 1 : 0), 0); return res; }
int main(int ac, char **argv, char **env) { char *buffer; t_env e; argv++; ac = 0; ft_memset(&e, 0, sizeof(e)); e.env = ft_array_str_cpy(env, e.env); signal(SIGINT, no_quit); while (42) { e.path = get_env(e.env); ft_printf("$> "); get_next_line(0, &buffer); del_tab(buffer); parse_all_cmds(buffer, &e); while (ac < e.nbcmd) { parse_user(e.cmds[ac], &e); (e.nbarg > 0 && is_bull(e.cmd, &e) == 1) ? cmd(&e) : 0; free(e.cmds[ac]); ac++; } ac = 0; } return (0); }
struct passwd * find_user(char *uname, FILE *fp) { char *line; struct passwd *pw; rewind(fp); while (NULL != (line = getAline(fp))) { if (line[0] == '#') continue; pw = parse_user(line); if (pw == (struct passwd *)NULL) continue; if (!strcmp(uname, pw->pw_name)) return pw; } pw = parse_user(NULL); return (struct passwd *)NULL; }
static void rewrite_file(char *path, FILE *fp, struct passwd *newpw) { int fd; char *line; size_t len; FILE *tfp = NULL; char *tempname = NULL; // temporary master.passwd file asprintf(&tempname, "%s.XXXXXX", path); fd = mkstemp(tempname); if (fd == -1) { err(EXIT_FAILURE, "%s", tempname); } tfp = fdopen(fd, "w+"); if (tfp == NULL || fchmod(fd, S_IRUSR | S_IWUSR) != 0) { int save = errno; unlink(tempname); errno = save; err(EXIT_FAILURE, "%s", tempname); } while ((line = fgetln(fp, &len)) != NULL) { struct passwd *pw = parse_user(line, len); // if this is not the entry we're looking for or if parsing // failed (likely a comment) then print the entry as is. if (pw == NULL || strcmp(newpw->pw_name, pw->pw_name) != 0) { fwrite(line, sizeof(char), len, tfp); } else { fprintf(tfp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", newpw->pw_name, newpw->pw_passwd, newpw->pw_uid, newpw->pw_gid, newpw->pw_class, newpw->pw_change, newpw->pw_expire, newpw->pw_gecos, newpw->pw_dir, newpw->pw_shell); } } // Move the temporary file into place. if (fclose(tfp) != 0 || rename(tempname, path) != 0) { int save = errno; unlink(tempname); errno = save; err(EXIT_FAILURE, "%s", tempname); } free(tempname); }
static struct passwd * find_user(FILE *fp, char *uname) { size_t len; char *line; rewind(fp); while ((line = fgetln(fp, &len)) != NULL) { struct passwd *pw = parse_user(line, len); if (pw && strcmp(uname, pw->pw_name) == 0) { return pw; } } return NULL; }
struct taginfo *cgit_parse_tag(struct tag *tag) { void *data; enum object_type type; unsigned long size; const char *p; struct taginfo *ret; data = read_sha1_file(tag->object.sha1, &type, &size); if (!data || type != OBJ_TAG) { free(data); return 0; } ret = xmalloc(sizeof(*ret)); ret->tagger = NULL; ret->tagger_email = NULL; ret->tagger_date = 0; ret->msg = NULL; p = data; while (p && *p) { if (*p == '\n') break; if (starts_with(p, "tagger ")) { p = parse_user(p + 7, &ret->tagger, &ret->tagger_email, &ret->tagger_date); } else { p = strchr(p, '\n'); if (p) p++; } } // skip empty lines between headers and message while (p && *p == '\n') p++; if (p && *p) ret->msg = xstrdup(p); free(data); return ret; }
/* * This routine replaces user/group name with numeric id. */ static char * resolve_ids(char *rule) { id_t id; const char *subject, *textid, *rest; char *resolved; subject = strsep(&rule, ":"); textid = strsep(&rule, ":"); if (textid == NULL) errx(1, "error in rule specification -- no subject"); if (rule != NULL) rest = rule; else rest = ""; if (strcasecmp(subject, "u") == 0) subject = "user"; else if (strcasecmp(subject, "g") == 0) subject = "group"; else if (strcasecmp(subject, "p") == 0) subject = "process"; else if (strcasecmp(subject, "l") == 0 || strcasecmp(subject, "c") == 0 || strcasecmp(subject, "class") == 0) subject = "loginclass"; else if (strcasecmp(subject, "j") == 0) subject = "jail"; if (strcasecmp(subject, "user") == 0 && strlen(textid) > 0) { id = parse_user(textid); asprintf(&resolved, "%s:%d:%s", subject, (int)id, rest); } else if (strcasecmp(subject, "group") == 0 && strlen(textid) > 0) { id = parse_group(textid); asprintf(&resolved, "%s:%d:%s", subject, (int)id, rest); } else asprintf(&resolved, "%s:%s:%s", subject, textid, rest); if (resolved == NULL) err(1, "asprintf"); return (resolved); }
static void process_online_users(int s, void *(f)(char *)) { setutxent(); struct utmpx *uinfo; while ((uinfo = getutxent())) { if (uinfo->ut_type != USER_PROCESS) continue; int uline_len; char *uline = parse_user(uinfo, &uline_len); if (!uline) { // TODO: logging return; } if (s) { flush(s, uline, uline_len); } else { f(uline); } free(uline); } endutxent(); }
static char * humanize_ids(char *rule) { id_t id; struct passwd *pwd; struct group *grp; const char *subject, *textid, *rest; char *humanized; subject = strsep(&rule, ":"); textid = strsep(&rule, ":"); if (textid == NULL) errx(1, "rule passed from the kernel didn't contain subject"); if (rule != NULL) rest = rule; else rest = ""; /* Replace numerical user and group ids with names. */ if (strcasecmp(subject, "user") == 0) { id = parse_user(textid); pwd = getpwuid(id); if (pwd != NULL) textid = pwd->pw_name; } else if (strcasecmp(subject, "group") == 0) { id = parse_group(textid); grp = getgrgid(id); if (grp != NULL) textid = grp->gr_name; } asprintf(&humanized, "%s:%s:%s", subject, textid, rest); if (humanized == NULL) err(1, "asprintf"); return (humanized); }
int get_config(PORANGEFS_OPTIONS options, char *error_msg, unsigned int error_msg_len) { FILE *config_file; char line[256], copy[256], *token, *p, *endptr; int ret = 0, debug_file_flag = FALSE; long mask; config_file = open_config_file(error_msg, error_msg_len); if (config_file == NULL) /* config file is required */ return -1; set_defaults(options); /* parse options from the file */ while (!feof(config_file)) { line[0] = '\0'; fgets(line, 256, config_file); /* remove \n */ if (strlen(line) > 0 && line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; /* check line -- # used for comments */ if (strlen(line) > 0 && line[0] != '#') { /* make a copy */ strncpy(copy, line, 256); /* parse line */ token = strtok(copy, " \t"); if (token == NULL) continue; if (!stricmp(token, "mount")) { /* copy the remaining portion of the line as the mount point */ token = strtok(NULL, " \t"); strncpy(options->mount_point, token, MAX_PATH); } else if (!stricmp(token, "threads")) { token = strtok(NULL, " \t"); options->threads = atoi(token); } else if (!stricmp(token, "user-mode")) { token = strtok(NULL, " \t"); if (token == NULL) { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "user-mode option must be list, certificate, " "or ldap"); ret = -1; goto get_config_exit; } if (!stricmp(token, "list")) { options->user_mode = USER_MODE_LIST; } else if (!stricmp(token, "certificate")) { options->user_mode = USER_MODE_CERT; } else if (!stricmp(token, "ldap")) { options->user_mode = USER_MODE_LDAP; } else { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "user-mode option must be list, certificate, " "or ldap"); ret = -1; goto get_config_exit; } } else if (!stricmp(token, "user")) { if (options->user_mode == USER_MODE_NONE) { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "user option: specify 'user-mode list' above user " "option"); ret = -1; goto get_config_exit; } else if (options->user_mode != USER_MODE_LIST) { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "user option: not legal with current user mode"); ret = -1; goto get_config_exit; } if (parse_user() != 0) { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "user option: parse error"); ret = -1; goto get_config_exit; } } else if (!stricmp(token, "cert-dir-prefix")) { p = line + strlen(token); EAT_WS(p); if (strlen(p) > 0) { strncpy(options->cert_dir_prefix, p, MAX_PATH-2); options->cert_dir_prefix[MAX_PATH-2] = '\0'; if (options->cert_dir_prefix[strlen(options->cert_dir_prefix)-1] != '\\') strcat(options->cert_dir_prefix, "\\"); } else { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "cert-dir-prefix option: parse error"); ret = -1; goto get_config_exit; } } else if (!stricmp(token, "ca-path")) { p = line + strlen(token); EAT_WS(p); if (strlen(p) > 0) { strncpy(options->ca_path, p, MAX_PATH-2); options->ca_path[MAX_PATH-2] = '\0'; } else { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "ca-path option: parse error\n"); ret = -1; goto get_config_exit; } } else if (!stricmp(token, "new-file-perms") || !stricmp(token, "new-dir-perms")) { p = line + strlen(token); EAT_WS(p); /* get mask in octal format */ mask = strtol(p, &endptr, 8); if (!mask || *endptr != '\0') { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "%s option: parse error - value must be " "nonzero octal integer\n", token); ret = -1; goto get_config_exit; } if (!stricmp(token, "new-file-perms")) { options->new_file_perms = (unsigned int) mask; } else { options->new_dir_perms = (unsigned int) mask; } } else if (!stricmp(token, "debug")) { options->debug = TRUE; /* rest of line gives optional debug mask */ p = line + strlen(token); EAT_WS(p); if (strlen(p) > 0) { strncpy(options->debug_mask, p, 256); options->debug_mask[255] = '\0'; } else { /* just debug Windows client */ strcpy(options->debug_mask, "win_client"); } } else if (!stricmp(token, "debug-stderr")) { options->debug_stderr = options->debug = TRUE; } else if (!stricmp(token, "debug-file")) { debug_file_flag = TRUE; /* path to debug file */ p = line + strlen(token); EAT_WS(p); if (strlen(p) > 0) { strncpy(options->debug_file, p, MAX_PATH-2); options->debug_file[MAX_PATH-2] = '\0'; } } else if (!strnicmp(token, "ldap", 4)) { ret = parse_ldap_option(options, line, token, error_msg, error_msg_len); if (ret != 0) goto get_config_exit; } else { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "Unknown option %s", token); ret = -1; goto get_config_exit; } } } if (options->user_mode == USER_MODE_NONE) { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "Must specify user-mode (list, certificate or ldap)"); ret = -1; goto get_config_exit; } if (options->user_mode == USER_MODE_LDAP && (strlen(options->ldap.host) == 0 || strlen(options->ldap.search_root) == 0)) { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "Missing ldap option: ldap-host, or ldap-search-root"); ret = -1; } /* gossip can only print to either a file or stderr */ if (options->debug_stderr && debug_file_flag) { _snprintf(error_msg, error_msg_len, "Configuration file (fatal): " "Cannot specify both debug-stderr and debug-file"); ret = -1; } if (options->user_mode == USER_MODE_LDAP && options->ldap.port == 0) options->ldap.port = options->ldap.secure ? 636 : 389; get_config_exit: close_config_file(config_file); return ret; }
struct commitinfo *cgit_parse_commit(struct commit *commit) { struct commitinfo *ret; const char *p = get_cached_commit_buffer(commit, NULL); const char *t; ret = xmalloc(sizeof(*ret)); ret->commit = commit; ret->author = NULL; ret->author_email = NULL; ret->committer = NULL; ret->committer_email = NULL; ret->subject = NULL; ret->msg = NULL; ret->msg_encoding = NULL; if (p == NULL) return ret; if (!starts_with(p, "tree ")) die("Bad commit: %s", sha1_to_hex(commit->object.sha1)); else p += 46; // "tree " + hex[40] + "\n" while (starts_with(p, "parent ")) p += 48; // "parent " + hex[40] + "\n" if (p && starts_with(p, "author ")) { p = parse_user(p + 7, &ret->author, &ret->author_email, &ret->author_date); } if (p && starts_with(p, "committer ")) { p = parse_user(p + 10, &ret->committer, &ret->committer_email, &ret->committer_date); } if (p && starts_with(p, "encoding ")) { p += 9; t = strchr(p, '\n'); if (t) { ret->msg_encoding = substr(p, t + 1); p = t + 1; } } /* if no special encoding is found, assume UTF-8 */ if (!ret->msg_encoding) ret->msg_encoding = xstrdup("UTF-8"); // skip unknown header fields while (p && *p && (*p != '\n')) { p = strchr(p, '\n'); if (p) p++; } // skip empty lines between headers and message while (p && *p == '\n') p++; if (!p) return ret; t = strchr(p, '\n'); if (t) { ret->subject = substr(p, t); p = t + 1; while (p && *p == '\n') { p = strchr(p, '\n'); if (p) p++; } if (p) ret->msg = xstrdup(p); } else ret->subject = xstrdup(p); reencode(&ret->author, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->author_email, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->committer, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->committer_email, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->subject, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->msg, ret->msg_encoding, PAGE_ENCODING); return ret; }
int parse_status(xmlDocPtr *doc, xmlNode *node, status **stptr){ if(!node || !doc || !stptr) return -1; xmlNode *attr = node->children; status *st = *stptr; while(attr){ // parse status attributes if(!xmlStrcmp(attr->name, (const xmlChar *)"id")){ //status id char *id = xmlNodeListGetString(*doc, attr->xmlChildrenNode, 1); if(id){ // look up status by id /* pthread_mutex_lock(&status_map_mutex); st = g_hash_table_lookup(status_map,id); pthread_mutex_unlock(&status_map_mutex); */ if(!st){ // create new status and insert into the map st = newstatus(); st->id = strdup(id); /* pthread_mutex_lock(&status_map_mutex); g_hash_table_insert(status_map,st->id,st); pthread_mutex_unlock(&status_map_mutex); */ } else break; } else break; } else if(!xmlStrcmp(attr->name, (const xmlChar *)"text")){ //status text char *text = xmlNodeListGetString(*doc, attr->xmlChildrenNode, 1); if(text){ st->wtext = malloc((TWEET_MAX_LEN+1)*sizeof(wchar_t)); memset(st->wtext,'\0',(TWEET_MAX_LEN+1)*sizeof(wchar_t)); st->length = mbstowcs(st->wtext,text,TWEET_MAX_LEN); } } else if(!xmlStrcmp(attr->name, (const xmlChar *)"favorited")){ char *favorited = xmlNodeListGetString(*doc, attr->xmlChildrenNode, 1); if(favorited && strcmp(favorited,"true") == 0) SET_FAVORITED(st->extra_info); } else if(!xmlStrcmp(attr->name, (const xmlChar *)"user")){ //user parse_user(doc,attr,&(st->composer)); } /* else if(!xmlStrcmp(attr->name, (const xmlChar *)"in_reply_to_status_id")){ char *in_reply_to_status_id = xmlNodeListGetString(*doc, attr->xmlChildrenNode, 1); if(in_reply_to_status_id && strlen(in_reply_to_status_id) > 0){ st->in_reply_to_status_id = strdup(in_reply_to_status_id); } } */ else if(!xmlStrcmp(attr->name,(const xmlChar *)"retweeted_status")){ parse_status(doc,attr,&(st->retweeted_status)); /* for(entity *et=st->retweeted_status->entities;et;et=et->next) printf("%ls\n",et->text); */ } else if(!xmlStrcmp(attr->name,(const xmlChar *)"entities")){ parse_entities(doc,attr,st); } attr = attr->next; } split_status_entities(st); *stptr = st; return 0; }
int file_passwd(char *uname, int isroot, const char *old_pw, const char *new_pw) { FILE *fp=NULL; char *fname; struct passwd *pw; struct passwd newpw={0}; struct stat sb; int error_id = 0; char salt[9]; static char nbuf[_PASSWORD_LEN+1]={0}; fname = _PASSWD_FILE; umask((S_IRWXG | S_IRWXO)); if ( lstat(fname, &sb) != 0 ) { return ERR_PASSWD_FILE_NO_EXIST; } fp = fopen(fname, "a+"); if (fp == NULL) { return ERR_PASSWD_FILE_WRITE; } if (fchmod(fileno(fp), (S_IRUSR | S_IWUSR)) != 0) { error_id = ERR_PASSWD_FILE_PERMISSON; goto err; } pw = find_user(uname, fp); if (pw == (struct passwd *)NULL) { error_id = ERR_USER_NO_EXIST; goto err; } if (isroot == 0) { if (strcmp(crypt(old_pw, pw->pw_passwd), pw->pw_passwd)) { error_id = ERR_OLD_PW_WRONG; goto err; } } nbuf[0] = '\0'; snprintf( nbuf, sizeof(nbuf), "%s", new_pw ); /* * Create a random salt */ srandom((int)time((time_t *)NULL)); salt[0] = saltchars[random() % strlen(saltchars)]; salt[1] = saltchars[random() % strlen(saltchars)]; salt[2] = '\0'; new_pw = crypt(nbuf, salt); newpw.pw_name = copyString(pw->pw_name); newpw.pw_passwd = copyString(new_pw); newpw.pw_class = copyString(pw->pw_class); newpw.pw_gecos = copyString(pw->pw_gecos); newpw.pw_dir = copyString(pw->pw_dir); newpw.pw_shell = copyString(pw->pw_shell); newpw.pw_uid = pw->pw_uid; newpw.pw_gid = pw->pw_gid; newpw.pw_change = pw->pw_change; newpw.pw_expire = pw->pw_expire; /* * Re-write the file */ error_id = rewrite_file(fname, fp, &newpw); /* * Clean up memory */ free(newpw.pw_name); free(newpw.pw_passwd); free(newpw.pw_class); free(newpw.pw_gecos); free(newpw.pw_dir); free(newpw.pw_shell); err: pw = parse_user(NULL); fclose(fp); return error_id; }
int rewrite_file(char *pwname, FILE *fp, struct passwd *newpw) { char *line; struct passwd *pw; FILE *tfp, *cfp; int fd; char fname[256]; sprintf(fname, "%s.%.5d", TEMP_FILE_TEMPLATE, getpid()); fd = mkstemps(fname, 6); if (fd == -1) { return ERR_TEMP_CREATE; } if (fchmod(fd, (S_IRUSR | S_IWUSR)) != 0) { close(fd); unlink(fname); return ERR_TEMP_PERMISSON; } tfp = fdopen(fd, "w+"); if (tfp == NULL) { close(fd); unlink(fname); return ERR_TEMP_WRITE; } cfp = NULL; if (!strcmp(pwname, _PASSWD_FILE)) { cfp = fopen(_COMPAT_FILE, "w"); if (cfp == NULL) { return ERR_COMPAT_FILE_WRITE; } } if (cfp != NULL) { fprintf(cfp, "#\n"); fprintf(cfp, "# 4.3BSD-compatable User Database\n"); fprintf(cfp, "#\n"); fprintf(cfp, "# Note that this file is not consulted for login.\n"); fprintf(cfp, "# It only exisits for compatability with 4.3BSD utilities.\n"); fprintf(cfp, "#\n"); fprintf(cfp, "# This file is automatically re-written by various system utilities.\n"); fprintf(cfp, "# Do not edit this file. Changes will be lost.\n"); fprintf(cfp, "#\n"); } rewind(fp); while (NULL != (line = getAline(fp))) { if (line[0] == '#') { fprintf(tfp, "%s", line); continue; } pw = parse_user(line); if (pw == (struct passwd *)NULL) { fprintf(stderr, "warning: bad format for entry: \"%s\"\n", line); fprintf(tfp, "%s\n", line); if (cfp != NULL) fprintf(cfp, "%s\n", line); continue; } if (strcmp(newpw->pw_name, pw->pw_name)) { fprintf(tfp, "%s\n", line); if (cfp != NULL) { fprintf(cfp, "%s:",pw->pw_name); if ((pw->pw_passwd == NULL) || (pw->pw_passwd[0] == '\0')) fprintf(cfp, ":"); else fprintf(cfp, "*:"); fprintf(cfp, "%d:%d:%s:%s:%s\n", pw->pw_uid, pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell); } continue; } fprintf(tfp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n", newpw->pw_name, newpw->pw_passwd, newpw->pw_uid, newpw->pw_gid, newpw->pw_class, newpw->pw_change, newpw->pw_expire, newpw->pw_gecos, newpw->pw_dir, newpw->pw_shell); if (cfp != NULL) { fprintf(cfp, "%s:",newpw->pw_name); if ((newpw->pw_passwd == NULL) || (newpw->pw_passwd[0] == '\0')) fprintf(cfp, ":"); else fprintf(cfp, "*:"); fprintf(cfp, "%d:%d:%s:%s:%s\n", newpw->pw_uid, newpw->pw_gid, newpw->pw_gecos, newpw->pw_dir, newpw->pw_shell); } } if (cfp != NULL) fclose(cfp); fclose(fp); rewind(tfp); fp = fopen(pwname, "w"); if (fp == NULL) { fprintf(stderr, "ERROR: can't update \"%s\"\n", pwname); fprintf(stderr, "new passwd file is \"%s\"\n", fname); return ERR_PASSWD_FILE_WRITE; } while (NULL != (line = getAline(tfp))) { fprintf(fp, "%s", line); if (line[0] != '#') fprintf(fp, "\n"); } fclose(fp); fclose(tfp); unlink(fname); return 0; }
struct commitinfo *cgit_parse_commit(struct commit *commit) { struct commitinfo *ret; char *p = commit->buffer, *t = commit->buffer; ret = xmalloc(sizeof(*ret)); ret->commit = commit; ret->author = NULL; ret->author_email = NULL; ret->committer = NULL; ret->committer_email = NULL; ret->subject = NULL; ret->msg = NULL; ret->msg_encoding = NULL; if (p == NULL) return ret; if (strncmp(p, "tree ", 5)) die("Bad commit: %s", sha1_to_hex(commit->object.sha1)); else p += 46; // "tree " + hex[40] + "\n" while (!strncmp(p, "parent ", 7)) p += 48; // "parent " + hex[40] + "\n" if (p && !strncmp(p, "author ", 7)) { p = parse_user(p + 7, &ret->author, &ret->author_email, &ret->author_date); } if (p && !strncmp(p, "committer ", 9)) { p = parse_user(p + 9, &ret->committer, &ret->committer_email, &ret->committer_date); } if (p && !strncmp(p, "encoding ", 9)) { p += 9; t = strchr(p, '\n'); if (t) { ret->msg_encoding = substr(p, t + 1); p = t + 1; } } // skip unknown header fields while (p && *p && (*p != '\n')) { p = strchr(p, '\n'); if (p) p++; } // skip empty lines between headers and message while (p && *p == '\n') p++; if (!p) return ret; t = strchr(p, '\n'); if (t) { ret->subject = substr(p, t); p = t + 1; while (p && *p == '\n') { p = strchr(p, '\n'); if (p) p++; } if (p) ret->msg = xstrdup(p); } else ret->subject = xstrdup(p); if (ret->msg_encoding) { reencode(&ret->subject, PAGE_ENCODING, ret->msg_encoding); reencode(&ret->msg, PAGE_ENCODING, ret->msg_encoding); } return ret; }
struct commitinfo *cgit_parse_commit(struct commit *commit) { const int sha1hex_len = 40; struct commitinfo *ret; const char *p = get_cached_commit_buffer(commit, NULL); const char *t; ret = xcalloc(1, sizeof(struct commitinfo)); ret->commit = commit; if (!p) return ret; if (!skip_prefix(p, "tree ", &p)) die("Bad commit: %s", oid_to_hex(&commit->object.oid)); p += sha1hex_len + 1; while (skip_prefix(p, "parent ", &p)) p += sha1hex_len + 1; if (p && skip_prefix(p, "author ", &p)) { parse_user(p, &ret->author, &ret->author_email, &ret->author_date, &ret->author_tz); p = next_header_line(p); } if (p && skip_prefix(p, "committer ", &p)) { parse_user(p, &ret->committer, &ret->committer_email, &ret->committer_date, &ret->committer_tz); p = next_header_line(p); } if (p && skip_prefix(p, "encoding ", &p)) { t = strchr(p, '\n'); if (t) { ret->msg_encoding = substr(p, t + 1); p = t + 1; } } if (!ret->msg_encoding) ret->msg_encoding = xstrdup("UTF-8"); while (!end_of_header(p)) p = next_header_line(p); while (p && *p == '\n') p++; if (!p) return ret; t = strchrnul(p, '\n'); ret->subject = substr(p, t); while (*t == '\n') t++; ret->msg = xstrdup(t); reencode(&ret->author, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->author_email, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->committer, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->committer_email, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->subject, ret->msg_encoding, PAGE_ENCODING); reencode(&ret->msg, ret->msg_encoding, PAGE_ENCODING); return ret; }